Как быстро обнаружить одну функцию, вызывающую переполнение стека в Visual C ++? - PullRequest
2 голосов
/ 12 августа 2011

У меня огромная база кода C ++.Для определенного набора данных переполнение стека.Если я запускаю программу в отладчике Visual Studio, я получаю стек вызовов из 30 незнакомых функций - одна (или несколько) из этих функций создали слишком большой объект в стеке, что приводит к исчерпанию стека.Я посмотрел на все функции, и в этом нет ничего очевидного - ничего подобного

char buffer[512 * 1024];

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

Как быстро определить функцию, которая создала слишком большой набор объектов в стеке и вызывает переполнение буфера?

Ответы [ 3 ]

4 голосов
/ 12 августа 2011

Если у вас есть трассировка стека (и вы должны ее получить), вы можете получить доступ к адресам фреймов.

Одна функция, вызывающая проблему, должна привести к огромному скачку в указателях кадров.

Если его нет, проверьте размер стека, он может быть слишком маленьким.

РЕДАКТИРОВАТЬ: Как отладить неочевидные проблемы с VC ++? (гм ... я кодирую на Unix: /)

Элан Раскинг выступил с большой речью о расследовании в своей 2011 презентации GDC ( PDF ).

Указатель стека (на x86) хранится в регистре ESP. Если вы посмотрите на разборку и проверите изменения ESP, то вы сможете увидеть, какая функция увеличивает / уменьшает ее с большим значением.

Пример на викибуках :

mov eax, DWORD PTR SS:[esp]
add esp, 4

Это add esp - это то, что вы хотите отслеживать. Если вы не используете VLA, добавленные / вычтенные значения жестко закодированы, поэтому их легко проверить.

4 голосов
/ 12 августа 2011

Вы можете использовать Анализ кода в Visual C ++, который доступен в более поздних выпусках. Предупреждение ( C6262 ) генерируется, если функция использует стек выше некоторого предела. Вы можете использовать переключатель /analyze:stacksize, где stacksize - желаемый предел.

2 голосов
/ 12 августа 2011

Поток, который превышает выделение стека, вызовет исключение. Это исключение можно перехватить с помощью ключевых слов __try и __except в Microsoft Visual C ++. Вы можете обернуть свои функции внутри этого блока try-Кроме того, чтобы увидеть, если они вызывают переполнение стека.

Посмотрите здесь: Как перехватить переполнение стека в приложении Visual C ++

...