Недавно наткнулся на непонятную проблему. В небольших консольных прогах я использую маленькую dll собственного написания которая среди всего прочего ставит обработчик исключений вызывая SetUnhandledExceptionFilter (я это делал и в Dllmain, если код запроса =DLL_PROCESS_ATTACH и в отдельной экспортируемой функции вызывая её из главного модуля — на результат это не влияет). Обработчик выводил в консоль с помощью WriteConsole сообщение и завершал процесс. Однако когда я попробовал использовать свою dll в более сложной программе, где кроме главного модуля и библиотеки с обработчиком есть ещё одна dll, в которой и генерируется исключение, я обнаружил, что WriteConsole возвращается с ошибкой, а последующий вызов GetLastError даёт ERROR_INVALID_HANDLE, хотя хэндл, который я получал в dllmain или в специальной функции инициализации вызывая GetStdHandle был вполне валидным, по крайней мере до исключения.
Во вложении приведены два тестовых примера на ассемблере (код и бинарники), синтаксис fasm (sorry, на С я писать не умею)
После долгих экспериментов я выяснил, что проблему удаётся решить вызывая AllocConsole и GetStdHandle непосредственно в обработчике исключения (одного только GetStdHandle недостаточно). Однако это очень не удобно для консольных приложений.
Кто-нибудь сталкивался с пободной проблемой? Возможно, есть какие-нибудь предположения, почему исключение "портит" стандартный вывод (не просто хэндл, а весь канал), в тестовом примере я генерирую его обычным
xor eax,eax
mov [eax],eax
и проблем оно вызывать не должно. И почему портит его только исключение в дополнительной dll, но не портит исключение в главном модуле?