我在接受采访时被问到如何使用GDB 在C程序中调试分段错误。
我告诉他们我们可以使用-g
选项编译我们的程序,因为它将调试信息添加到二进制文件中并且可以读取核心转储文件但是然后面试官告诉我他们是否有3到4个文件一起编译但是它们导致分段错误然后我们如何在GDB中调试?
答案 0 :(得分:3)
$ 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 :(得分:1)
如果您在Linux下工作,更容易找到分段错误的方法是使用名为VALGRIND的工具:http://valgrind.org/。
您只需要使用-g标志编译代码,然后运行./valgrind。
然后你会确切地知道在哪个函数和哪行代码中有一个错误未初始化的内存/内存从已分配的空间中读出或者......
答案 2 :(得分:1)
您只需在gdb下运行该程序,然后调试器捕获SIGSEGV并向您显示出现故障的行和指令。然后你只需检查变量和/或寄存器值,看看有什么不对。通常它是一个流氓指针值,尝试使用GDB访问它会产生错误,所以很容易。
是的,使用-g重新编译所有内容会很有帮助。面试官可能希望你描述你如何找出哪个文件有错误(gdb只是告诉你何时捕获信号)并且只是用调试信息重新编译那个文件。如果有20,000个源文件可能有用,但有3个或4个文件,那有什么意义呢?即使有较大的项目,你通常最终会通过10个函数和5个文件追逐坏指针,所以再一次,重点是什么?调试信息在运行时不需要任何费用,但它会在安装中花费磁盘空间。
答案 3 :(得分:1)
通过给出gcc文件名以正常方式编译代码
您将获得一个.out
文件,开始运行该文件并通过提供ps -aef | grep filename.out
来获取进程ID
在另一个窗口类型gdb
中输入,在gdb提示符下面给出attach processid
(您将从上面的命令中获取processid),让c
继续。执行完成后给出“ bt“在gdb内部。你将获得分割发生的地方。
答案 4 :(得分:0)
听起来他们正在设置它以便您可以在运行时逐步执行代码,您可以使用命令行版本执行此操作,或者我认为您可以获取GDB的GUI。
答案 5 :(得分:0)
可以使用以下步骤使用gdb调试分段错误
$ gdb <exec name >
$ r //run the pgm
$ where
$ f <1> <0> //to view the function n variables
$ list
$ p <variable>