16

OutputDebugString(PAnsiChar(''));

线程安全吗?

我/我们一直在线程中使用它进行调试,我从来没有想过我应该以不同的方式来做。

(德尔福 7)

4

3 回答 3

26

好吧,并不是说它不是真的,它是,但只是为了让你不必只接受 Lieven 的话:

应用程序和调试器之间的数据传递是通过一个 4kbyte 的共享内存块完成的,其中一个 Mutex 和两个 Event 对象保护对它的访问。这些是涉及的四个内核对象。

了解 Win32 OutputDebugString是一篇关于此事的优秀文章。

于 2009-02-03T23:55:23.647 回答
18

别担心,它是。

当应用程序调用 OutputDebugString() 时,它会执行以下步骤。请注意,任何时候的失败都会放弃整个事情并将调试请求视为无操作(字符串不会发送到任何地方)。

  1. 打开 DBWinMutex 并等到我们拥有对它的独占访问权限。
  2. 将 DBWIN_BUFFER 段映射到内存中:如果找不到,则说明没有调试器在运行,因此忽略整个请求。
  3. 打开 DBWIN_BUFFER_READY 和 DBWIN_DATA_READY 事件。与共享内存段一样,缺少对象意味着没有可用的调试器。
  4. 等待 DBWIN_BUFFER_READY 事件发出信号:这表示内存缓冲区不再使用。大多数情况下,这个事件会在被检查时立即发出信号,但等待缓冲区不会超过 10 秒(超时放弃请求)。
  5. 将最多约 4kbytes 的数据复制到内存缓冲区,并将当前进程 ID 也存储在那里。始终在字符串末尾放置一个 NUL 字节。
  6. 通过设置 DBWIN_DATA_READY 事件告诉调试器缓冲区已准备好。调试器从那里获取它。
  7. 释放互斥锁
  8. 关闭 Event 和 Section 对象,尽管我们保留互斥体的句柄以备后用。
于 2009-02-03T23:43:11.610 回答
3

不过,我曾经遇到过 ISAPI DLL 中的字符串问题。由于某些奇怪的原因,未设置 System.pas 中定义的 IsMultiThread 布尔值!

一旦线程运行多个线程,就会导致奇怪的 AccessViolations ... 一个简单的“IsMultiThread:=true;” 在一个单元初始化中修复了它。

于 2009-04-07T06:43:54.657 回答