常用调试命令极简指南(工作中能应对百分之八十的问题...)

一、nm 查看未定义符号

  • 作用: 列出目标文件中的符号即其在内存中的位置(目标文件即编译器编译的文件:动态库、可执行程序、.o文件等)

  • nm输出 的常用符号说明:
    b/B: 该符号在bss段,如未初始化的全局变量或0初始化的全局变量;
    d/D: 该符号在初始化数据段,如已初始化的全局变量;
    t/T: 改符号在代码段,一般是函数定义;
    U: 该符号未定义, 一般直接使用nm -u xxx,即可列出未定义符号

  • 举例:

int global_var;
int global_var_zero = 0;
int global_var_init = 26;
const int global_var_const = 0;static int static_var;
static int static_var_init = 25;extern int extern_var;
extern int extern_function(int);static int static_function(int x, int y)
{int local_automatic_var;local_automatic_var = x + y;return local_automatic_var;
}int global_function(int p)
{static int local_static_var;static int local_static_var_init=5;local_static_var = static_function(local_static_var_init, p);  return local_static_var;
}int main(int argc, char** argv)
{static_var = 1;    global_var = global_function(2);extern_var = extern_function(3);return 0;
}

编译指令:
只编译,不链接
[或者编译成动态库也可以,动态库可以有未定义的符号,在动态库被链接时能找到符号定义即可]
g++ -c test.cpp -o test.o
nm test.o 输出如下:

                 U extern_varU _GLOBAL_OFFSET_TABLE_
0000000000000000 B global_var
0000000000000000 D global_var_init
0000000000000004 B global_var_zero
0000000000000045 T mainU _Z15extern_functioni
000000000000001a T _Z15global_functioni
0000000000000008 b _ZL10static_var
0000000000000000 t _ZL15static_functionii
0000000000000004 d _ZL15static_var_init
0000000000000000 r _ZL16global_var_const
000000000000000c b _ZZ15global_functioniE16local_static_var
0000000000000008 d _ZZ15global_functioniE21local_static_var_init

二、ldd 查询可执行程序、动态库 依赖关系

很简单,很常用
在这里插入图片描述

三、readelf 分析ELF(Executable and Linking Format)文件必备

参考: 官网说明
不是很常用,目前开发中用到以下几个选项:

  • readelf -h testlib -h 显示ELF Header信息,可以看到文件类型,file 命令也可以
ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              DYN (Shared object file)                Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x610Start of program headers:          64 (bytes into file)Start of section headers:          6536 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         7Size of section headers:           64 (bytes)Number of section headers:         26Section header string table index: 25
  • readelf -p .comment testlib 查看编译器
String dump of section '.comment':[     0]  GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

四、objdump 查看目标文件信息,反汇编

参考: 官网说明

  • 查看文件信息
root@923a3cd440e0:/workspace# objdump -a testlib
testlib:     file format elf64-x86-64
  • 反汇编
    objdump -S testlib

五、gdb 调试,很香

参考: 说明

如果遇到程序莫名其妙的挂了,那就gdb吧,绝对有帮助,
程序crash之后,bt 查看堆栈调用信息,基本就能确定问题的根源了。

六、动态库的搜索顺序

动态库是有搜索顺序的,动态库的搜索路径搜索的先后顺序是:
1.编译目标代码时指定的动态库搜索路径, 所谓的rpath
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部