首页 > 技术知识 > 正文

首先我们可以使用直接调试方法来调试程序,也就是直接使用gdb来运行看一个简单的示例:

#include <stdio.h> int main(int argc, char* argv[]) { char *s = NULL; s[0] = \0; return 0; }

编译并用gdb运行程序

gcc -o -g test test.c #一定要加上-g选项 gdb test (gdb) r Starting program: /home/lwx/workspace/test/test Program received signal SIGSEGV, Segmentation fault. 0x000000000040048b in main (argc=1, argv=0x7fffffffe3a8) at test.c:5 5 s[0] = \0; Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64 (gdb) list 1 #include <stdio.h> 2 int main(int argc, char* argv[]) 3 { 4 char *s = NULL; 5 s[0] = \0; 6 return 0; 7 } (gdb)

传统的调试段错误的步骤就是这样的,那么有没有其他的方法呢?我开发的程序在我这里没有错误,发给客户的时候突然错误了,有没有办法调试呢?

答案是有的,就是让程序运行崩溃的时候产生核心存储core文件,然后让用户把core文件发给我们我们再调试。首先要确定目标机器上时候开启核心转储

直接运行刚刚简单的例子会发现终端直接打印: [lwx@git test]$ ./test Segmentation fault

我们当然也可以使用ulimit -a来产看, 并使用ulimit -c unlimited来开启

[lwx@git ~]$ ulimit -a core file size (blocks, -c) 0 #这一项就是是否打开了核心存储,现在是0也就是不生成核心存储 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7809 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 1024 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited #并使用如下命令开启: ulimit -c unlimited

再次运行:

[lwx@git test]$ ./test Segmentation fault (core dumped) #这里可以生成了core文件

会在当前的目录下生成core.3773文件,3773是这个程序运行时的PID,有了core文件我们就可以很方便的调试了。

使用如下的命令就可以很方便的找到在哪里崩溃了: [lwx@git test]$ gdb test core.3773 GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1) Copyrigh&#116; (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type “show copying” and “show warranty” for details. This GDB was configured as “x86_64-redhat-linux-gnu”. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>… Reading symbols from /home/lwx/workspace/test/test…done. [New Thread 3773] Missing separate debuginfo for Try: yum –disablerepo=* –enablerepo=*-debug* install /usr/lib/debug/.build-id/f7/95efbe6950d1523c5748594c166cedd4254c33 Reading symbols from /lib64/libc.so.6…(no debugging symbols found)…done. Loaded symbols for /lib64/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2…(no debugging symbols found)…done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 Core was generated by `./test. Program terminated with signal 11, Segmentation fault. #0 0x000000000040048b in main (argc=1, argv=0x7fff1468cab8) at test.c:5 5 s[0] = \0; Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64 (gdb) list 1 #include <stdio.h> 2 int main(int argc, char* argv[]) 3 { 4 char *s = NULL; 5 s[0] = \0; 6 return 0; 7 } (gdb) bt #0 0x000000000040048b in main (argc=1, argv=0x7fff1468cab8) at test.c:5
<

到这里似乎很完美了,我把程序发给你你运行错误了吧core文件返给我我来调试就好了,但是我们这里忽略了一个很重要的问题,那就是使用-g选项生成的文件

是相对于strip是很大的,我们是不可以直接发给客户运行的,发给客户的通常都是经过strip的文件,看下下面的文件大小: [lwx@git test]$ ll total 12 -rwxrwxr-x. 1 lwx lwx 7622 Apr 2 22:26 test #没有strip的test是7622字节 -rw-rw-r–. 1 lwx lwx 97 Apr 2 22:25 test.c [lwx@git test]$ strip test [lwx@git test]$ ll total 12 -rwxrwxr-x. 1 lwx lwx 4160 Apr 2 22:26 test #小了很多,只要4160字节 -rw-rw-r–. 1 lwx lwx 97 Apr 2 22:25 test.c [lwx@git test]$

strip的文件产生的core是看不到符号表的,如果拿回来使用gdb调试会发现看不到函数调用自然也就没有用了了

Core was generated by `./test. Program terminated with signal 11, Segmentation fault. #0 0x000000000040048b in ?? () #但到底调用了那个函数发生的崩毁???? Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64

那么有没有办法将程序stip后也能定位呢?答案是有的,我们可以使用objcopy将程序和调试符号分离来达到目的

[lwx@git test]$ objcopy –only-keep-debug test test.sym [lwx@git test]$ strip test [lwx@git test]$ objcopy –add-gnu-debuglink=test.sym test.sym [lwx@git test]$ ll total 20 -rwxrwxr-x. 1 lwx lwx 4256 Apr 2 22:34 test #当然这里的test要比4160字节的稍微大点 -rw-rw-r–. 1 lwx lwx 97 Apr 2 22:25 test.c -rwxrwxr-x. 1 lwx lwx 6238 Apr 2 22:30 test.sym

这里你可以讲test程序发给用户测试了(这里的test是经过stip的,比较小的文件),当产生崩溃的时候只要客户讲core文件发给你你就可以直接调试了:

[lwx@git test]$ gdb test core.4471 GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1) Copyrigh&#116; (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type “show copying” and “show warranty” for details. This GDB was configured as “x86_64-redhat-linux-gnu”. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>… Reading symbols from /home/lwx/workspace/test/test…Reading symbols from /home/lwx/workspace/test/test.sym…done. done. [New Thread 4471] Missing separate debuginfo for Try: yum –disablerepo=* –enablerepo=*-debug* install /usr/lib/debug/.build-id/f7/95efbe6950d1523c5748594c166cedd4254c33 Reading symbols from /lib64/libc.so.6…(no debugging symbols found)…done. Loaded symbols for /lib64/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2…(no debugging symbols found)…done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 Core was generated by `./test. Program terminated with signal 11, Segmentation fault. #0 0x000000000040048b in main (argc=1, argv=0x7fff75f92028) at test.c:6 6 s[0] = \0; Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64 (gdb)
<

不要小看了stip后的文件和没有strip的文件,在实际的使用中会有很大的作用的,尤其在嵌入式的开发板上,nand或者norflash是非常小的,同时该方法也可以用在动态的调试上

end!

猜你喜欢