Есть ли способ предотвратить сбой приложения при повреждении кучи?- язык программирования C - PullRequest
1 голос
/ 29 сентября 2010

Иногда при выполнении я получаю это сообщение об ошибке в VS2010 при попытке освободить память:

Windows запустила точку останова в [APPNAME] .exe.

Это может быть связано с повреждением кучи, что указывает на ошибку в [APPNAME] .exe или любой из загруженных им библиотек DLL.

Это также может быть связано с тем, что пользователь нажимает клавишу F12, когда [APPNAME] .exe имеет фокус.

Окно вывода может содержать больше диагностической информации.

Что означает что-то не так с кучей или указателем.

Моя проблема в том, что эта ошибка приводит к сбою моего приложения при его сборке в виде выпуска.

Кроме того, это просто модуль более крупного приложения, и когда происходит сбой, все исчезает.

Я бы хотел справиться с этой ошибкой.

Из MSDN на "бесплатно":

Если при освобождении памяти возникает ошибка, то errno устанавливается с информацией из операционной системы о характере сбоя. Для получения дополнительной информации см. Errno, _doserrno, _sys_errlist и _sys_nerr.

Существует функция errno_t _get_errno( int * pValue );, которая возвращает код ошибки.

Если я нажимаю продолжить в сообщении об ошибке, показанном выше, эта функция возвращает код ошибки. С помощью этого кода я могу обнаружить ошибку, создать стек вызовов и тихо завершить работу моей функции.

Есть ли какой-нибудь переключатель компилятора или что-то такое, чтобы предотвратить сбой приложения при сбое free и позволить мне выйти из него по-своему ??

Ответы [ 4 ]

8 голосов
/ 29 сентября 2010

Если куча повреждена, все ставки отключены. Распределение памяти может не получиться (если они не в стеке), они могут вернуть указатели на дурацкие области, и даже существующий материал в кучебыть искалеченным до неузнаваемости.В таких случаях вам на самом деле лучше не рушиться, поскольку любое действие, которое вы предпринимаете (даже пытаясь грациозно выйти), может только ухудшить ситуацию.куча, и исправить или удалить ее.

4 голосов
/ 29 сентября 2010

Исправьте ваш код вместо того, чтобы игнорировать такую ​​серьезную ошибку.В вашем производственном коде не должно быть таких серьезных ошибок памяти.AFAIK нет простого способа справиться с этим, и это не без причины.Кстати, я думал, что диалог появляется только в режиме отладки.В режиме выпуска ошибка памяти не должна быть обнаружена, и приложение должно немедленно аварийно завершить работу (или работать с поврежденной кучей, юк).

4 голосов
/ 29 сентября 2010

Теоретически вы пытаетесь предотвратить сбои приложения с помощью SEH.AFAIK «точка останова отладки» является своего рода исключением SEH, которое может быть обработано.

__try {
    // do something here
} __except(EXCEPTION_EXECUTE_HANDLER) {
}

Вышеупомянутый блок __try / __except будет перехватывать все исключения (как C ++, так и SEH).

ОДНАКО

Я считаю, что вы не должны этого делать.Повреждение кучи, а также любой другой недопустимый доступ к памяти - это ошибка Как только это произойдет - повреждение обычно невосстановимо .Вы можете предотвратить сбой (надеюсь), но вы не можете гарантировать, что ваша программа сделает то, что должна.Отныне он может рухнуть в любом другом месте.

Вместо предотвращения сбоя, я предлагаю вам НАЙТИ преступника, который осмеливается перезаписать запрещенную память и испортить кучу.

0 голосов
/ 29 сентября 2010

Многие программы Windows используют HeapSetInformation с HeapEnableTerminationOnCorruption, чтобы обеспечить немедленный сбой программы при обнаружении повреждения кучи.Это мера безопасности, поскольку коррупция в куче может быть использована.Единственное, что нужно сделать - это немедленно вызвать повреждение кучи.

Но если вы пытаетесь отладить, и это сборка релиза, этот параметр может затруднить отладку проблемы.Похоже, у вас есть модуль, который запускается внутри чужого приложения (хотя я не уверен из вашего описания).В этом случае может случиться так, что другое приложение устанавливает флаг завершения кучи.К сожалению, его нельзя сбросить после установки (для каждого процесса).

Вам потребуется подключить отладчик для создания файла дампа при возникновении сбоя и попытаться отладить его.

...