Однажды у меня возникла проблема, когда приложение вело себя так же, как ваше. Это оказалось неприятным переполнением буфера в sprintf. Естественно, он работал, когда запускался с отладчиком. Что я сделал, так это установил необработанный фильтр исключений ( SetUnhandledExceptionFilter ), в котором я просто бесконечно блокировался (используя WaitForSingleObject на фиктивном дескрипторе со значением времени ожидания INFINITE).
Так что вы могли бы что-то вроде:
long __stdcall MyFilter(EXCEPTION_POINTERS *)
{
HANDLE hEvt=::CreateEventW(0,1,0,0);
if(hEvt)
{
if(WAIT_FAILED==::WaitForSingleObject(hEvt, INFINITE))
{
//log failure
}
}
}
// somewhere in your wmain/WinMain:
SetUnhandledExceptionFilter(MyFilter);
Затем я подключил отладчик после того, как ошибка проявилась (программа GUI перестала отвечать).
Тогда вы можете взять дамп и поработать с ним позже:
.dump / ma path_to_dump_file
Или отладить прямо сейчас. Самый простой способ - отследить, где контекст процессора был сохранен механизмом обработки исключений во время выполнения:
s-d esp Диапазон 1003f
Команда будет искать адресное пространство стека для записей КОНТЕКСТА при условии продолжительности поиска. Я обычно использую что-то вроде 'l? 10000' . Обратите внимание, что не используйте неоправданно большие числа в качестве записи, которую вы ищете, обычно рядом с рамкой фильтра необработанных исключений.
1003f - это комбинация флагов (я думаю, что она соответствует CONTEXT_FULL), используемая для захвата состояния процессора.
Ваш поиск будет выглядеть примерно так:
0: 000> s-d esp l1000 1003f
0012c160 0001003f 00000000 00000000 00000000? ...............
Получив результаты, используйте адрес в команде cxr:
.cxr 0012c160
Это приведет вас к этому новому КОНТЕКСТУ, точно в момент сбоя (вы получите точно трассировку стека в момент сбоя вашего приложения).
Дополнительно используйте:
.exr -1
чтобы точно выяснить, какое исключение произошло.
Надеюсь, это поможет.