【问题标题】:Erased components in Delphi programDelphi程序中的擦除组件
【发布时间】:2016-05-11 04:21:56
【问题描述】:

更新

2016-02-18:添加流程信息


我有一个使用 XE4 编译的 Delphi 程序。数百名客户正在使用它。几周前,其中一位客户报告说,可执行文件的某些区域在白天被随机擦除(如下图)。此客户端有 35 个站点使用此 exe,并且出现问题的站点不超过 10 个。

调查

1 - 我的第一个怀疑是无限循环。该 exe 在组件被擦除时一直响应,从没有发生此问题并且日志没有显示任何循环(此 exe 到处都有日志)时,代码上没有发生如此根本的变化。

2 - 行为不端的线程。我有一个单独的线程来同步这个 exe 和我们在云中的服务器之间的数据。同样,当问题发生时,日志不会显示线程正在运行,而且这里没有任何更改。

3 - 其他一些程序(防病毒软件?)正在影响我的 exe。还无法正确调查这种髋关节疼痛,但到目前为止找不到任何引起我注意的已安装程序。

我的问题是:什么可能导致这个问题?我该如何进一步调查?我知道这可能是一个广泛的问题,但这是我能收集到的所有信息,我无法想象还有更多的地方可以看。

图片

1 - 在下图中,红色描边区域应该是一个 TToolBar

2 - 在第二张图片中有三个区域,从上到下第一个应该是 TToolBar,第二个应该是子窗体的标题,第三个应该是 TwwDBGrid

3 - 第三个示例在顶部显示了应该是 TEdit 的已擦除区域,在它下面应该是 TwwDBGrid 上的一条线,在侧面我们可以看到 TwwDBGrid 的已擦除滚动条

4 - 最后一个示例显示了 5 个已擦除区域:应用程序的标题、主 TToolBar、窗体的标题、一个 TButton 和两个 TwwDBGrid

5 - 这是一个有趣的例子,因为除了被擦除的组件之外,还有 4 个 TSpeedButtons 没有被擦除,但它们没有原来的图像(第一个红色描边区域)。其他 3 个红色描边区域依次是 2 个 TEdit、一个 TwwDBGrd 和一个 TButton

流程信息

我在问题发生的那一刻得到了一个屏幕截图。 scgolr 是我的软件。

【问题讨论】:

  • 我猜是显卡和驱动程序的问题。众所周知,工具栏对这些东西很敏感。
  • 表单显示时缺少组件?程序是否运行良好,直到突然所有新表单都开始失败?也许您有一些内存或资源泄漏,并且正在耗尽一些 Windows/GDI 资源。验证您是否在关闭时正确释放表单。
  • 您已经在任务管理器中打开了进程选项卡。请使用View (Exibir) -> Select Columns 选择列GDI ObjectsUser Objects。按这些列排序,看看是否有过度使用这些对象。
  • 您的程序被 几百 个客户使用。 一个客户在不到三分之一的网站上发现了这个问题。由于问题非常明显并且工作流程中断,我相信如果这是一个普遍问题,其他客户会与您联系。因此,原因的关键是在那些已经看到它的地方找到。此外,该问题发生在今年年初的一个相当具体的时间范围内(几周前)。 IMO 的第一步是澄清当时发生了什么变化? ....
  • (继续)硬件、网络、服务器、操作系统、其他软件。不要忘记,您的软件是如何使用的。真的在那个时候改变了什么。要检查的列表很长,目的是为那些发现问题的少数站点找到共同的变化?更改本身可能是实际原因(例如不兼容的硬件),或者它可能只是触发了您的软件的弱点。一旦你知道是什么让问题浮出水面,它就会大大减少搜索量。

标签: delphi


【解决方案1】:

确实没有足够详细的信息给你一个明确的答案。但是,我可以就您的问题给出一些指导:

我该如何进一步调查?

因为你所说的:

  • 数百名客户正在使用该程序
  • 一个(只有一个)客户遇到问题
  • 第一次出现问题是在几周前

首先要做的是与客户取得联系,并获得您所说的您要求但未获得的信息。需要回答的问题是:

  • 问题发生时客户环境发生了什么变化 从硬件、网络、服务器、操作系统、其他软件开始 在 PC 上运行?
  • 您的客户使用您的软件的方式有什么变化吗?
  • 一旦问题发生,客户必须做些什么来解决问题?关闭程序?重启电脑?或者只是最小化 - 恢复错误的窗口?

以上所述,我不认为该客户及其设备或他们使用软件的方式有问题。可能只是站点上与所有其他客户不同的组合导致问题出现。

当问题发生时,在您的软件和现场检查一些具体的事情,如果问题随着最小化 - 应用程序的恢复而消失(这表明绘画中断问题:

  • 您是否随时致电Application.ProcessMessages
  • 后台线程是否访问与 GUI 相同的数据?如果是,数据保护是否到位(锁定、同步)。
  • 后台线程是否可以访问任何没有Synchronize 的GUI 组件?

最后我建议你去现场拜访客户。在直接讨论中,您会得到更好更快的答案。


收到进程信息后进行编辑。

关于 GDI 或用户对象没有什么令人担忧的。但是令人震惊,当您在 cmets 中说您在许多地方调用 Application.ProcessMessages 时,显然是为了“修复”无响应的 UI。例如,如果用户双击一个按钮会发生什么情况,但它是否足够慢以至于 Windows 检测到它以单独单击?第一次单击可能会启动您调用A.P. 的长期程序。第二次单击是从启动相同程序的消息队列中读取的。现在对过程的第二次调用运行(与它自己对A.P. 的调用)并最终结束并且执行返回到第一次调用。根据您在此过程中执行的操作,您很可能会弄乱句柄和设备上下文等。强烈建议出于友好的意图说:摆脱那些对A.P.的调用

【讨论】:

  • 我终于可以访问带有 GDI 信息的进程信息...添加到问题中。
  • 我在很多地方都调用了 Application.ProcessMessages 我有长时间运行的代码。
  • @Ricardo 这不好!您需要删除那些 A.P. 调用。
  • @Ricardo 这是a link 值得一读,here 是另一个。
  • 谢谢汤姆·布伦伯格!我看得更深入,实际上我在软件中不到 10 个地方使用了 ProcessMessages。但我真的不知道这个问题,现在它很有意义。 @Passella 的回答解决了这个问题,但是根据您的 cmets,我已经在这里开始重构以更改我使用 ProcessMessages by Threads 的位置。
【解决方案2】:

问题出在您的客户正在访问的安全插件 (Warsaw - Gas Tecnologia) 银行网站上,更新它就会得到解决,问题发生在巴西

【讨论】:

【解决方案3】:

正如@SebastianZ 和@AlekseyK 指出的那样,您可以尝试exaustin 一些GDI 资源(句柄?)。 如果系统可以访问一些工具,如 Process explerer 或 process hacker 可以给你一些提示。这个实用程序也可能有帮助GDIView

我不知道这是否适用于您的情况,但有时数据库数据损坏会导致程序运行时出现奇怪的效果(我记得“数据炸弹”导致内存不足异常......

因此,如果某些原因导致 GDI 分配循环,您的应用程序的图形可能会以“奇怪”的方式受到影响

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 2011-06-28
    相关资源
    最近更新 更多