strace命令
strace是Linux上的一个很好用的工具,它可以用来输出程序在运行过程中发生的系统调用以及收到的信号的相关信息,因此在调试和诊断问题时有很大的帮助,特别是在程序没有源码,或是在前期做一些粗略的分析时。strace命令格式如下:
strace [options] command [args]
查看帮助
strace -h
查看版本信息
strace -V
基本使用
举个例子:
[root cprogs2]#strace sleep 300
execve("/bin/sleep", ["sleep", "300"], 0x7ffc2a8576d8 /* 26 vars */) = 0
brk(NULL) = 0x55e6d16ea000
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)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5f124ef000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/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\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f124ed000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f5f11eed000
mprotect(0x7f5f120d4000, 2097152, PROT_NONE) = 0
mmap(0x7f5f122d4000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f5f122d4000
mmap(0x7f5f122da000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5f122da000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f5f124ee540) = 0
mprotect(0x7f5f122d4000, 16384, PROT_READ) = 0
mprotect(0x55e6d13ee000, 4096, PROT_READ) = 0
mprotect(0x7f5f12505000, 4096, PROT_READ) = 0
munmap(0x7f5f124ef000, 86092) = 0
brk(NULL) = 0x55e6d16ea000
brk(0x55e6d170b000) = 0x55e6d170b000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=10281936, ...}) = 0
mmap(NULL, 10281936, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5f1151e000
close(3) = 0
nanosleep({tv_sec=300, tv_nsec=0}, NULL) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
[root cprogs2]#
strace列出了系统调用的参数,等号后面是执行相应系统调用的返回值。
结果输出到文件
strace -o output sleep 10
上面的命令是将sleep 10的执行结果输出到文件output中。
系统调用前添加时间
strace -t ls
执行部分结果:
[root ~]#strace -t ls
17:06:48 execve("/bin/ls", ["ls"], 0x7ffedb93da58 /* 25 vars */) = 0
17:06:48 brk(NULL) = 0x5589cab91000
17:06:48 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
17:06:48 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
17:06:48 openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
17:06:48 fstat(3, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
17:06:48 mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f83fc1fc000
17:06:48 close(3) = 0
17:06:48 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
17:06:48 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
17:06:48 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20b\0\0\0\0\0\0"..., 832) = 832
17:06:48 fstat(3, {st_mode=S_IFREG|0644, st_size=154832, ...}) = 0
17:06:48 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f83fc1fa000
17:06:48 mmap(NULL, 2259152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f83fbdc3000
17:06:48 mprotect(0x7f83fbde8000, 2093056, PROT_NONE) = 0
17:06:48 mmap(0x7f83fbfe7000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24000) = 0x7f83fbfe7000
17:06:48 mmap(0x7f83fbfe9000, 6352, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f83fbfe9000
17:06:48 close(3) = 0
只关注某一系统调用
strace -e xxx ls
其中xxx代表想要关注的系统调用。
例如我想查看系统调用close的执行情况,可以使用如下命令:
strace -te close ls
[root ~]#strace -te close ls
17:08:34 close(3) = 0
17:08:34 close(3) = 0
17:08:34 close(3) = 0
17:08:34 close(3) = 0
17:08:34 close(3) = 0
17:08:34 close(3) = 0
17:08:34 close(3) = 0
17:08:34 close(3) = 0
17:08:34 close(3) = 0
C-Programming-A-Modern-Approach C-Thread-Pool output pcstat sleep workspace
17:08:34 close(1) = 0
17:08:34 close(2) = 0
17:08:34 +++ exited with 0 +++
显示和文件描述符关联的文件路径
strace -y ls
[root ~]#strace -y ls
execve("/bin/ls", ["ls"], 0x7ffd916f8f88 /* 25 vars */) = 0
brk(NULL) = 0x5562553e8000
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)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache>
fstat(3</etc/ld.so.cache>, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3</etc/ld.so.cache>, 0) = 0x7f60ff6f3000
close(3</etc/ld.so.cache>) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3</lib/x86_64-linux-gnu/libselinux.so.1>
read(3</lib/x86_64-linux-gnu/libselinux.so.1>, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20b\0\0\0\0\0\0"..., 832) = 832
fstat(3</lib/x86_64-linux-gnu/libselinux.so.1>, {st_mode=S_IFREG|0644, st_size=154832, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f60ff6f1000
mmap(NULL, 2259152, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3</lib/x86_64-linux-gnu/libselinux.so.1>, 0) = 0x7f60ff2ba000
mprotect(0x7f60ff2df000, 2093056, PROT_NONE) = 0
mmap(0x7f60ff4de000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</lib/x86_64-linux-gnu/libselinux.so.1>, 0x24000) = 0x7f60ff4de000
查看运行进程
strace -p 进程号
这是strace命令我在工作中用的最多的地方,下面结合一个实际例子来看。
C代码
//dead_loop.c
#include <unistd.h>
int main(void)
{
while (1)
{
sleep(1);
}
return 0;
}
执行过程:
[root ~]#gcc -g -o dead_loop dead_loop.c
[root ~]#./dead_loop &
[1] 20646
[root ~]#strace -p 20646
strace: Process 20646 attached
restart_syscall(<... resuming interrupted nanosleep ...>) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffd2d6653e0) = 0
我们可以看到,这是一种在没有在明显日志打印且不影响程序运行的情况下查看进程执行情况的简单方法。
通常用于定位进程占用cpu高,分析该进程为何cpu使用率高,结合strace输出和具体业务代码可以优化cpu的使用。
跟踪子进程
C代码
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int pid = fork();
if (pid < 0)
{
return 1;
}
else if(pid ==0){
while (1)
{
sleep(1);
}
}
else
{
while(1)
{
sleep(5);
}
}
return 0;
}
上面的代码,我们在子进程里sleep 1秒钟,在父进程里sleep 5秒钟。默认情况下strace不会跟踪子进程(fork vfork clone).
[root ~]#gcc -g -o fork fork.c
[root ~]#
[root ~]#
[root ~]#strace ./fork
execve("./fork", ["./fork"], 0x7ffd1ab1eee0 /* 25 vars */) = 0
brk(NULL) = 0x560b46515000
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)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f0bda925000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/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\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0bda923000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0bda323000
mprotect(0x7f0bda50a000, 2097152, PROT_NONE) = 0
mmap(0x7f0bda70a000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f0bda70a000
mmap(0x7f0bda710000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0bda710000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f0bda9244c0) = 0
mprotect(0x7f0bda70a000, 16384, PROT_READ) = 0
mprotect(0x560b449e4000, 4096, PROT_READ) = 0
mprotect(0x7f0bda93b000, 4096, PROT_READ) = 0
munmap(0x7f0bda925000, 86092) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f0bda924790) = 21870
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffd06296c40) = 0
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffd06296c40) = 0
nanosleep({tv_sec=5, tv_nsec=0}, 0x7ffd06296c40) = 0
nanosleep({tv_sec=5, tv_nsec=0}, ^Cstrace: Process 21869 detached
我们可以看到最后函数部分只有nanosleep tv_sec=5,表示strace系统调用只跟踪了父进程。
[root ~]#strace -f ./fork
execve("./fork", ["./fork"], 0x7ffe56828e28 /* 25 vars */) = 0
brk(NULL) = 0x55a1754b3000
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)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd46ee53000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/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\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd46ee51000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd46e851000
mprotect(0x7fd46ea38000, 2097152, PROT_NONE) = 0
mmap(0x7fd46ec38000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fd46ec38000
mmap(0x7fd46ec3e000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd46ec3e000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fd46ee524c0) = 0
mprotect(0x7fd46ec38000, 16384, PROT_READ) = 0
mprotect(0x55a173d35000, 4096, PROT_READ) = 0
mprotect(0x7fd46ee69000, 4096, PROT_READ) = 0
munmap(0x7fd46ee53000, 86092) = 0
clone(strace: Process 22460 attached
child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd46ee52790) = 22460
[pid 22459] nanosleep({tv_sec=5, tv_nsec=0}, <unfinished ...>
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, <unfinished ...>
[pid 22459] <... nanosleep resumed> 0x7fff1214b620) = 0
[pid 22459] nanosleep({tv_sec=5, tv_nsec=0}, <unfinished ...>
[pid 22460] <... nanosleep resumed> 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, 0x7fff1214b620) = 0
[pid 22460] nanosleep({tv_sec=1, tv_nsec=0}, ^C <unfinished ...>
[pid 22459] <... nanosleep resumed> {tv_sec=0, tv_nsec=84752277}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
strace: Process 22459 detached
strace: Process 22460 detached
添加-f参数后我们可以看到nanosleep 1秒和5秒都跟跟踪,最后我们按下control + c时也可以看到有22459 和22460两个进程detached.
-b syscall
-b syscall If specified syscall is reached, detach from traced process. Currently, only execve syscall is suported. This option is useful if you want to trace multi-threaded process and therefore require -f, but don't want to trace its (potentially very complex) children.
-b选项目前支持的syscall只有execve。
myecho.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int j;
for (j = 0; j < argc; j++)
printf("argv[%d]: %s\n", j, argv[j]);
exit(EXIT_SUCCESS);
}
execve.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char *newargv[] = { NULL, "hello", "world", NULL };
char *newenviron[] = { NULL };
if (argc != 2) {
fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
execve(argv[1], newargv, newenviron);
perror("execve"); /* execve() returns only on error */
exit(EXIT_FAILURE);
}
#gcc myecho.c -o myecho
# gcc execve.c -o execve
如果不加-b选项,执行结果输出:
[root strace]#strace ./execve myecho
execve("./execve", ["./execve", "myecho"], 0x7ffd26bb0c78 /* 26 vars */) = 0
brk(NULL) = 0x557bbbe21000
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)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6f34876000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/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\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6f34874000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6f34274000
mprotect(0x7f6f3445b000, 2097152, PROT_NONE) = 0
mmap(0x7f6f3465b000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f6f3465b000
mmap(0x7f6f34661000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6f34661000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f6f348754c0) = 0
mprotect(0x7f6f3465b000, 16384, PROT_READ) = 0
mprotect(0x557bba59d000, 4096, PROT_READ) = 0
mprotect(0x7f6f3488c000, 4096, PROT_READ) = 0
munmap(0x7f6f34876000, 86092) = 0
execve("myecho", ["myecho", "hello", "world"], 0x7ffe770f46a8 /* 0 vars */) = 0
brk(NULL) = 0x55d340320000
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)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f0f970a1000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/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\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0f9709f000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f0f96a9f000
mprotect(0x7f0f96c86000, 2097152, PROT_NONE) = 0
mmap(0x7f0f96e86000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f0f96e86000
mmap(0x7f0f96e8c000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f0f96e8c000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f0f970a04c0) = 0
mprotect(0x7f0f96e86000, 16384, PROT_READ) = 0
mprotect(0x55d33f4aa000, 4096, PROT_READ) = 0
mprotect(0x7f0f970b7000, 4096, PROT_READ) = 0
munmap(0x7f0f970a1000, 86092) = 0
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0
brk(NULL) = 0x55d340320000
brk(0x55d340341000) = 0x55d340341000
write(1, "argv[0]: myecho\n", 16argv[0]: myecho
) = 16
write(1, "argv[1]: hello\n", 15argv[1]: hello
) = 15
write(1, "argv[2]: world\n", 15argv[2]: world
) = 15
exit_group(0) = ?
+++ exited with 0 +++
[root strace]#
添加-b选项,遇到execve函数后,strace不会继续分析其执行,程序继续执行打印输出:
[root strace]#strace -b execve ./execve myecho
execve("./execve", ["./execve", "myecho"], 0x7fff5b22b808 /* 26 vars */) = 0
brk(NULL) = 0x558f31f33000
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)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=86092, ...}) = 0
mmap(NULL, 86092, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fad95f61000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/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\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fad95f5f000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fad9595f000
mprotect(0x7fad95b46000, 2097152, PROT_NONE) = 0
mmap(0x7fad95d46000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fad95d46000
mmap(0x7fad95d4c000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fad95d4c000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7fad95f604c0) = 0
mprotect(0x7fad95d46000, 16384, PROT_READ) = 0
mprotect(0x558f2ff76000, 4096, PROT_READ) = 0
mprotect(0x7fad95f77000, 4096, PROT_READ) = 0
munmap(0x7fad95f61000, 86092) = 0
execve("myecho", ["myecho", "hello", "world"], 0x7ffd689a07c8 /* 0 vars */strace: Process 17779 detached
<detached ...>
argv[0]: myecho
argv[1]: hello
argv[2]: world
[root strace]#