Linux下将程序和调试符号分离并使用gdb定位

goodman 2017-09-28 11:37:40 2624

首先我们可以使用直接调试方法来调试程序,也就是直接使用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!

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
goodman
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
关于作者
goodman

goodman

wooshang@126.com

原创18
阅读8.9w
收藏6
点赞23
评论12
打赏用户 0
我要创作
分享技术经验,可获取创作收益
分类专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
goodman
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区