Нужна помощь с переполнением буфера - PullRequest
4 голосов
/ 30 апреля 2010

У меня переполнение буфера, которое я абсолютно не вижу (в C). Прежде всего, это происходит только в 10% случаев или около того. Данные, которые он извлекает из БД каждый раз, кажется, не сильно отличаются между исполнениями ... по крайней мере, не настолько различны, чтобы я мог найти какой-либо различимый паттерн относительно того, когда это происходит. Точное сообщение от Visual Studio:

Произошло переполнение буфера в hub.exe который повредил внутреннее состояние программы. Нажмите Перерыв для отладки программы или Продолжить завершить программу.

Подробнее см. В разделе справки. «Как отладить проблемы переполнения буфера».

Если я отлаживаю, я обнаруживаю, что он не работает в __report_gsfailure(), что, я уверен, происходит из флага / GS на компиляторе, а также означает, что это переполнение стека, а не кучи. Я также могу видеть функцию, которую он бросил, когда уходил, но я не вижу там ничего, что могло бы вызвать такое поведение, функция также существует в течение длительного времени (более 10 лет, хотя и с некоторыми незначительными изменениями) и, насколько я знаю, этого никогда не было.

Я бы опубликовал код функции, но он довольно длинный и ссылается на множество проприетарных функций / переменных / и т. Д.

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

Ответы [ 5 ]

3 голосов
/ 30 апреля 2010

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

2 голосов
/ 30 апреля 2010

Хотя это не поможет вам в Windows, Valgrind - безусловно, лучший инструмент для обнаружения плохого поведения памяти.

Если вы отлаживаете стек, вам нужно перейти к низкоуровневым инструментам - поместите канарейку в кадр стека (возможно, буфер, заполненный чем-то вроде 0xA5) вокруг любых потенциальных подозреваемых. Запустите программу в отладчике и посмотрите, какие канареки больше не имеют нужный размер и содержат правильное содержимое. Делая это, вы сожрете большой кусок стека, но это может помочь вам точно определить, что происходит.

1 голос
/ 01 мая 2010

Одна вещь, которую я сделал в прошлом, чтобы помочь сгладить такую ​​загадочную ошибку, как это, заключалась в создании переменной с глобальной видимостью с именем checkpoint. Внутри функции виновника я установил checkpoint = 0; в качестве первой строки. Затем я добавил операторы ++checkpoint; до и после вызовов функций или операций с памятью, которые, как я даже подозревал, может вызывать ссылку на недопустимую память (плюс добавление остальной части кода, чтобы у меня была хотя бы контрольная точка каждые 10 строк или около того). Когда ваша программа падает, значение checkpoint сузит диапазон, на котором вы должны сосредоточиться, до нескольких строк кода. Это может быть немного излишним, я делаю такие вещи во встроенных системах (где инструменты типа valgrind не могут быть использованы), но это все равно должно быть полезно.

0 голосов
/ 01 мая 2010

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

0 голосов
/ 30 апреля 2010

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

...