Отладка segv [crash, debugging]

Отладка segv

Я уверен, что многие из вас испытали это. Иногда при отладке сбоя вы добавляете строку трассировки, и вуаля сбой исчезает. Обычно это указывает на повреждение памяти, и вы ищете переполнения буфера и т. д. вокруг кода. Чтобы быть более конкретным, то же самое происходит даже для однопоточных приложений.

Как линия трассировки предотвращает сбой?

Строка трассировки — это фрагмент кода, поэтому следует перейти к сегменту кода, который доступен только для чтения, верно?

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


person HeretoLearn    schedule 18.12.2009    source источник
comment
В какой среде вы запускаете код? Не могли бы вы приложить код, так как это облегчит вам помощь для нас, SO'ers?   -  person t0mm13b    schedule 18.12.2009


Ответы (3)


arrow_upward
1
arrow_downward

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

Что касается этого утверждения:

Строка трассировки — это часть кода, поэтому она должна идти в сегмент кода.

Это зависит от того, что на самом деле делает ваш код отслеживания. Даже что-то такое простое, как:

write(0, "Hello, World!\n", 14);

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

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

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

В противном случае вы можете попробовать запустить код с отладочным пакетом malloc (доступно несколько). Даже если «ошибка» не воспроизводится, вы, вероятно, обнаружите, что таким образом неправильно манипулируете указателем.

Последнее предложение: перекомпилируйте свой код со всеми предупреждениями, включенными в компиляторе, и серьезно рассмотрите все предупреждения, сгенерированные таким образом. Обратите внимание, что в gcc параметр -Wall не включает все предупреждения.

person Mark Bessey    schedule 18.12.2009

arrow_upward
1
arrow_downward

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

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

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

person R Samuel Klatchko    schedule 18.12.2009
comment
Не помещайте строковые константы в память только для чтения. Где зависит от реализации, но в целом он помещается в сегмент кода. - person HeretoLearn; 18.12.2009
comment
Да, но это все еще может повлиять на сегмент данных. Если сегмент кода длиннее, начало сегмента данных может быть перемещено. - person R Samuel Klatchko; 18.12.2009

arrow_upward
0
arrow_downward

См. здесь за мой ответ на другой ТАК вопрос. Я не уверен на 100%, в какой среде вы работаете, но я думаю, что это один из вариантов Unix... Ссылка, которую я дал, демонстрирует простой трюк для перехвата обработчика SIGSEGV путем подключения к обработчику signal и в любое время во время выполнения. кода обработчик перехватывается и выгружает трассировку стека в файл для чтения.

Надеюсь, это поможет вам в отслеживании проблемы, С уважением, Том.

person t0mm13b    schedule 18.12.2009