Не могу отследить нарушение доступа 0xC00000FD
Я использую VS2008, и приложение My MFC начало аварийно завершать работу при установке точек останова или работе курсора. Я получаю много ошибок, как это:-
First-chance exception at 0x78a5727c (mfc90ud.dll) in MyApp.exe: 0xC0000005: Access violation reading location 0xfffffffc.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
First-chance exception at 0x00000000 in MyApp.exe: 0xC0000005: Access violation reading location 0x00000000.
Стек вызовов не так уж и остался, он только перечисляет код в NT.dll
> 00000000()
ntdll.dll!7c9032a8()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c90327a()
ntdll.dll!7c92aa0f()
ntdll.dll!7c90e48a()
ntdll.dll!7c9032a8()
Я не могу найти проблему, используя точки останова или пошагово просматривая мой код. Приложение "кажется" работает нормально, если оно запускается с использованием F5 в VS.
Каков наилучший способ отследить эту проблему?
4 ответа
Где переполнение стека от заголовка вашего вопроса? Нарушения доступа обычно указывают на недопустимую разыменование указателя.
Используйте свою историю ревизий, чтобы найти первую версию, в которой началось бурное развитие событий, а затем критически проанализируйте весь материал указателей, происходящий внутри и вокруг кода, модифицированного в этой ревизии.
В Интернете есть несколько "шаблонов", которые некоторые используют для создания своих программ для Windows. WndProc()
case WM_CLOSE:
PostQuitMessage(SUCCESS);
break;
case WM_DESTROY:
DestroyWindow(hwnd);
break;
Мы получаем это:
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(SUCCESS);
break;
Если SUCCESS
это 0, DestroyWindow()
получает нулевой указатель, который создает исключение при закрытии окна.
Я буду использовать свои навыки экстрасенсорной отладки и скажу вам, что вы перезаписываете буфер, который находится в стеке - в частности, вы записываете слишком много нулей в буфер, который недостаточно велик для его хранения.
У вас есть классические признаки разбитого стека - первый AV, который вы ударили, пытается получить доступ к нулю минус несколько байтов - явно смещение от вашего указателя стека на ваши параметры или ваши локальные переменные. (Я никогда не могу вспомнить, какие из них находятся выше указателя стека, а какие - ниже.) Затем у вас есть несколько строк, которые указывают, что указатель инструкции был установлен на ноль, что часто происходит потому, что адреса возврата функций в кадрах стека имеют был перезаписан с нулевыми значениями - потому что вы перезаписали буфер на основе стека и повредили все другие важные вещи в стеке. Когда ваша программа пытается вернуться из текущей функции, она смотрит в стек, чтобы увидеть, откуда она думает, откуда она пришла, видит ноль и сразу же переходит туда. Упс!
Поскольку ваш стек перегружен, вы можете не найти трассировку стека слишком полезной; ваши кадры стека, вероятно, будут повреждены этой точкой.
В Visual Studio есть возможность где-то разбить первое исключение (не помню точно, где оно находится, может быть, пункт меню исключений в подменю отладки?) Вы хотите включить это и посмотреть, как стеки вызовов вызываются в момент их возникновения.
Существует также возможность включить Microsoft Symbol Server, который автоматически загрузит соответствующие символы для любой системы, которую вы увидите в стеке. (извините, не помню, как именно это настроить).