переполнение буфера, обратный адрес возврата - PullRequest
0 голосов
/ 14 июня 2010

Когда я добавляю метод A, он вызывает переполнение буфера, но когда я возвращаюсь, он работает нормально. Я думал, что throw перемещает выполнение к методу вызывающего, поэтому адрес, по которому он идет, должен совпадать с адресом возврата, но я явно ошибаюсь. Есть ли способ узнать, к какому выбрасыванию адресов обращается отладчик Visual Studio?

Спасибо

Berkus: Означает ли это, что стек метода верхнего уровня поврежден? Так, например,

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

Тогда, возможно, что адрес возврата метода C в порядке, но адрес возврата метода B поврежден, вызывая переполнение буфера? Я вижу, что если нет броска, мое приложение работает нормально, поэтому я думаю, что у всех методов A, B и C есть действительные адреса возврата.

Ответы [ 3 ]

2 голосов
/ 14 июня 2010

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

0 голосов
/ 14 июня 2010

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

Разумеется, вполне возможно, что переполнение буфера может повредить данные, которые используются только обработкой исключений (что приводит к сбою броска), оставляя адрес возврата без изменений (что позволяет нормальному возврату завершиться успешно). Но опять же, это зависит от того, как ваш компилятор использует стек. (На другом компиляторе у вас могут быть совершенно другие симптомы). Также возможно, что коррупция вызвала другие проблемы, которые вы просто еще не заметили. Или что такое повреждение вызовет проблемы в будущем после следующей смены кода. Если стек (или другая память, от которой зависит C ++) будет поврежден, то может произойти практически все.

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

Если вы действительно знаете, что у вас переполнение буфера, нет смысла пытаться ответить на эти вопросы. Просто исправьте превышение.

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

0 голосов
/ 14 июня 2010

В C ++, если у вас нет блока try / catch, то это:

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

завершит приложение.Вы должны иметь блок try / catch в своем коде, если хотите избежать завершения.

...