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

文章介绍了Linux下用于分析和调试的几个关键工具的使用。nm用于查看目标文件中的符号及其位置,特别是未定义的符号;ldd用来检查可执行文件或动态库的依赖关系;readelf提供了查看ELF文件头信息的功能;objdump用于查看目标文件信息和反汇编;gdb是强大的调试工具,尤其在程序崩溃时能提供堆栈调用信息,帮助定位问题。此外,还提到了动态库的搜索顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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_var
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 B global_var
0000000000000000 D global_var_init
0000000000000004 B global_var_zero
0000000000000045 T main
                 U _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 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)                
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x610
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6536 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         7
  Size of section headers:           64 (bytes)
  Number of section headers:         26
  Section 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白龙呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值