美文网首页
程序core了,调试看到的还是问号

程序core了,调试看到的还是问号

作者: 尧字节 | 来源:发表于2022-04-30 21:03 被阅读0次

一 背景

C程序发布的时候,经常去掉-g编译选项的,那么这就遇到一个问题,当程序运行core dump后,想去调试查看core的具体信息,会发现很多符号都被优化掉了,看到的栈信息要么是问号,要么变量无法打印值;
去掉符号表,却可以让程序体积更小,而且不容易泄漏程序的信息,更安全些。

这就产生了矛盾,我们在运行的时候不需要符号表,调试的时候需要符号表,那我们能否把符号表在发布程序的时候删除,调试的时候加载符号表信息那,这样就满足了需要。

二 测试程序

2.1 测试源码

为了直观起见,先写个简单的c代码用于演示,代码如下:

  1 #include <stdio.h>
  2 
  3 int func()
  4 {
  5     int a = 5;
  6     int b = a*5+8;
  7     int * pi = NULL;
  8     *pi = 0;
  9     printf("In func a is:%d b is:%d",a,b);
 10 }
 11 
 12 int main()
 13 {
 14     int a = func();
 15     printf("%d\n", a);
 16 }

2.2 编译

编译下:

miao@ubuntu-lab:~/c-test$ gcc -o test testdebug.c 

gdb调试看看:

root@ubuntu-lab:/home/miao/c-test# gdb ./test -q
Reading symbols from ./test...
(No debugging symbols found in ./test)
(gdb) quit

可以看到显示没有调试符号表信息,我们重新用-g编译选项试试:

root@ubuntu-lab:/home/miao/c-test# gcc -o test-debug -g ./testdebug.c 
root@ubuntu-lab:/home/miao/c-test# ls
test  test-debug  testdebug.c
root@ubuntu-lab:/home/miao/c-test# gdb ./test-debug -q
Reading symbols from ./test-debug...
(gdb) 

其实也不是完全没有符号,也还是有不少的,只是没有调试信息,可以用命令查看:

root@ubuntu-lab:/home/miao/c-test# readelf -h ./test|grep "string table index"
  Section header string table index: 30
root@ubuntu-lab:/home/miao/c-test# 
root@ubuntu-lab:/home/miao/c-test# readelf -h ./test-debug|grep "string table index"
  Section header string table index: 36

两个符号表的大小是有差距的差距6个,这个表示符号表的index的个数。
查下段表更清晰:

root@ubuntu-lab:/home/miao/c-test# readelf -S ./test-debug|grep '.debug'
  [28] .debug_aranges    PROGBITS         0000000000000000  00003035
  [29] .debug_info       PROGBITS         0000000000000000  00003065
  [30] .debug_abbrev     PROGBITS         0000000000000000  00003159
  [31] .debug_line       PROGBITS         0000000000000000  000031fd
  [32] .debug_str        PROGBITS         0000000000000000  0000326e
  [33] .debug_line_str   PROGBITS         0000000000000000  00003353
root@ubuntu-lab:/home/miao/c-test# 
root@ubuntu-lab:/home/miao/c-test# 
root@ubuntu-lab:/home/miao/c-test# 
root@ubuntu-lab:/home/miao/c-test# readelf -S ./test|grep '.debug'
root@ubuntu-lab:/home/miao/c-test# 

2.3 删除符号表

编译的时候可以采用-g编译,然后发布的时候去掉符号表,可以使用命令:strip。
如下最简单的处理下:

root@ubuntu-lab:/home/miao/c-test# ll -al ./test*
-rwxrwxr-x 1 miao miao 15984 Apr 30 10:41 ./test*
-rwxr-xr-x 1 root root 17304 Apr 30 10:48 ./test-debug*
-rw-rw-r-- 1 miao miao   171 Apr 30 10:41 ./testdebug.c
root@ubuntu-lab:/home/miao/c-test# strip ./test-debug
root@ubuntu-lab:/home/miao/c-test# ll -al
total 44
drwxrwxr-x  2 miao miao  4096 Apr 30 11:19 ./
drwxr-x--- 16 miao miao  4096 Apr 30 10:41 ../
-rwxrwxr-x  1 miao miao 15984 Apr 30 10:41 test*
-rwxr-xr-x  1 root root 14464 Apr 30 11:19 test-debug*
-rw-rw-r--  1 miao miao   171 Apr 30 10:41 testdebug.c
root@ubuntu-lab:/home/miao/c-test# nm -s test-debug
nm: test-debug: no symbols
root@ubuntu-lab:/home/miao/c-test# nm -s test
000000000000038c r __abi_tag
0000000000004010 B __bss_start
0000000000004010 b completed.0
                 w __cxa_finalize@GLIBC_2.2.5
...

可以看到strip处理过的testdebug,比不用-g 选项的编译出来的test文件更小,通过nm命令验证下,确实任何符号都被删除了,而不用-g编译的文件还可以看到符号信息的。

三 符号表引入测试

3.1 core测试

默认情况下不会产生core文件,加大core文件尺寸:

root@ubuntu-lab:/home/miao/c-test# ulimit -c unlimited
root@ubuntu-lab:/home/miao/c-test# tail -f 

重新编译运行:

root@ubuntu-lab:/home/miao/c-test# gcc  -g -o testdebug ./testdebug.c 
root@ubuntu-lab:/home/miao/c-test# strip testdebug -o testdebug-strip

看下core的信息:

root@ubuntu-lab:/home/miao/c-test# tail -f /var/log/apport.log
ERROR: apport (pid 125154) Sat Apr 30 11:52:20 2022: executable: /home/miao/c-test/testdebug-strip (command line "./testdebug-strip")
ERROR: apport (pid 125154) Sat Apr 30 11:52:20 2022: executable does not belong to a package, ignoring
ERROR: apport (pid 125154) Sat Apr 30 11:52:20 2022: writing core dump to core._home_miao_c-test_testdebug-strip.0.3fc6ea16-9440-4d72-81f8-7221d0b6684d.125153.3233349 (limit: -1)

调试下看看:

root@ubuntu-lab:/home/miao/c-test# gdb ./testdebug-strip /var/lib/apport/coredump/core._home_miao_c-test_testdebug-strip.0.3fc6ea16-9440-4d72-81f8-7221d0b6684d.125153.3233349 -q
Reading symbols from ./testdebug-strip...
(No debugging symbols found in ./testdebug-strip)
[New LWP 125153]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./testdebug-strip'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055d8d93bc178 in ?? ()
(gdb) where
#0  0x000055d8d93bc178 in ?? ()
#1  0x000055d8d93bc1b3 in ?? ()
#2  0x00007f173a2ebfd0 in __libc_start_call_main (main=main@entry=0x55d8d93bc19d, argc=argc@entry=1, argv=argv@entry=0x7ffe16913908) at ../sysdeps/nptl/libc_start_call_main.h:58
#3  0x00007f173a2ec07d in __libc_start_main_impl (main=0x55d8d93bc19d, argc=1, argv=0x7ffe16913908, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffe169138f8)
    at ../csu/libc-start.c:409
#4  0x000055d8d93bc085 in ?? ()
(gdb) bt
#0  0x000055d8d93bc178 in ?? ()
#1  0x000055d8d93bc1b3 in ?? ()
#2  0x00007f173a2ebfd0 in __libc_start_call_main (main=main@entry=0x55d8d93bc19d, argc=argc@entry=1, argv=argv@entry=0x7ffe16913908) at ../sysdeps/nptl/libc_start_call_main.h:58
#3  0x00007f173a2ec07d in __libc_start_main_impl (main=0x55d8d93bc19d, argc=1, argv=0x7ffe16913908, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffe169138f8)
    at ../csu/libc-start.c:409
#4  0x000055d8d93bc085 in ?? ()

因为没有符号信息,很可惜看不到具体的符号信息,也不知道在哪里core了。

(gdb) symbol-file /home/miao/c-test/testdebug
Load new symbol table from "/home/miao/c-test/testdebug"? (y or n) y
Reading symbols from /home/miao/c-test/testdebug...
(gdb) where
#0  0x000055d8d93bc178 in func () at ./testdebug.c:8
#1  0x000055d8d93bc1b3 in main () at ./testdebug.c:14
(gdb) 

看重点,加载符号文件,这个是直接加载没有strip前的文件,是包含符号表的。我们清晰的可以看到core的位置是在第8行。

顺便说下,gdb调试多线程,打印多线程堆栈信息命令:thread apply all bt full

3.2 提取符号表

root@ubuntu-lab:/home/miao/c-test# eu-strip testdebug -f testdebug.sym
root@ubuntu-lab:/home/miao/c-test# ll 
total 100
drwxrwxr-x  2 miao miao  4096 Apr 30 12:23 ./
drwxr-x--- 16 miao miao  4096 Apr 30 12:09 ../
-rwxr-xr-x  1 root root 15984 Apr 30 11:23 test*
-rwxr-xr-x  1 root root 14464 Apr 30 11:24 test-debug*
-rwxr-xr-x  1 root root 14568 Apr 30 12:23 testdebug*
-rw-rw-r--  1 miao miao   205 Apr 30 11:38 testdebug.c
-rwxr-xr-x  1 root root 14464 Apr 30 11:52 testdebug-strip*
-rwxr-xr-x  1 root root  5864 Apr 30 12:23 testdebug.sym*
root@ubuntu-lab:/home/miao/c-test# file test.sym
test.sym: cannot open `test.sym' (No such file or directory)
root@ubuntu-lab:/home/miao/c-test# file ./testdebug.sym
./testdebug.sym: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter \004, BuildID[sha1]=5881c326d8f784139407ed0c7576149cb19270f4, for GNU/Linux 3.2.0, with debug_info, not stripped

我们通过命令:eu-strip testdebug -f testdebug.sym提取testdebug中的符号表,保存为文件testdebug.sym。

我们gdb调试的时候导入这个符号试试:

root@ubuntu-lab:/home/miao/c-test# gdb ./testdebug-strip /var/lib/apport/coredump/core._home_miao_c-test_testdebug-strip.0.3fc6ea16-9440-4d72-81f8-7221d0b6684d.125153.3233349 -q
Reading symbols from ./testdebug-strip...
(No debugging symbols found in ./testdebug-strip)
[New LWP 125153]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./testdebug-strip'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055d8d93bc178 in ?? ()
(gdb) symbol-file /home/miao/c-test/testdebug.sym
Load new symbol table from "/home/miao/c-test/testdebug.sym"? (y or n) y
Reading symbols from /home/miao/c-test/testdebug.sym...
(gdb) where
#0  0x000055d8d93bc178 in func () at testdebug.c:8
#1  0x000055d8d93bc1b3 in main () at testdebug.c:14
(gdb) 

四 参考网站

[https://blog.csdn.net/bluebubble/article/details/10407217](https://blog.csdn.net/bluebubble/article/details/10407217)

相关文章

  • 程序core了,调试看到的还是问号

    一 背景 C程序发布的时候,经常去掉-g编译选项的,那么这就遇到一个问题,当程序运行core dump后,想去调试...

  • linux:abrt-cli list

    在linux调试程序,最痛苦的就是程序异常宕掉,但是找不到core文件,很难定位问题。但是有了core文件就容易定...

  • GDB常用命令

    1、file载入调试程序,同时加载符号表 2、core-file载入core dump程序映像,gdb命令行参数形...

  • core文件

    1、core文件简介 core文件其实就是内存的映像,当程序崩溃时,存储内存的相应信息,主用用于对程序进行调试。当...

  • Core Data并发调试

    Core Data并发调试 Core Data并发调试

  • 玩转ASP.NET Core中的日志组件

    简介 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息。ASP.NET Core中内置...

  • VS ASP.net Core Web 调试Docker

    一、概述 学习在VS2019建立ASP.net Core Web程序,并用VS支持的Docker调试方式调试运行程...

  • 挂了而且gdb显示问号!

    这两天遇到一个程序挂的问题,关键是原因还不好找,虽然core了产生了core文件,但是通过gdb调试的时候很遗憾,...

  • 利用Core Dump调试程序

    描述 这里介绍Linux环境下使用gdb结合core dump文件进行程序的调试和定位。 简介 当用户程序运行,可...

  • coredump备忘

    背景 程序已经挂死等情况,内核会生成一个core文件(是内存映像以及调试信息)。可以通过使用gdb来查看core文...

网友评论

      本文标题:程序core了,调试看到的还是问号

      本文链接:https://www.haomeiwen.com/subject/anvyyrtx.html