LINUX.ORG.RU

Как отловить в с++ прыжок из секции кода в секцию данных ?

 , , , ,


1

3

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

Ответ на: комментарий от peregrine

На borland пишу, подскажи, чем ловить там. Встроенный codeguard не ловит. По стеку оставшемуся только видно, что до этого было delete[], которое возможно потерло чужую память.

user2132 ()
Ответ на: комментарий от alysnix

Да в настройках проекта стоят галочки оставлять дебаг инфу. При остановке на acess violtaion в дебаг вкладке стек трейс ничего нету. Почему-то теряет видимо эту инфу. Нужен какой-нибудь внешний инструмент, более продвинутый чем среда разработки видимо.

user2132 ()

улететь из кода в данные в плюсах можно только двумя способами(остальные от него производные)

  1. вызвать функцию по мусорному указателю на функцию
  2. попортить виртуальную таблицу класса и вызвать вирт. функцию

ну плюс чудачества со встроенным асмом.

alysnix ()
Ответ на: комментарий от user2132

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

alysnix ()
Ответ на: комментарий от user2132

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

alysnix ()
Ответ на: комментарий от user2132

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

alysnix ()
Ответ на: комментарий от user2132

«следовательно»(есть вероятность крайне больше нуля) трётся именно место откуда(либо чем) дебагер инфу колектит

а сырцы/код ваще ваш али исследуется?

от ответа на вопрос зависит ошибка это или …. https://en.wikipedia.org/wiki/Antoine_Jacques_Claude_Joseph,_comte_Boulay_de_la_Meurthe

qulinxao3 ()
Ответ на: комментарий от user2132

На borland пишу, подскажи, чем ловить там. Встроенный codeguard не ловит. По стеку оставшемуся только видно, что до этого было delete[], которое возможно потерло чужую память

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

byko3y ()
Ответ на: комментарий от alysnix

улететь из кода в данные в плюсах можно только двумя способами(остальные от него производные)

Можно просто затереть какие-либо данные /например за пределами массива, …/.
И тогда происходят - «чудеса».

Кошки  - гавкают.
Собаки - мяукают.
...

Владимир

anonymous ()
Ответ на: комментарий от user2132

Вообще valgrind это внешняя штука (но только для linux-ов, маков, андроида и есть неофициальные порты на другие unix-like системы), но если у тебя windows only код, то тогда можешь попробовать статистическим анализатором по коду пробежаться. Оно, конечно не для этого, но какое-то говно найдёт скорее всего, если повезёт то и твоё. cppcheck как опенсорсный вариант.

peregrine ★★★★★ ()
Ответ на: комментарий от anonymous

Если проверять, то не этим.

Вообще-то, для офтопика лучше бы WinDbg. Идёт в составе офтопного SDK и, по сути, рекомендованное M$ средство отладки. Пример разборок со стеком – https://www.codeproject.com/Articles/6470/Debug-Tutorial-Part-2-The-Stack

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

Думаю, вот… А нет ли здесь какой пропаганды виндов? =))) Не тот же сайт, не?

anonymous ()
Ответ на: Re: Если проверять, то не этим. от anonymous

Re: Если проверять, то не этим.

И что дальше? Я в курсе что приведённая мною ссылка, это только одна часть. Но у ТС проблема со стеком, я ему именно эту ссылку и привёл, наивно полагая что по кодепроджекту, если ему нужно, то он остальное нароет сам.

И да. Всё таки WinDbg здесь более «к лицу», чем альтернативы.

anonymous ()

Но если ты всё-таки ССЗБ - то отладчиком конечно тоже можно…

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

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Я знаю, что логи и тесты помогут локализовать место _проявления_ ошибки с точностью до пары десятков строк исходника, на этом всё. В чём я себя должен убеждать?

DllMain ()
Ответ на: комментарий от pon4ik

дальше глазами ошибка ищется тривиально

Это когда ошибка в логике или что техническое по мелочи. А у ТС-а жесть с перетёртым стеком. Вот тебе пример даже: логи и тесты показали функцию f(), в которой процесс упал. Но истинная причина в том, что кто-то _выше_ по стэку вызовов перетёр текущий фрейм. Санитайзер скорее всего сразу укажет на проблемную функцию, а чувак с логами и тестами будет обходить весь граф вызовов f() и глазами искать ошибку. И правда тривиально

DllMain ()
Ответ на: комментарий от DllMain

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

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Не будет у тебя в тестах большого стек трейса

Большого не будет, будет непонятный - за счёт того что ошибочный код и место проявления ошибки удалены друг от друга более чем на десяток строк(в execution order). Поинт в том, что ub и прочее непотребство намного удобнее ловить санитайзерами. А нужность логов и, тем более, тестов я тоже не отрицаю

DllMain ()