1、使用介绍
一般来说,Ubuntu等系统里面都已经装了starce命令,可以直接加-h
选项查看更多使用方法,不过一般都是strace [-o file] <被跟踪的程序>
:strace作为父进程,“被跟踪的程序”作为子进程,子进程涉及的系统调用会在系统的异常处理阶段被父进程记录下来,我们可以使用它来定位一些简单的问题。
以最简单的hello world程序为例:
#include <stdio.h>
int main()
{
printf("Hello, world!\n");
return 0;
}
编译之后运行并且跟踪:
book@book-VirtualBox:~/strace$ strace -o log.txt ./hello
Hello, world!
book@book-VirtualBox:~/strace$ cat log.txt
execve("./hello", ["./hello"], [/* 31 vars */]) = 0
brk(NULL) = 0x10a6000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {
st_mode=S_IFREG|0644, st_size=89497, ...}) = 0
mmap(NULL, 89497, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f335224c000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-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>\0\1\0\0\0`\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {
st_mode=S_IFREG|0755, st_size=1868984, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f335224b000
mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f3351c73000
mprotect(0x7f3351e33000, 2097152, PROT_NONE) = 0
mmap(0x7f3352033000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7f3352033000
mmap(0x7f3352039000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f3352039000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f335224a000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3352249000
arch_prctl(ARCH_SET_FS, 0x7f335224a700) = 0
mprotect(0x7f3352033000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7f3352262000, 4096, PROT_READ) = 0
munmap(0x7f335224c000, 89497) = 0
fstat(1, {
st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
brk(NULL) = 0x10a6000
brk(0x10c7000) = 0x10c7000
write(1, "Hello, world!\n", 14) = 14
exit_group(0) = ?
+++ exited with 0 +++
可以看到,刚开始就执行execve执行子进程,后续子进程所涉及的系统调用也通通被记录起来,这种方法在追踪segmentation fault段错误等一些问题尤其方便。
2、交叉编译
Ubuntu上面默认自带strace程序,但ARM板上不一定有,那就要交叉编译得到strace可执行文件放到板子上运行,strace源码下载地址:https://strace.io/files/
tar xJvf strace-4.9.tar.xz
cd strace-4.9/
./configure --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc
make # 编译生成可执行程序strace