Не могу отследить нарушение доступа 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, который автоматически загрузит соответствующие символы для любой системы, которую вы увидите в стеке. (извините, не помню, как именно это настроить).

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