Linux | Strace使用

article/2025/9/19 18:10:14

文章目录

  • 1、strace的基本介绍
  • 2、strace的使用实例
    • 2.1、直接运行结果
    • 2.2、strace追踪系统调用(strace ./test)
    • 2.3、strace跟踪信号传递
    • 2.4、系统调用统计
      • 使用`-c`参数,它会将进程的所有系统调用做一个统计分析展示出来
      • `-o`选项重定向输出
      • `-T`选项对系统调用进行计时
      • 系统调用的时间
      • 截断输出
      • 追踪现有的进程
    • 2.5、用strace调试程序

Linux下,进程不能直接访问硬件设备。当进程需要访问硬件设备时(读取磁盘文件、接收网络数据等),则必须由用户态切换为内核态,然后通过系统调用来访问硬件设备。

strace是跟踪进程执行时的系统调用和所接收的信号(即它跟踪到一个进程产生的系统调用,包括参数、返回值、执行消耗的时间)。

strace最简单的用法是执行一个指定的命令(过程中,starce会记录和解析命令进程的所有系统调用及这个进程的所有的信号值),在指定命令结束后立即退出。

1、strace的基本介绍

参数:-c 统计每一系统调用的所执行的时间,次数和出错的次数等.-d 输出strace关于标准错误的调试信息.-f 跟踪由fork调用所产生的子进程.-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.-h 输出简要的帮助信息.-i 输出系统调用的入口指针.-q 禁止输出关于脱离的消息.-r 打印出相对时间关于,,每一个系统调用.-t 在输出中的每一行前加上时间信息.-tt 在输出中的每一行前加上时间信息,微秒级.-ttt 微秒级输出.-T 显示每一调用所耗的时间.-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.-V 输出strace的版本信息.-x 以十六进制形式输出非标准字符串-xx 所有字符串以十六进制形式输出.-a column 设置返回值的输出位置.默认 为40.-e expr 指定一个表达式,用来控制如何跟踪.格式:[qualifier=][!]value1[,value2]...qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如:-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open 表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none. 注意有些shell使用!来执行历史记录里的命令,所以要使用\\.-e trace=set 只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.-e trace=file 只跟踪有关文件操作的系统调用.-e trace=process 只跟踪有关进程控制的系统调用.-e trace=network 跟踪与网络有关的所有系统调用.-e strace=signal 跟踪所有与系统信号有关的系统调用.-e trace=ipc 跟踪所有与进程通讯有关的系统调用.-e abbrev=set 设定strace输出的系统调用的结果集.-v 等于abbrev=none.默认为abbrev=all.-e raw=set 将指定的系统调用的参数以十六进制显示.-e signal=set 指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.-e read=set 输出从指定文件中读出 的数据.例如: -e read=3,5 -e write=set 输出写入到指定文件中的数据.-o filename 将strace的输出写入文件filename-p pid 跟踪指定的进程pid.-s strsize 指定输出的字符串的最大长度.默认为32.文件名一直全部输出.-u username 以username的UID和GID执行被跟踪的命令

2、strace的使用实例

对于如下test.cpp程序

#include<iostream>
using namespace std;
int main(){int a;cin>>a;cout<<a<<endl;return 0;
}

使用g++ -o test test.cpp进行编译。

2.1、直接运行结果

在这里插入图片描述

2.2、strace追踪系统调用(strace ./test)

[root@init1 strace]# strace ./test
execve("./test", ["./test"], [/* 25 vars */]) = 0
brk(NULL)                               = 0x1ec7000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd40f43f000
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=29479, ...}) = 0
mmap(NULL, 29479, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd40f437000
close(3)                                = 0
open("/lib64/libstdc++.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 \262\5\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=991616, ...}) = 0
mmap(NULL, 3171168, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd40ef18000
mprotect(0x7fd40f001000, 2093056, PROT_NONE) = 0
mmap(0x7fd40f200000, 40960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe8000) = 0x7fd40f200000
mmap(0x7fd40f20a000, 82784, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd40f20a000
close(3)                                = 0
open("/lib64/libm.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\0pS\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1139680, ...}) = 0
mmap(NULL, 3150136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd40ec16000
mprotect(0x7fd40ed17000, 2093056, PROT_NONE) = 0
mmap(0x7fd40ef16000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x100000) = 0x7fd40ef16000
close(3)                                = 0
open("/lib64/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220*\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=88776, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd40f436000
mmap(NULL, 2184192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd40ea00000
mprotect(0x7fd40ea15000, 2093056, PROT_NONE) = 0
mmap(0x7fd40ec14000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14000) = 0x7fd40ec14000
close(3)                                = 0
open("/lib64/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\0P%\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2173512, ...}) = 0
mmap(NULL, 3981792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd40e633000
mprotect(0x7fd40e7f6000, 2093056, PROT_NONE) = 0
mmap(0x7fd40e9f5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c2000) = 0x7fd40e9f5000
mmap(0x7fd40e9fb000, 16864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd40e9fb000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd40f435000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd40f433000
arch_prctl(ARCH_SET_FS, 0x7fd40f433740) = 0
mprotect(0x7fd40e9f5000, 16384, PROT_READ) = 0
mprotect(0x7fd40ec14000, 4096, PROT_READ) = 0
mprotect(0x7fd40ef16000, 4096, PROT_READ) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd40f432000
mprotect(0x7fd40f200000, 32768, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7fd40f440000, 4096, PROT_READ) = 0
munmap(0x7fd40f437000, 29479)           = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd40f43e000
read(0, 123456
"123456\n", 1024)               = 7
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd40f43d000
write(1, "123456\n", 7123456
)                 = 7
exit_group(0)                           = ?
+++ exited with 0 +++

注:以上每一行都是一条系统调用,等号左边是系统调用的函数名和参数,右边是该调用的返回值

strace显示这些调用的参数并返回符号形式的值。

strace从内核接收信息,而且不需要以任何特殊的方式来构建内核

2.3、strace跟踪信号传递

首先,strace ./test,等到等待输入的那一步时,不输入任何东西,然后打开另外一个窗口,输入命令:killall test

我们观察第一次打开的strace窗口中,此时,我们看见程序退出了,结果如下(仅截取末尾几行):
在这里插入图片描述

2.4、系统调用统计

使用-c参数,它会将进程的所有系统调用做一个统计分析展示出来

这里清楚的告诉我们,在这一过程中调用了哪些系统函数,调用了多少次,消耗了多少时间等信息,这对我们分析一个程序是很有帮助的。实例如下:
在这里插入图片描述

-o选项重定向输出

-o 将strace 的结果输出到文件中若不指定 -o 参数的话,默认的输出设备是STDERR,也就是说,使用 -o filename2>filename 的结果是一样的。执行strace -c -o file ./test结果如下:
在这里插入图片描述

-T选项对系统调用进行计时

-T 将每个系统调用所花费的时间打印出来。每个调用的花销体现在调用行最右边的尖括号里边(下面只是调用的一部分)

strace -T ./test执行后结果如下(截取前几行):
在这里插入图片描述

系统调用的时间

-t/-tt/-ttt-t 精确到秒-tt  精确到微秒-ttt  精确到微秒,而且时间表示为unix时间戳。

调用strace -t ./test 结果如下(截取前几行):
在这里插入图片描述

截断输出

-s 指定trace结果的每一行输出的字符串长度

现指定-s 5,而在read时,我们输入一个超过5个字符的字符串

追踪现有的进程

strace -p pid

2.5、用strace调试程序

对于如下程序:

#include<iostream>
#include <fstream>
#include <stdlib.h>using namespace std;int main() {char buffer[256];ifstream in("input.txt");if(!in.is_open()) {cout<<"error open file"<<endl;exit(1);}while(!in.eof()) {in.getline(buffer,100);cout<<buffer<<endl;}return 0;
}

如果不创建input.txt文件夹的话直接执行肯定会报错,如下:
在这里插入图片描述
但是仅仅看这个提示我并不知道究竟是哪个系统调用出错,或者说我想更精确的定位出错的位置要怎么办?

执行strace ./stracetest后就能够直接定位具体的错误位置了:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/CvSd5na3.shtml

相关文章

linux下strace的使用

strace是一款用于跟踪Linux系统调用和信号的工具&#xff0c;可以帮助开发者排除程序运行时的问题。 具体来说&#xff0c;strace可以跟踪一个程序执行时所涉及到的系统调用&#xff0c;包括读写文件、网络通信、进程管理、内存管理等操作&#xff0c;通过分析程序运行过程中发…

linux strace命令--跟踪系统调用

简介 strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界&#xff0c;进程不能直接访问硬件设备&#xff0c;当进程需要访问硬件设备(比如读取磁盘文件&#xff0c;接收网络数据等等)时&#xff0c;必须由用户态模式切换至内核态模式&#xff0c;通 过系统调用…

Linux常用命令——strace命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) strace 跟踪系统调用和信号 补充说明 strace命令是一个集诊断、调试、统计与一体的工具&#xff0c;我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析&#xff0c;以达到解决问题或者…

【转】strace命令详解

Article1&#xff1a; strace是什么&#xff1f; 按照strace官网的描述, strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互&#xff0c;比如系统调用、信号传递、进程状态变更等。 strace底层使用内核的ptrace特性来实现其…

强大的strace命令用法详解

strace是什么&#xff1f; 按照strace官网的描述, strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互&#xff0c;比如系统调用、信号传递、进程状态变更等。 strace底层使用内核的ptrace特性来实现其功能。 在运维的日常工作…

Linux命令之strace命令

一、命令简介 strace是一个有用的诊断、指导和调试工具。系统管理员、诊断专家和故障解决人员将发现&#xff0c;对于解决源代码不易获得的程序的问题&#xff0c;这是非常宝贵的&#xff0c;因为它们不需要重新编译以跟踪它们。学生、黑客和过分好奇的人会发现&#xff0c;通过…

strace命令使用分析

strace命令介绍与用法 1.1 strace概述 在操作系统中&#xff0c;进程分为用户态进程和内核态进程&#xff0c;应用程序运行在用户态&#xff0c;内核态负责对资源包括网络&#xff0c;磁盘&#xff0c;内存等管理&#xff0c;用户态进程要访问这些资源时&#xff0c;需要通过…

【已解决】安装Ubuntu时怎样分区--利用EasyBCD在win7下进行ubuntu安装(双系统)时遇到报错:没有根文件系统,请回到分区菜单以修正此错误

由于我们离不开Windows操作&#xff0c;并且因为不熟悉而不习惯ubuntu的操作方式&#xff0c;固采用Win7和Ubuntu双系统方式比较合理。在Win7基础上安装Ubuntu&#xff0c;Ubuntu会自动建立一个启动菜单&#xff0c;让我们在开机时自行选择启动Win7还是Ubuntu。 1、在win7上安…

根文件系统挂载过程—基于linux3.10

本文基于linux3.10某一嵌入式系统&#xff0c;该文件系统的配置选项设置如下&#xff1a; 图1.1 根文件系统配置选项设置 两行配置如下&#xff1a; [*] Initial RAMfilesystem and RAM disk (initramfs/initrd) support (usr/rootfs.cpio.gz)Initramfs source file(s) 这两…

JFFS2根文件系统制作

一.根文件系统简介 根文件系统首先是内核启动时所mount的第一个文件系统&#xff0c;内核代码映像文件保存在根文件系统中&#xff0c;系统引导启动程序会在根文件系统挂载之后从中把一些初始化脚本&#xff08;如inittab、rcS&#xff09;和服务加载到内存中去运行。 文件系统…

ARM Linux启动流程-根文件系统的加载

前言 在Kernel启动的初始阶段&#xff0c;首先去创建虚拟的根文件系统(rootfs)&#xff0c;接下来再去调用do_mount来加载真正的文件系统&#xff0c;并将根文件系统切换到真正的文件系统&#xff0c;也即真实的文件系统。   接下来结核内核代码(内核版本&#xff1a;linux-…

怎么使用 Buildroot 构建根文件系统

1. Buildroot 简介 制作根文件系统有归多种方法&#xff1a; ① 使用Busybox手工制作 Busybox本身包含了很了Linux命令&#xff0c;但是要编译其他程序的话需要手工下载、编译&#xff0c;如果它需要某些依赖库&#xff0c;你还需要手工下载、编译这些依赖库。 如果想做一个极…

一文讲解Linux内核中根文件系统挂载流程

根文件系统的概念 根文件系统是控制权从linux内核转移到用户空间的一个桥梁。linux内核就类似于一个黑匣子&#xff0c;只向用户提供各种功能的接口&#xff0c;但是功能的具体实现不可见&#xff0c;用户程序通过对这些功能接口的不同整合实现不同的功能需求。以用户的角度来…

【linux kernel】挂载根文件系统之rootfs

挂载根文件系统之rootfs 文章目录 挂载根文件系统之rootfs一、开篇二、rootfs根文件系统&#xff08;2-1&#xff09;初始化rootfs&#xff08;2-2&#xff09;挂载rootfs文件系统&#xff08;2-3&#xff09;创建简单的rootfs根文件系统目录和文件&#xff08;2-4&#xff09;…

2021年Linux技术总结(三):根文件系统(rootfs)

# 一、根文件系统简介 Linux系统三大块&#xff1a;U-boot、kernel以及最后这个rootfs&#xff0c;跟文件系统。在kernel中&#xff0c;启动流程的最后会调用 prepare_namespace 函数&#xff0c;挂载根文件系统&#xff0c;这里就是挂载的本篇要说的。 根文件系统保存了内核代…

详解制作根文件系统

目录 前言 具体步骤 一.编译&#xff0f;安装busybox&#xff0c;生成/bin、/sbin、/usr/bin、/usr/sbin目录 二.利用交叉编译工具链&#xff0c;构建/lib目录 三.手工构建/etc目录 四.手工构建最简化的/dev目录 五.创建其它空目录 六.配置系统自动生成/proc目录和构建…

根文件系统理解

文件系统概念 文件系统是一些代码&#xff0c;是一套软件&#xff0c;这套软件的功能就是对存储设备的扇区进行管理&#xff0c;将这些扇区的访问变成了对目录和文件名的访问。我们在上层按照特定的目录和文件名去访问一个文件时&#xff0c;文件系统会将这个目录文件名转换成对…

linux之根文件系统

前言 1、板卡上电后首先由UBOOT启动初始化板卡&#xff0c;将Linux内核移到内存中运行 2、由linux内核自行做了初始化等操作&#xff0c;挂在了第一个应用程序上&#xff08;根文件系统/linuxrc&#xff09; 3、根文件系统会提供磁盘管理服务&#xff0c;glibc设备节点&…

Linux:根文件系统构建

文章目录 一、编译 BusyBox 构建根文件系统1.创建BusyBox路径并解压2.修改顶层Makefile3.修改 busybox 源码4.配置busybox5.编译busybox6.向 rootfs 的“/lib”目录添加库文件7.向 rootfs 的“usr/lib”目录添加库文件创建其他文件夹 二、NFS挂载根文件系统1.bootargs 环境变量…

制作嵌入式Linux根文件系统

文章目录 1. 根文件系统布局2. 使用BusyBox生成二进制工具2-1. 获取BusyBox源码2-2. 配置BusyBox2-2-1. 选择编译静态库2-2-2. 选择交叉编译工具链2-2-3. 选择安装目录2-2-4. 编译安装 3. 构建根文件系统3-1. 完善目录结构3-2. 添加C运行库文件3-3. 添加初始化配置脚本3-3-1. 修…