LINUX.ORG.RU

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

 , , , ,


1

3

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

Плохо. Надо аккуратнее код писать и поменьше указателей и магии с ними... valgrind тебе в помощь, по идее он умеет такое.

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

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

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

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

user2132
() автор топика

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

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

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

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

Сами в коде по указателю другую функцию не вызываем, но в коде есть активное использование memset, memcpy, полагаем, где-то есть выход за пределы памяти.

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

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

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

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

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

А как на офтопике это сделать ?

с офтопиком не работал лет 10. но принципы те же. вот думаю, стек вы там расписали.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от user2132

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

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

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

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

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

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

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

qulinxao3 ★★
()
Ответ на: комментарий от trex6
  1. Затереть адрес возврата на стеке.

написал это двумя постами выше

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

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

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

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

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

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

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

Владимир

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

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

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

попортить виртуальную таблицу класса

А что, их не в read-only секции складывают? Странно, если так. Впрочем, всегда можно попортить указатель на vtable.

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

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

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

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

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

anonymous
()

LLVM Address Sanitizer

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

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

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

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

Плюсую. Неистово плюсую. =)))

Я бы начал с того, что убрал бы borland.

Да. С этого и следовало бы начать.

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

На офтопике есть аналог valgrind, DrMemory. Но с ним больше мороки. Если valgrind лопает любую сборку программы, то этому подавай с отладочными символами.

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

Логи и тесты - наше всё. Нет их? ССЗБ.

Хороший совет.
Без логов это как - «телега без кобылы».

Владимир

anonymous
()

+2 Адрес Ассенизатор

anonymous
()

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

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

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

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

DllMain
()

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

Просто используй Rust или вот Bosque - очередной убийца C++ от MS, например, и все у тебя будет хорошо в жизни.

Разорванный Владимир

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

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

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

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

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

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

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

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

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

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

DllMain
()

windbg[br] !analyze -v

anonymous
()

капец сколько мамкиных какеров в теме дали бестолковых советов
но я уже windbg посоветовал /thread

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.