Как найти ошибку сегментации из нескольких файлов, используя GDB - PullRequest
5 голосов
/ 23 января 2012

Меня спросили в интервью как вы можете отладить ошибку сегментации в программе на C, используя GDB .

Я сказал им, что мы можем скомпилировать нашу программу с опцией -g, чтобы она добавляла отладочную информацию в двоичный файл и могла читать файл дампа основной памяти, но затем интервьюер сказал мне, если у нас есть от 3 до 4 скомпилированных файлов, но один из них вызывая ошибку сегментации, тогда как мы отлаживаем в GDB?

Ответы [ 6 ]

3 голосов
/ 23 января 2012
$ gcc -ggdb s1.c s2.c s3.c -o myprog
$ gdb myprog
(gdb) run --arg1 --arg2

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

Вы также можете присоединиться к уже запущенной программе, используя gdb --pid <the programs pid>.

Либо с файлом ядра.или одним из описанных выше способов, когда у вас появляется приглашение GDB после сбоя, введите backtrace (или bt для краткости), и GDB покажет вам стек во время сбоя, включая имена файлов и строкуномера каждого звонка и текущей выполняемой линии.

1 голос
/ 21 октября 2013

скомпилируйте код обычным способом, указав имя файла gcc, вы получите файл .out, запустите его и получите идентификатор процесса, указав ps -aef | grep filename.out

в другом окне типа gdb ивведите в командной строке gdb команду attach processid (processid, которую вы получите из приведенной выше команды), введите c для продолжения. Как только выполнение завершится, дайте "bt" внутри gdb. Вы получите место, где происходит сегментация.

1 голос
/ 23 января 2012

Вы просто запускаете программу под gdb, и отладчик с перехватывает SIGSEGV и показывает вам строку и инструкцию, которая вызвала ошибку.Затем вы просто исследуете переменную и / или регистрируете значения, чтобы увидеть, что не так.Обычно это неверное значение указателя, и попытка получить к нему доступ с помощью GDB приведет к ошибке, поэтому это легко.

И да, перекомпилирование всего с -g было бы полезно.Интервьюер, вероятно, хотел, чтобы вы описали, как вы выясните, в каком файле произошла ошибка (GDB просто сообщает вам, когда он ловит сигнал), и просто перекомпилируйте этот файл с отладочной информацией.Если есть 20 000 исходных файлов, которые могут быть полезны, но с 3 или 4 файлами, какой смысл?Даже в более крупных проектах вы обычно в конечном итоге гоняетесь за плохим указателем через 10 функций и 5 файлов, так что опять же, какой в ​​этом смысл?Отладочная информация ничего не стоит во время выполнения, хотя она стоит дискового пространства при установке.

1 голос
/ 23 января 2012

Если вы работаете в Linux, проще найти ошибку сегментации, используя инструмент VALGRIND: http://valgrind.org/.

Вам просто нужно скомпилировать код с флагом -g, а затемзапустите ./valgrind.

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

0 голосов
/ 07 февраля 2014

можно использовать следующие шаги для отладки ошибки сегментации, используя gdb

$ gdb <exec name > 
$ r          //run the pgm
$ where 
$ f <1> <0>   //to view the function n variables 

$ list 

$ p <variable>     
0 голосов
/ 23 января 2012

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

...