В Delphi поток OutputDebugString безопасен?
Является
OutputDebugString(PAnsiChar(''));
поток безопасно?
Я / мы использовали его в потоках для отладки, и мне никогда не приходило в голову, что я должен делать это по-другому.
(Delphi 7)
3 ответа
Не волнуйся, это так.
Когда OutputDebugString() вызывается приложением, оно предпринимает следующие шаги. Обратите внимание, что ошибка в любой момент оставляет все это и обрабатывает запрос на отладку как запрет (строка никуда не отправляется).
- Откройте DBWinMutex и дождитесь эксклюзивного доступа к нему.
- Сопоставьте сегмент DBWIN_BUFFER с памятью: если он не найден, отладчик не работает, поэтому весь запрос игнорируется.
- Откройте события DBWIN_BUFFER_READY и DBWIN_DATA_READY. Как и в случае сегмента общей памяти, отсутствующие объекты означают, что отладчик недоступен.
- Подождите, пока событие DBWIN_BUFFER_READY будет сигнализировано: это говорит о том, что буфер памяти больше не используется. В большинстве случаев об этом событии будет сигнализироваться сразу же после его проверки, но он не будет ждать дольше 10 секунд, пока буфер не станет готовым (тайм-аут отменяет запрос).
- Скопируйте до 4 Кбайт данных в буфер памяти и сохраните там также текущий идентификатор процесса. Всегда ставьте байт NUL в конце строки.
- Сообщите отладчику, что буфер готов, установив событие DBWIN_DATA_READY. Отладчик берет это оттуда.
- Отпустите мьютекс
- Закройте объекты Event и Section, хотя мы оставим дескриптор мьютекса на потом.
Ну, не то, чтобы это не было правдой, это так, но просто для того, чтобы вам не пришлось просто поверить на слово Ливен:
Передача данных между приложением и отладчиком осуществляется через блок общей памяти размером 4 Кбайта с Mutex и двумя объектами Event, защищающими доступ к нему. Это четыре задействованных объекта ядра.
Понимание Win32 OutputDebugString - отличная статья по этому вопросу.
Однажды у меня возникли проблемы со строками в DLL-библиотеке ISAPI. По какой-то странной причине логическое значение IsMultiThread, определенное в System.pas, не было установлено!
Это вызывало странные AccessViolations, когда поток выполнял более одного потока... Простой "IsMultiThread:=true;" в инициализации блока это исправили.