【问题标题】:How can I keep a large amount of OutputDebugString() calls from degrading my application in the Delphi 6 IDE?在 Delphi 6 IDE 中,如何防止大量的 OutputDebugString() 调用降低我的应用程序的性能?
【发布时间】:2012-01-12 06:45:55
【问题描述】:

这种情况不止一次发生在我身上,导致我在追逐鬼魂时浪费了很多时间。通常,当我调试一些非常困难的与时序相关的代码时,我开始添加大量的 OutputDebugString() 调用,这样我就可以很好地了解相关操作的顺序。问题是,Delphi 6 IDE 似乎只能长时间处理这种情况。我将使用一个我刚刚经历过的具体示例来避免笼统(尽可能)。

我花了几天时间调试我的线程间信号量锁定代码以及我的 DirectShow 时间戳计算代码,这导致了一些令人非常沮丧的问题。在消除了我能想到的所有错误之后,我的应用程序向其发送音频的Skype 仍然存在问题。

大约 10 秒后,我在用于测试的第二台 PC(通话的远端)上从 Skype 发出说话和听到声音之间的延迟开始增加。在大约 20 到 30 秒时,延迟开始呈指数级增长,此时触发代码,我可以检查关键部分是否被持有太久。

幸运的是,当时还不算太晚,而且之前经历过这种情况,我决定停止无情地跟踪并关闭大部分 OutputDebugString()。值得庆幸的是,我将它们中的大多数包裹在条件编译器定义中,因此很容易做到。我这样做的那一刻,问题就消失了,结果证明我的代码运行良好。

因此,当 OutputDebugstring() 流量超过某个阈值时,Delphi 6 IDE 似乎开始真正陷入困境。也许这只是将字符串添加到包含所有 OutputDebugString() 报告的 Event Log 调试器窗格的任务。我不知道,但是当 TMemo 或类似控件开始包含太多字符串时,我在我的应用程序中看到了类似的问题。

你们这些人做了什么来防止这种情况发生?有没有办法通过某种方法调用或至少限制其大小来清除事件日志?另外,您通过条件定义、IDE 插件或其他方式使用了哪些技术来应对这种情况?

【问题讨论】:

标签: delphi debugging logging outputdebugstring


【解决方案1】:

我之前在使用 Delphi 2007 时也遇到过类似的问题。在 IDE 中禁用事件查看,而是使用 Sysinternals 中的 DebugView

【讨论】:

  • 我有 DebugView 但我不知道你可以禁用事件查看。我看看Delphi6有没有这个选项,谢谢。
  • ... 我被告知缓慢的原因是由于事件日志使用了 StringGrid(现在它是 VirtualStringTree)。 Here 是我具体问题的线程缓存,当时在 Emb.. 论坛上。
【解决方案2】:

我几乎从不使用 OutputDebugString。我发现很难在 IDE 中分析输出,并且需要额外的努力来保持多组多次运行。

我真的更喜欢一个好的日志组件套件(CodeSite、SmartInspect),并且通常会记录到各种文件。例如,标准文件是“General”、“Debug”(我也想从客户端安装中收集的标准调试信息)、“Configuration”、“Services”、“Clients”。这些都设置为“溢出”到一组编号文件,这允许您通过简单地允许更多编号文件来保留多次运行的日志。这样一来,比较不同运行的日志信息就变得容易多了。

在您描述的情况下,我将添加调试语句,将日志记录到单独的日志文件中。例如“跟踪”。使“跟踪”可用的代码位于条件定义之间。这使得打开它非常简单。

为了避免留下这些额外的调试语句,我倾向于进行更改以打开“跟踪”日志而不从源代码管理中检查它。这样,构建服务器的编译器将在无意中留下的任何语句上抛出“未定义标识符”错误。如果我想保留这些额外的语句,我要么将它们更改为转到“调试”日志,要么将它们放在条件定义。

【讨论】:

  • 感谢有关日志记录组件的提示。我会看看那些。然而,我发现对于一些高速实时关键调试案例,写入日志文件会过多地破坏时序,甚至无法实现。但除了那一小部分用例之外,它们肯定有很大帮助。
  • @RobertOschler:我没有做过任何实时工作,但是在高性能的多线程服务器软件中(在我的雇主那里),我们通常可以摆脱一些在时间变化足以改变行为并使错误消失之前记录。当然,您确实希望保持日志消息简短,并尽可能避免字符串连接(使用格式)、内存重新分配、函数调用或属性获取器进行日志记录。
【解决方案3】:

我要做的第一件事是确定问题是您认为的问题。自从我使用 Delphi 以来已经有很长时间了,所以我不确定 IDE 的限制,但我有点怀疑事件日志会随着时间的推移而开始以指数方式陷入困境,而调试字符串的数量相同写在 20-30 秒的时间里。由于某种原因,编写的调试字符串的数量似乎更有可能随着时间的推移而增加,这可能表明您的应用程序控制流中存在一个错误,该错误在禁用日志记录时并不那么明显。

为了确保我会尝试编写一个简单的应用程序,它只是在一个循环中运行,以 100 个左右的块写出调试字符串,并开始记录每个块花费的时间,看看时间是否开始增加显着超过 20-30 秒的时间跨度。

如果您确实确认这是问题所在——或者即使不是——那么我建议您改用某种类型的日志库。当您将 OutputDebugString 用于这样的大量日志转储时,它真的失去了它的有效性。即使您确实找到了重置或限制输出窗口的方法,您也会丢失所有的日志记录数据。

【讨论】:

  • 谢谢。请参阅下面关于日志记录的我对 Marjan 的评论。
  • 一个好的日志库将允许您配置缓冲,这样您就不会为每个日志条目写入文件,因此它不会比 OutputDebugString 更具破坏性。他们中的许多人还可以使用外部进程来处理日志条目并通过共享内存传递日志条目,这与 OutputDebugString 所做的基本相同。
【解决方案4】:

IDE Fix Pack 进行了优化以提高 OutputDebugString 的性能

IDE 的调试日志视图也得到了优化。现在的调试器 仅在 IDE 空闲时更新日志视图。这允许 IDE 在数百条 OutputDebugString 消息或其他消息时保持响应 调试消息被写入调试日志视图。

请注意,这只在 Delphi 2007 及更高版本上运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 2023-04-05
    相关资源
    最近更新 更多