前两天写程序的时候遇到一个问题,程序在运行的时候会中途挂掉,gdb调试显示段错误,但是bt查看的时候显示的堆栈信息全是问号“?”
1、 先说堆栈显示问题,这种情况大致分两种,一个是堆栈被破坏无法正常显示,一个是编译的时候将调试信息删掉了。
堆栈被破坏可能是代码中有访问空指针或者访问被释放的局部变量等其他原因,当然这些操作也是导致段错误的原因;编译时删掉调试信息是减小文件大小合理节省空间的一种方法,我查看makefile的时候发现里面有一个命令即arm-linux-strip。
该命令可以清除执行文件中不必要的标识符以及调试信息,可以减少文件的大小而不影响正常使用,但是文件一旦strip之后就不能恢复原样了,并且被strip后的文件不包含调试信息,因此调试的时候就会没有显示调试信息。实际上strip跟tar一样都是为了不让文件那么大,但是tar是基于压缩,而strip是基于删减。
将makefile中运行该命令的地方注释掉,再去运行gdb调试就可以正常显示堆栈了。
2、接着说段错误的问题,排查代码发现我在定义了一个指针变量之后直接置 NULL,在该指针变量没有空间的情况下给他里面的成员赋值,由此导致了段错误。所以大家在给成员变量赋值之前先考虑定义一个该结构体的变量而不是一个该结构体的指针,这样可以避免检查不到位导致程序崩溃。
有的时候gdb无法显示有没有strip的时候怎么办呢,那就只能用最笨的方法了,就是加打印信息,看程序走到哪里会挂掉,依次排查。