调试工具

调试工具

本文介绍一些常见的调试工具,ltrace、strace、ftrace 属于不同层级的调试工具。

  • ltrace 主要用于业务层面的调试
  • strace 主要用于系统调用、C 库层面的调试
  • ftrace 主要用于内核级别的调试

如下 demo 均为一个 hello world 程序。

1
2
3
4
5
6
#include <stdio.h>

int main() {
printf("hello world\n");
return 0;
}

一、ltrace

使用 ltrace 是一个函数库调用跟踪器,主要用于跟踪程序的函数库调用信息。

1
2
3
4
5
6
7
# ltrace -f ./main

[pid 1159589] __libc_start_main(0xaaaae7a33764, 1, 0xfffff21958d8, 0xaaaae7a33788 <unfinished ...>
[pid 1159589] puts("hello world"hello world
) = 12
[pid 1159589] __cxa_finalize(0xaaaae7a44008, 0xaaaae7a33718, 0x10d88, 0xffff94637a78) = 1
[pid 1159589] +++ exited (status 0) +++

二、strace

主要是跟踪系统调用和信号。更加细粒度。

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
27
28
29
# strace -f ./main

execve("./main", ["./main"], 0xfffffe8074c8 /* 28 vars */) = 0
brk(NULL) = 0xaaab008cb000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=28945, ...}) = 0
mmap(NULL, 28945, PROT_READ, MAP_PRIVATE, 3, 0) = 0xffffb4453000
close(3) = 0
openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0`\17\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1450832, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffffb4451000
mmap(NULL, 1519552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xffffb42b9000
mprotect(0xffffb4414000, 61440, PROT_NONE) = 0
mmap(0xffffb4423000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15a000) = 0xffffb4423000
mmap(0xffffb4429000, 12224, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffffb4429000
close(3) = 0
mprotect(0xffffb4423000, 16384, PROT_READ) = 0
mprotect(0xaaaae7e07000, 4096, PROT_READ) = 0
mprotect(0xffffb445d000, 4096, PROT_READ) = 0
munmap(0xffffb4453000, 28945) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x2), ...}) = 0
brk(NULL) = 0xaaab008cb000
brk(0xaaab008ec000) = 0xaaab008ec000
write(1, "hello world\n", 12hello world
) = 12
exit_group(0) = ?
+++ exited with 0 +++

如上的 hello world 程序,进行了 ELF 文件的载入流程。最后才执行了 write 输出“hello world”

三、ftrace

Ftrace 是一个内部跟踪器,帮助系统的开发人员和设计人员找到内核内部发生的事情。 它可用于调试或分析发生在用户空间之外的延迟和性能问题。Ftrace最开始是一个函数跟踪器,主要用于记录内核函数运行轨迹;随着功能的逐渐增加,演变成一个跟踪框架,一个包含多种跟踪实用程序的框架(比如:有延迟跟踪来检查中断禁用和启用之间发生的情况,以及抢占以及从任务被唤醒到任务实际调度的时间。)。

https://blog.csdn.net/weixin_45030965/article/details/125738911#:~:text=Ftrace%20%E6%98%AFLinux%20%E5%AE%98%E6%96%B9%E6%8F%90%E4%BE%9B,%E5%86%85%E6%A0%B8%E5%86%85%E9%83%A8%E5%8F%91%E7%94%9F%E7%9A%84%E4%BA%8B%E6%83%85%E3%80%82