В Delphi поток OutputDebugString безопасен?

Является

OutputDebugString(PAnsiChar(''));

поток безопасно?

Я / мы использовали его в потоках для отладки, и мне никогда не приходило в голову, что я должен делать это по-другому.

(Delphi 7)

3 ответа

Решение

Не волнуйся, это так.

Когда OutputDebugString() вызывается приложением, оно предпринимает следующие шаги. Обратите внимание, что ошибка в любой момент оставляет все это и обрабатывает запрос на отладку как запрет (строка никуда не отправляется).

  1. Откройте DBWinMutex и дождитесь эксклюзивного доступа к нему.
  2. Сопоставьте сегмент DBWIN_BUFFER с памятью: если он не найден, отладчик не работает, поэтому весь запрос игнорируется.
  3. Откройте события DBWIN_BUFFER_READY и DBWIN_DATA_READY. Как и в случае сегмента общей памяти, отсутствующие объекты означают, что отладчик недоступен.
  4. Подождите, пока событие DBWIN_BUFFER_READY будет сигнализировано: это говорит о том, что буфер памяти больше не используется. В большинстве случаев об этом событии будет сигнализироваться сразу же после его проверки, но он не будет ждать дольше 10 секунд, пока буфер не станет готовым (тайм-аут отменяет запрос).
  5. Скопируйте до 4 Кбайт данных в буфер памяти и сохраните там также текущий идентификатор процесса. Всегда ставьте байт NUL в конце строки.
  6. Сообщите отладчику, что буфер готов, установив событие DBWIN_DATA_READY. Отладчик берет это оттуда.
  7. Отпустите мьютекс
  8. Закройте объекты Event и Section, хотя мы оставим дескриптор мьютекса на потом.

Ну, не то, чтобы это не было правдой, это так, но просто для того, чтобы вам не пришлось просто поверить на слово Ливен:

Передача данных между приложением и отладчиком осуществляется через блок общей памяти размером 4 Кбайта с Mutex и двумя объектами Event, защищающими доступ к нему. Это четыре задействованных объекта ядра.

Понимание Win32 OutputDebugString - отличная статья по этому вопросу.

Однажды у меня возникли проблемы со строками в DLL-библиотеке ISAPI. По какой-то странной причине логическое значение IsMultiThread, определенное в System.pas, не было установлено!

Это вызывало странные AccessViolations, когда поток выполнял более одного потока... Простой "IsMultiThread:=true;" в инициализации блока это исправили.

Другие вопросы по тегам