zoukankan      html  css  js  c++  java
  • 对“线上问题 不能gdb调试怎么处理??“”的思考

    • Q1:线上问题的process 都为release版本!不带调试信息怎么查?(目前有时需要查线上问题, 不得不解决这个问题)  
      •   之前查问题都是编译环境编译一个带有debug信息的版本进行替换来调试,但是这是对必现问题,使用gdb调试没问题,如果是非必现问题呢?替换进程重新运行现象就会消失!
      • 解决方法:使用objcoy将信息表分离, 在打包环境编译进程时, makefile 中加入 -ggdb -O0 编译完成后使用objcopy 分离出调试信息, 然后strip 掉debug信息。
      • objcopy --only-keep-debug  test test.symbol         //拷贝出一个符号表文件
      • objcopy --strip-debug test   test.bin              //拷贝出一个执行文件
      • 分离出的调试信息debugsymbol还可以链接回可执行文件test中

        objcopy --add-gnu-debuglink test.symbol test

        然后就可以正常用addr2line等需要读取调试信息的程序了

        addr2line -e test 0x401c23



    • Q2: strip -s bin后的进程其符号表被去掉了,那么进程是怎样动态链接的呢? 动态链接是通过符号表完成重定位装载!!!
      • 实际上strip 后会发现strip后的so只少了symtab和strtab 以及debug信息!!保存链接符号的dynsym和dynstr都没有被strip掉
      • .dynsym

        为了表示动态链接这些模块之间的符号导入导出关系,ELF专门有一个叫做动态符号表(Dynamic Symbol Table)的段用来保存这些信息,

    这个段的段名通常叫做 .dynsym(Dynamic Symbol)

    与“.symtab”不同的是,“.dynsym”只保存了与动态链接相关的符号,对于那些模块内部的符号,比如模块私有变量则不保存。很多时候动态链接的模块同时拥有“.dynsym”和“.symtab”两个表,“.symtab”中往往保存了所有符号,包括“.dynsym”中的符号
     

    .dynamic

    动态链接ELF中最重要的结构应该是 .dynamic 段 ,这个段里面保存了动态链接器所需要的基本信息,比如依赖于哪些共享对象、动态链接符号表的位置、动态链接重定位表的位置、共享对象初始化代码的地址等

    .dynstr

    与“.symtab”类似,动态符号表也需要一些辅助的表,比如用于保存符号名的字符串表。静态链接时叫做符号字符串表“.strtab”(String Table),在这里就是动态符号字符串表 .dynstr

    .symtab &dynsym

    静态链接中有一个专门的段叫符号表 -- “.symtab”(Symbol Table), 里面保存了所有关于该目标文件的符号的定义和引用。动态链接中同样有一个段叫 动态符号表 -- “.dynsym”(Dynamic Symbol) 但.dynsym 相对于 .symtab 只保存了与动态链接相关的导入导出符号
     
     
    readelf -S test
    There are 35 section headers, starting at offset 0x7b2fc:
    
    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .interp           PROGBITS        000080f4 0000f4 000014 00   A  0   0  1
      [ 2] .hash             HASH            00008108 000108 000658 04   A  3   0  4
      [ 3] .dynsym           DYNSYM          00008760 000760 000cf0 10   A  4   1  4
      [ 4] .dynstr           STRTAB          00009450 001450 00137b 00   A  0   0  1
      [ 5] .gnu.version      VERSYM          0000a7cc 0027cc 00019e 02   A  3   0  2
      [ 6] .gnu.version_r    VERNEED         0000a96c 00296c 000060 00   A  4   3  4
      [ 7] .rel.dyn          REL             0000a9cc 0029cc 000070 08   A  3   0  4
      [ 8] .rel.plt          REL             0000aa3c 002a3c 0005a8 08   A  3  10  4
      [ 9] .init             PROGBITS        0000afe4 002fe4 000010 00  AX  0   0  4
      [10] .plt              PROGBITS        0000aff4 002ff4 000890 04  AX  0   0  4
      [11] .text             PROGBITS        0000b884 003884 00f158 00  AX  0   0  4
      [12] .fini             PROGBITS        0001a9dc 0129dc 000010 00  AX  0   0  4
      [13] .rodata           PROGBITS        0001a9ec 0129ec 003838 00   A  0   0  4
      [14] .eh_frame         PROGBITS        0001e224 016224 000004 00   A  0   0  4
      [15] .init_array       INIT_ARRAY      00026228 016228 000004 00  WA  0   0  4
      [16] .fini_array       FINI_ARRAY      0002622c 01622c 000004 00  WA  0   0  4
      [17] .jcr              PROGBITS        00026230 016230 000004 00  WA  0   0  4
      [18] .dynamic          DYNAMIC         00026234 016234 000188 08  WA  4   0  4
      [19] .got              PROGBITS        000263bc 0163bc 0002e0 04  WA  0   0  4
      [20] .data             PROGBITS        0002669c 01669c 00003c 00  WA  0   0  4
      [21] .bss              NOBITS          000266d8 0166d8 0074a0 00  WA  0   0  8
      [22] .comment          PROGBITS        00000000 0166d8 000068 01  MS  0   0  1
      [23] .ARM.attributes   ARM_ATTRIBUTES  00000000 016740 00002f 00      0   0  1
      [24] .debug_aranges    PROGBITS        00000000 01676f 000108 00      0   0  1
      [25] .debug_info       PROGBITS        00000000 016877 0398ba 00      0   0  1
      [26] .debug_abbrev     PROGBITS        00000000 050131 001e7e 00      0   0  1
      [27] .debug_line       PROGBITS        00000000 051faf 005827 00      0   0  1
      [28] .debug_frame      PROGBITS        00000000 0577d8 00162c 00      0   0  4
      [29] .debug_str        PROGBITS        00000000 058e04 01788b 01  MS  0   0  1
      [30] .debug_loc        PROGBITS        00000000 07068f 009e6d 00      0   0  1
      [31] .debug_ranges     PROGBITS        00000000 07a4fc 000cc0 00      0   0  1
      [32] .shstrtab         STRTAB          00000000 07b1bc 000140 00      0   0  1
      [33] .symtab           SYMTAB          00000000 07b874 003760 10     34 548  4
      [34] .strtab           STRTAB          00000000 07efd4 002e81 00      0   0  1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      y (noread), p (processor specific)
    
    
    arm-openwrt-linux-strip  -s  test
    
    
    There are 25 section headers, starting at offset 0x1683c:
    
    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .interp           PROGBITS        000080f4 0000f4 000014 00   A  0   0  1
      [ 2] .hash             HASH            00008108 000108 000658 04   A  3   0  4
      [ 3] .dynsym           DYNSYM          00008760 000760 000cf0 10   A  4   1  4
      [ 4] .dynstr           STRTAB          00009450 001450 00137b 00   A  0   0  1
      [ 5] .gnu.version      VERSYM          0000a7cc 0027cc 00019e 02   A  3   0  2
      [ 6] .gnu.version_r    VERNEED         0000a96c 00296c 000060 00   A  4   3  4
      [ 7] .rel.dyn          REL             0000a9cc 0029cc 000070 08   A  3   0  4
      [ 8] .rel.plt          REL             0000aa3c 002a3c 0005a8 08   A  3  10  4
      [ 9] .init             PROGBITS        0000afe4 002fe4 000010 00  AX  0   0  4
      [10] .plt              PROGBITS        0000aff4 002ff4 000890 04  AX  0   0  4
      [11] .text             PROGBITS        0000b884 003884 00f158 00  AX  0   0  4
      [12] .fini             PROGBITS        0001a9dc 0129dc 000010 00  AX  0   0  4
      [13] .rodata           PROGBITS        0001a9ec 0129ec 003838 00   A  0   0  4
      [14] .eh_frame         PROGBITS        0001e224 016224 000004 00   A  0   0  4
      [15] .init_array       INIT_ARRAY      00026228 016228 000004 00  WA  0   0  4
      [16] .fini_array       FINI_ARRAY      0002622c 01622c 000004 00  WA  0   0  4
      [17] .jcr              PROGBITS        00026230 016230 000004 00  WA  0   0  4
      [18] .dynamic          DYNAMIC         00026234 016234 000188 08  WA  4   0  4
      [19] .got              PROGBITS        000263bc 0163bc 0002e0 04  WA  0   0  4
      [20] .data             PROGBITS        0002669c 01669c 00003c 00  WA  0   0  4
      [21] .bss              NOBITS          000266d8 0166d8 0074a0 00  WA  0   0  8
      [22] .comment          PROGBITS        00000000 0166d8 000068 01  MS  0   0  1
      [23] .ARM.attributes   ARM_ATTRIBUTES  00000000 016740 00002f 00      0   0  1
      [24] .shstrtab         STRTAB          00000000 01676f 0000ca 00      0   0  1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      y (noread), p (processor specific)
    
    //可以发现符号表symtab 消失了
     
    • 同时执行nm xxx 的时候显示 no symbols  说明 nm 是读取的symtab表项
    注意在cp debug.symtab到线上环境时, 需要将debug.symtabl 放在正确的位置 一般都是进程当前路径或者usr/lib/debug+ rottpath
    或者利用gdb的命令设置搜索路径:set debug-file-directory directories
    具体情况strace 就可以看到如下:
    open("/fp/lib/log_plugins/libto_logs.so.debug.symbol", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
    open("/fp/lib/log_plugins/.debug/libto_logs.so.debug.symbol", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
    open("/usr/lib/debug//fp/lib/log_plugins/libto_logs.so.debug.symbol", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
    open("/usr/lib/debug/old_rootfs/fp/lib/log_plugins/libto_logs.so.debug.symbol", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
    write(1, "(no debugging symbols found)...d"..., 37(no debugging symbols found)...done.
    • -fpic:使用-fPIC时,生成的代码时与位置无关的代码。那么在加载动态库时,就不会加载到固定位置,那么每个symbol都可以加载成功。当没有-fPIC时,程序会发现该位置已有对应的symbol,自然就不会二次加载了。(这个对于在线升级动态库有比较大的帮助)
    • gcc参数 -rdynamic 用来通知链接器将所有符号添加到动态符号表中(目的是能够通过使用 dlopen 来实现向后跟踪).表示main函数调用dlopen 打开xxx
    • gcc main.c -ldl -rdynamic -O  test.bin  # gcc -shared -fPIC -nostartfiles -o testlib.so testlib.c
      gcc参数 -fPIC 作用: 当使用.so等类的库时,当遇到多个可执行文件共用这一个库时, 在内存中,这个库就不会被复制多份,让每个可执行文件一对一的使用,而是让多个可执行文件指向一个库文件,达到共用. 宗旨:节省了内存空间,提高了空间利用率
     
  • 相关阅读:
    Robocode教程4——Robocode的游戏物理
    JAVA:获取系统中可用的字体的名字
    Robocode游戏规则
    Robocode教程2——你的第一个robo,取个好名字哦
    Robocode教程1——安装、运行、配置
    第二十四章 异常和错误处理 6异常类与模板的关系 简单
    第二十四章 异常和错误处理 5异常类的虚函数 简单
    第二十三模板 18.4算法类 简单
    解决不能通过'/tmp/mysql.sock'连到服务器 简单
    第二十四章 异常和错误处理 4创建异常类的成员函数 简单
  • 原文地址:https://www.cnblogs.com/codestack/p/12830451.html
Copyright © 2011-2022 走看看