Отладка ошибки памяти с помощью GDB и C ++ - PullRequest
4 голосов
/ 04 ноября 2008

Я запускаю свою программу на C ++ в gdb. Я не очень разбираюсь в gdb, но получаю сообщения вроде:

warning: HEAP[test.exe]:
warning: Heap block at 064EA560 modified at 064EA569 past requested size of 1

Как я могу отследить, где это происходит? Просмотр памяти не дает мне никаких подсказок.

Спасибо!

Ответы [ 5 ]

4 голосов
/ 04 ноября 2008

Итак, вы разоряете свою кучу. Вот хороший учебник GDB , чтобы иметь в виду.

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

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

1 голос
/ 14 июля 2009

Одна вещь, которую вы можете попробовать, так как это то же самое, что и стандартная библиотека libc, с настроенной переменной среды MALLOC_CHECK_ (man libc).

Если вы не можете выйти из GDB (если ваше приложение закрывается, просто используйте «r» для его повторного запуска), вы можете установить точку останова памяти по этому адресу, «hbreak 0x64EA569», также используйте «help hbreak» для настройки опции включения или выключения условия или другой точки останова для предотвращения чрезмерного ввода этой точки останова ....

Вы можете просто настроить файл журнала, установить журнал ... установить трассировку стека на каждом разрыве, "display / bt -4", затем нажать r, и просто удерживать нажатой клавишу ввода и позволить ему прокрутить «или используйте c ## для продолжения x раз ... и т. д.», в конце концов вы увидите то же самое утверждение, а затем у вас будет (из-за display / bt) трассировка стека, которую вы можете соотнести с изменяемым кодом по этому адресу ...

1 голос
/ 05 ноября 2008

Если вы можете использовать другие инструменты, я настоятельно рекомендую попробовать Valgrind . Это инструментарий инструментария, который может запускать ваш код таким образом, который позволяет ему обычно останавливаться на точной инструкции, которая вызывает ошибку. Таким образом, ошибки кучи обычно легко найти.

1 голос
/ 05 ноября 2008

Вы, вероятно, можете использовать функцию, называемую «точка наблюдения». Это похоже на точку останова, но при изменении памяти отладчик останавливается.

Я дал грубое представление о том, как использовать это в ответе на другой вопрос.

0 голосов
/ 07 июня 2013

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

itemsetList_t ** iteration_isets;

Таким образом, в realloc вместо:

iteration_isets = realloc(iteration_isets, sizeof(itemsetList_t *) * max_elem);

У меня было:

iteration_isets = realloc(iteration_isets, sizeof(int) * max_elem);

И это вызвало мою проблему с кучей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...