• GDB调试之strip


    目录

    • strip命令简介
    • GDB调试strip后的文件

    stri命令简介

    GNU strip discards all symbols from object files objfile. The list of object files may include archives. At least one object file must be given.

    简单来讲就是给文件脱衣服,包括可执行文件和动态库等。

    可使用file命令查看文件的属性,file + 文件名,会显示出是否被strip

    例如,我们写一个简单的代码main.c

    1
    2
    3
    4
    
    int add(int a, int b)
    {
        return a+b;
    }
    

    编译生成so后,使用strip生成main_release.so,然后使用file查看两个so的状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    [root@VM_0_4_centos studyCode]# gcc main.c -o main.so -shared -g -fPIC
    [root@VM_0_4_centos studyCode]# ls
    main.c  main.so
    [root@VM_0_4_centos studyCode]# strip main.so -o main_release.so
    [root@VM_0_4_centos studyCode]# ls
    main.c  main_release.so  main.so
    
    [root@VM_0_4_centos studyCode]# file main.so
    main.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=2500b8ed287f2dff9f7f89b09f5acddf60f8a6c8, not stripped
    [root@VM_0_4_centos studyCode]# file main_release.so 
    main_release.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=2500b8ed287f2dff9f7f89b09f5acddf60f8a6c8, stripped
    

    未strip的文件较大,strip后的文件较小

    1
    2
    3
    4
    5
    
    [root@VM_0_4_centos studyCode]# ll
    total 24
    -rw-r--r-- 1 root root   51 Mar 28 23:03 main.c
    -rwxr-xr-x 1 root root 6008 Mar 28 23:41 main_release.so
    -rwxr-xr-x 1 root root 8784 Mar 28 23:40 main.so
    

    未strip的文件使用nm可查看符号,可使用gdb调试,
    strip的文件使用nm无法查看符号(加入-D参数可以继续查看),不可gdb调试,该过程不可逆

    符号表分为两部分,.systab和.dynsym部分,前者主要用于在debug和link中使用,后者主要在运行时使用,strip去掉的是.systab,所以对可执行文件和.so进行strip操作,不影响程序的执行,但是无法对so进行debug,而如果将中间文件.o进行strip操作,则无法完成编译(无法link)

    nm的-D参数含义如下,即显示动态符号而不是普通符号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    [root@VM_0_4_centos studyCode]# nm -help
    Usage: nm [option(s)] [file(s)]
     List symbols in [file(s)] (a.out by default).
     The options are:
      -a, --debug-syms       Display debugger-only symbols
      -A, --print-file-name  Print name of the input file before every symbol
      -B                     Same as --format=bsd
      -C, --demangle[=STYLE] Decode low-level symbol names into user-level names
                              The STYLE, if specified, can be `auto' (the default),
                              `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'
                              or `gnat'
          --no-demangle      Do not demangle low-level symbol names
      -D, --dynamic          Display dynamic symbols instead of normal symbols
          --defined-only     Display only defined symbols
    

    使用nm查看两个so后的效果如图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    [root@VM_0_4_centos studyCode]# nm main.so
    0000000000000655 T add
    0000000000201028 B __bss_start
    0000000000201028 b completed.6355
                     w __cxa_finalize@@GLIBC_2.2.5
    0000000000000570 t deregister_tm_clones
    00000000000005e0 t __do_global_dtors_aux
    0000000000200e00 t __do_global_dtors_aux_fini_array_entry
    0000000000200e10 d __dso_handle
    0000000000200e18 d _DYNAMIC
    0000000000201028 D _edata
    0000000000201030 B _end
    000000000000066c T _fini
    0000000000000620 t frame_dummy
    
    
    [root@VM_0_4_centos studyCode]# nm main_release.so 
    nm: main_release.so: no symbols
    

    加入-D参数,可以发现结果是相同的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    [root@VM_0_4_centos studyCode]# nm -D main.so 
    0000000000000655 T add
    0000000000201028 B __bss_start
                     w __cxa_finalize
    0000000000201028 D _edata
    0000000000201030 B _end
    000000000000066c T _fini
                     w __gmon_start__
    0000000000000520 T _init
                     w _ITM_deregisterTMCloneTable
                     w _ITM_registerTMCloneTable
                     w _Jv_RegisterClasses
    
    
    [root@VM_0_4_centos studyCode]# nm -D main_release.so 
    0000000000000655 T add
    0000000000201028 B __bss_start
                     w __cxa_finalize
    0000000000201028 D _edata
    0000000000201030 B _end
    000000000000066c T _fini
                     w __gmon_start__
    0000000000000520 T _init
                     w _ITM_deregisterTMCloneTable
                     w _ITM_registerTMCloneTable
                     w _Jv_RegisterClasses
    

    GDB调试strip后的文件

    此时对main_release.so进行gdb是无法加载符号表的(在一开始编译时就已经加入了-g参数)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    [root@VM_0_4_centos studyCode]# gdb main_release.so 
    GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-115.el7
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later 
    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:
    ...
    Reading symbols from /home/yu.tian/studyCode/main_release.so...Missing separate debuginfo for /home/yu.tian/studyCode/main_release.so
    Try: yum --enablerepo='*debug*' install /usr/lib/debug/.build-id/25/00b8ed287f2dff9f7f89b09f5acddf60f8a6c8.debug
    (no debugging symbols found)...done.
    

    既然strip的过程不可逆,那我们如何对strip后的可执行文件或库进行debug?

    为了兼顾,既将符号表去掉了,出问题时又能用符号表。采用符号表和可执行程序分离的方式

    制作符号表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    [root@VM_0_4_centos studyCode]# objcopy --only-keep-debug main.so main.dbg
    [root@VM_0_4_centos studyCode]# nm main.dbg
    0000000000000655 T add
    0000000000201028 B __bss_start
    0000000000201028 b completed.6355
                     w __cxa_finalize@@GLIBC_2.2.5
    0000000000000570 t deregister_tm_clones
    00000000000005e0 t __do_global_dtors_aux
    0000000000200e00 t __do_global_dtors_aux_fini_array_entry
    0000000000200e10 d __dso_handle
    0000000000200e18 b _DYNAMIC
    0000000000201028 B _edata
    0000000000201030 B _end
    000000000000066c T _fini
    0000000000000620 t frame_dummy
    0000000000200df8 t __frame_dummy_init_array_entry
    00000000000006f8 b __FRAME_END__
    0000000000201000 b _GLOBAL_OFFSET_TABLE_
    

    发现使用nm main.dbg和main.so查看到的符号相同,至此符号表已经创建成功

    添加符号表连接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    [root@VM_0_4_centos studyCode]# objcopy --add-gnu-debuglink=main.dbg main_release.so 
    [root@VM_0_4_centos studyCode]# gdb main_release.so 
    GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-115.el7
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later 
    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:
    ...
    Reading symbols from /home/yu.tian/studyCode/main_release.so...Reading symbols from /home/yu.tian/studyCode/main.dbg...done.
    done.
    

    可以看到此时gdb已经可以正常加载符号表了

    GDB调试之strip-蒲公英云

    增加:

    也可以不添加符号表

     而是使用gdb 

    使用gdb方式导入符号文件,即通过gdb -s在调试时

    # 调试进程

    $ gdb ./gaussdb -s gaussdb.symbol

    # 调试core文件

    $ gdb ./gaussdb core.xxxxx -s gaussdb.symbol导入符号文件

  • 相关阅读:
    【进程间通信】进程间通信方式汇总
    React.js学习(二):案例源码学习“排序动画”
    澳元兑美元预测:美元可能因美国经济衰退担忧而进一步下跌(MogaFX)
    【Python 常用脚本及命令系列 12.1 -- OpenCV 设置图片区域为某个颜色】
    Windows10安装配置Docker客户端和WSL2与Hyper-V虚拟机
    提高matlab运算效率——预分配内存
    ES-索引管理
    nuxt3项目使用pdfjs-dist预览pdf
    做了这些年开发,今天第一次梳理了这三种常用的变量
    Liunx 服务器安装Oracle JDK
  • 原文地址:https://blog.csdn.net/gezi322/article/details/127681639