系统调用追踪工具strace

简介:

当我们想知道某个进程为什么突然卡了,或者是某个工具到底是如何实现的时候。strace就派上了用场。它能将程序的调用信息打印出来。

strace原理:

它的实现基础是ptrace系统调用。ptrace系统调用提供了一种方法来跟踪和控制进程的执行,它可以读取和修改进程地址空间中的内容,包括寄存器的值。ptrace主要用于实现断点调试和跟踪系统调用。

ptrace系统调用

1 #include <sys/ptrace.h>
2 int ptrace(int request, int pid, int addr, int data);

Ptrace 提供了一种父进程可以控制子进程运行,并可以检查和改变它的核心image。它主要用于实现断点调试。

一个被跟踪的进程运行中,在执行系统调用之前,内核会先检查当前进程是否处于被“跟踪”(traced)的状态。如果是的话,内核暂停当前进程并将控制权交给跟踪进程,使跟踪进程得以察看或者修改被跟踪进程的寄存器

在一个进程被跟踪之后,跟踪者进程会在某种意义上充当被跟踪进程的父进程(如使用ps命令就可以看到他们的父子关系),而子进程真正的父进程被保存在其task_struct结构的real_parent成员中。

当子进程产生系统调用时,就会被暂停,父进程会在每次调用wait()时得到子进程停止运行的通知,这时父进程就可以检测和修改子进程了,随后父进程可以让子进程继续运行。当父进程不想跟踪了,可以通过设置PTRACE_KILL标记来终止子进程的运行。也可以通过设置PTRACE_DETACH标记让子进程解除被跟踪,继续正常运行。
函数参数:

  1. request:用于选择一个操作。
  2. pid:目标进程即被跟踪进程的pid。
  3. addr用于修改和拷贝被跟踪进程的进程地址空间的数据。
  4. data功能同addr。

父进程跟踪一个进程的方式有两种:

  1. 调用fork(),然后子进程打上PTRACE_TRACEME标记,并执行exec。
  2. 父进程可以给自己打上PTRACE_ATTACH标记来跟踪一个已有进程。

所以我们看strace有两种用法,一个是strace直接加要运行的程序,一个是用-p指定一个正在运行的进程。

一个进程被跟踪后,他只要接收到一个信号(即使这个信号被设置为忽略)就会停止运行(SIGKILL除外),然后父进程会在每次调用wait()时得到子进程停止运行的通知,这时父进程就可以检测和修改子进程了,随后父进程可以让子进程继续运行。

当父进程不想跟踪了,可以通过设置PTRACE_KILL标记来终止子进程的运行。也可以通过设置PTRACE_DETACH标记让子进程解除被跟踪,继续正常运行。

strace用法:

最简单的用法其实就是trace后面直接跟着要执行的命令。比如:

1 strace ls -l

就能追踪到它的系统调用。

1 execve("/bin/ls", ["ls""-l"], [/* 22 vars */]) = 0
2 brk(0)                                  = 0x2073000
3 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fee98686000
4 access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
5 open("/etc/ld.so.cache", O_RDONLY)      = 3
6 .........

命令参数:

  • -p pid :绑定到一个由pid对应的正在运行的进程。此参数常用来调试后台进程。
  • -e 函数名:只追踪定义函数名。
  • -f :除了跟踪当前进程外,还跟踪其子进程。
  • -o file :将输出信息写到文件file中,而不是显示到标准错误输出(stderr)。

在linux中,很多性能查看命令都是通过读取/proc中的文件实现的。所以我们如果想学习它们的实现,就可以使用strace追踪,用-e筛选出open函数,就知道它读取了什么文件。比如mount命令。

01 strace -eopen mount
02 open("/etc/ld.so.cache", O_RDONLY)      = 3
03 open("/lib64/libblkid.so.1", O_RDONLY)  = 3
04 open("/lib64/libuuid.so.1", O_RDONLY)   = 3
05 open("/lib64/libselinux.so.1", O_RDONLY) = 3
06 open("/lib64/libsepol.so.1", O_RDONLY)  = 3
07 open("/lib64/libc.so.6", O_RDONLY)      = 3
08 open("/lib64/libdl.so.2", O_RDONLY)     = 3
09 open("/proc/filesystems", O_RDONLY)     = 3
10 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
11 open("/dev/null", O_RDWR)               = 3
12 <span style="color: #ff0000;"><strong>open("/etc/mtab", O_RDONLY)             = 3
13 </strong></span>

参考资料:

http://blog.csdn.net/sealyao/article/details/6710772

转载请注明:旅途@KryptosX » 系统调用追踪工具strace

目录
相关文章
【神州数码】无线配置步骤
【神州数码】无线配置步骤
956 0
|
6月前
|
人工智能 安全 Linux
零基础养出“聪明龙虾”|OpenClaw阿里云/本地部署+9个核心Skills安装+大模型配置实战手册
2026年,OpenClaw(俗称“龙虾”)作为开源AI智能体框架,凭借强大的任务执行与技能扩展能力,成为个人与轻量团队的高效工具。部署好OpenClaw仅仅是起点,其核心价值源于ClawHub仓库中37000+个Skills(技能插件)——它们如同AI助手的“灵魂”,赋予框架浏览器自动化、实时搜索、持续学习等实战能力。
998 5
|
11月前
|
前端开发 开发者 容器
css学习
css学习
637 136
Python 高级编程与实战:深入理解面向对象与并发编程
本文深入探讨Python的高级特性,涵盖面向对象编程(继承、多态、特殊方法、类与实例属性)、异常处理(try-except、finally)和并发编程(多线程、多进程、异步编程)。通过实战项目如聊天服务器和异步文件下载器,帮助读者掌握这些技术,编写更复杂高效的Python程序。
|
10月前
|
人工智能 自然语言处理 安全
MCP 打造 AI Agent 的 5 大最佳实践
面对流量激增、系统告急,单一渠道AI Agent难堪重负?问题不在能力,在架构!MCP(多渠道平台)作为智能体“神经中枢”,可统一调度Web、微信、钉钉等多渠道任务,实现高并发、可扩展的自动化。本文详解企业级MCP构建AI Agent的五大最佳实践:模块拆分、工具选型、设计模式、上下文管理与安全可控,助你快速落地高效、稳定的智能系统。
|
JSON JavaScript 数据格式
何如定义 JSON Schema 并验证该 json 数据?
本文定义了一个包含 audio 和 tags 两个必需属性的 JSON Schema,用于规范数据结构。其中,audio 是非空字符串,表示音频组件;tags 是非空数组,表示标签组件。通过示例数据和验证工具(如 ajv, NJsonSchema),可确保 JSON 数据符合 Schema 要求,从而保障数据的一致性和正确性。
718 1
|
SQL 关系型数据库 MySQL
宝塔面板之MySQL无法远程连接
宝塔面板默认安装的MySQL,root用户无远程权限。本文详细介绍如何使root支持远程连接:确保3306端口已放行,通过SSH登录服务器并进入MySQL,修改root用户的host为&#39;%&#39;,最后刷新权限。具体步骤包括使用SQL命令修改用户主机设置,并确保网络配置正确,从而实现root的远程访问。
4438 35
|
存储 前端开发 中间件
vue3之vite配置vite-plugin-mock使用mock轻松创建模拟数据提高开发效率
vue3之vite配置vite-plugin-mock使用mock轻松创建模拟数据提高开发效率
3313 0
|
运维 Kubernetes 监控
基于Kubernetes的Serverless PaaS稳定性建设万字总结
本文将侧重于实际落地而非方法论,阐述云产品 SAE 业务侧稳定性实际建设过程中的经验和思考。

热门文章

最新文章