linux ptrace 图文详解(七) gdb、strace跟踪系统调用
目录
一、gdb/strace 跟踪程序系统调用
二、实现原理
三、代码实现
四、总结
(代码:linux 6.3.1,架构:arm64)
One look is worth a thousand words. —— Tess Flanders
相关链接:
linux ptrace 图文详解(一)基础介绍
linux ptrace 图文详解(二) PTRACE_TRACEME 跟踪程序
linux ptrace 图文详解(三) PTRACE_ATTACH 跟踪程序
linux ptrace 图文详解(四) gdb设置软断点
linux ptrace 图文详解(五) gdb设置硬断点、观察点
linux ptrace 图文详解(六) gdb单步调试
一、gdb/strace 跟踪程序系统调用
gdb、strace都能够跟踪被调试程序在执行过程中的所有系统调用,其底层依赖的就是ptrace(PTRACE_SYSCALL) 的能力。当使用 PTRACE_SYSCALL 时,被跟踪的进程会在每次系统调用的开始或结束时被暂停挂起,并通知父进程(gdb、strace)。这使得开发者能够详细地监控和分析程序的系统调用行为,对于调试和性能分析非常有用。
下图是strace跟踪ls命令执行期间,用到的所有系统调用信息:
二、实现原理
上图是gdb跟踪被调试程序执行过程中所有系统调用的原理:
1)gdb通过ptrace(PTRACE_SYSCALL),为被调试程序的task置位TIF_SYSCALL_TRACE,然后返回;
2)被调试程序执行系统调用陷入内核;
3)在系统调用的入口,调用tracehook_report_syscall,判断当前task是否置位TIF_SYSCALL_TRACE;
4)若置位,则将PTRACE_EVENTMSG_SYSCALL_ENTRY记录到被调试程序task的ptrace_message中;
5)随后给父进程gdb发送SIGCHLD信号,并唤醒gdb的wait操作,同时设置父进程gdb wait操作的status值 ( (SIGTRAP | 0x80) << 8) | 0X70;其中,0x80代表被调试程序触发了syscall!
6)被调试程序将自己挂起;
7)gdb被唤醒后,检查wait的status返回值内容,发现置位了0x80,说明被调试程序执行了syscall;
8)gdb通过ptrace(PTRACE_GETEVENTMSG) 获取被调试任务内核中的task->ptrace_message内容,来判断当前被调试程序是刚进入syscall、还是已经执行完毕syscall;
9)gdb唤醒被调试程序继续运行,被调试程序被调度运行后,调用invoke_syscall执行真正的系统调用任务;
10)当invoke_syscall执行完毕后,会再次调用tracehook_report_syscall,将自身挂起并通知gdb(这个流程与上述3~6步一致),唯一的区别是:此时设置到被调试任务task->ptrace_message中的字段是PTRACE_EVENTMSG_SYSCALL_EXIT;
11)gdb被唤醒后,判断出被调试程序是因为syscall挂起的,通过ptrace(PTRACE_GETEVENTMSG)可以获取到被调试程序执行完毕系统调用的信息;
是
三、代码实现
1、gdb、strace 通过 ptrace(PTRACE_SYSCALL) 为被调试程序置位标志
ptrace_requestcase PTRACE_SYSCALL:return ptrace_resume(child, request, data) {if (request == PTRACE_SYSCALL)set_task_syscall_work(child, SYSCALL_TRACE) {set_ti_thread_flag(task_thread_info(t), TIF_SYSCALL_TRACE)}}
2、被调试程序进入系统调用前夕,将自己暂停下来并通知gdb
el0t_64_sync_handler {el0_svcdo_el0_svcel0_svc_common {unsigned long flags = current_thread_info()->flagsif (has_syscall_work(flags)) {syscall_trace_enter {if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE))tracehook_report_syscall(struct pt_regs *regs = regs,enum ptrace_syscall_dir dir = PTRACE_SYSCALL_ENTER) {regno = (is_compat_task() ? 12 : 7)saved_reg = regs->regs[regno]regs->regs[regno] = dirif (dir == PTRACE_SYSCALL_ENTER) {tracehook_report_syscall_entry(regs){ptrace_report_syscall(regs, unsigned long message = PTRACE_EVENTMSG_SYSCALL_ENTRY) {
/* 保存syscall entry/exit event */ current->ptrace_message = message // 保存 PTRACE_EVENTMSG_SYSCALL_ENTRY 到ptrace_message, 之后gdb会调用ptrace来获取该信息
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ptrace_notify(int exit_code = SIGTRAP | 0x80) {ptrace_do_notify(int signr = SIGTRAP, int exit_code = exit_code, int why = CLD_TRAPPED) {ptrace_stop(exit_code, why, int clear_code = 1, &info) { // 通知tracer, 并将自己挂起current->last_siginfo = infocurrent->exit_code = exit_codedo_notify_parent_cldstop(current, true, why = CLD_TRAPPED)info.si_signo = SIGCHLDinfo.si_code = why // A.K.A: CLD_TRAPPEDinfo.si_status = tsk->exit_code & 0x7f__group_send_sig_info(SIGCHLD, &info, parent)send_signal(sig, info, p, PIDTYPE_TGID)__send_signal(sig, info, t, type, force)__wake_up_parentfreezable_schedulecurrent->last_siginfo = NULL // after wake up by gdb, clear last_siginfo}}}if (current->exit_code) {send_sig(current->exit_code, current, 1)current->exit_code = 0}current->ptrace_message = 0return fatal_signal_pending(current)}//ptrace_report_syscall}//tracehook_report_syscall_entry}regs->regs[regno] = saved_reg}return regs->syscallno}//syscall_trace_enter}invoke_syscall...}
}
3、被调试程序系统调用执行完毕后,将自己暂停下来并通知gdb
el0t_64_sync_handler {el0_svcdo_el0_svcel0_svc_common {unsigned long flags = current_thread_info()->flagsif (has_syscall_work(flags)) {syscall_trace_enter}invoke_syscallsyscall_trace_exit {unsigned long flags = READ_ONCE(current_thread_info()->flags)if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT) {tracehook_report_syscall_exit(regs, step = 0) {ptrace_report_syscall(regs, unsigned long message = PTRACE_EVENTMSG_SYSCALL_EXIT) {current->ptrace_message = messageptrace_notify(exit_code = SIGTRAP | 0x80)ptrace_do_notify(SIGTRAP, exit_code, why = CLD_TRAPPED) {kernel_siginfo_t infoinfo.si_signo = signrinfo.si_code = exit_code // A.K.A: SIGTRAP | 0x80ptrace_stop(exit_code, why, 1, &info) {current->last_siginfo = infocurrent->exit_code = exit_codedo_notify_parent_cldstop(current, true, why) {info.si_signo = SIGCHLDinfo.si_code = why // A.K.A: CLD_TRAPPEDinfo.si_status = tsk->exit_code & 0x7f__group_send_sig_info(SIGCHLD, &info, parent)send_signal(sig, info, p, PIDTYPE_TGID)__send_signal(sig, info, t, type, force)}current->last_siginfo = NULL // after wake up by gdb, clear last_siginfo}}//ptrace_do_notify}//ptrace_report_syscall}//tracehook_report_syscall_exit}//tracehook_report_syscall }//syscall_trace_exit}//el0_svc_common
}
四、总结
gdb、strace监控被调试程序的系统调用,主要是依赖系统调用的路径上,根据被调试程序是否置位TIF_SYSCALL_TRACE,通过tracehook_report_syscall将自身暂停,并记录相应的信息(PTRACE_EVENTMSG_SYSCALL_ENTRY、PTRACE_EVENTMSG_SYSCALL_EXIT)到current->ptrace_message中供后续gdb、strace通过ptrace(PTRACE_GETEVENTMSG)获取,最后通知gdb。
相关文章:

linux ptrace 图文详解(七) gdb、strace跟踪系统调用
目录 一、gdb/strace 跟踪程序系统调用 二、实现原理 三、代码实现 四、总结 (代码:linux 6.3.1,架构:arm64) One look is worth a thousand words. —— Tess Flanders 相关链接: linux ptrace 图…...

【前端】ES6 引入的异步编程解决方案Promise 详解
Promise 详解 1. 基本概念 定义:Promise 是 ES6 引入的异步编程解决方案,表示一个异步操作的最终完成(或失败)及其结果值。核心作用:替代回调函数,解决“回调地狱”问题,提供更清晰的异步流程控…...
常见正则表达式整理与Java使用正则表达式的例子
一、常见正则表达式整理 1. 基础验证类 邮箱地址 ^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\\.[a-zA-Z]{2,}$ (匹配如 userexample.com)手机号 ^1[3-9]\\\\d{9}$ (匹配国内11位手机号,如 13812345678)中文字符 ^[\u4e00-\u9fa5…...

const(C++)
打印出来的结果是 a是12 *p是200 const修饰指针 const修饰引用...

python21-循环小作业
课程:B站大学 记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化 循环语句小作业 for-in作业斐波那契 for 固定数值计算素数字符统计数字序列range 函数 水仙花…...

小白电路设计-设计11-恒功率充电电路设计
介绍 作为电子信息工程的我,电路学习是一定要学习的,可惜目前作为EMC测试工程师,无法兼顾太多,索性不如直接将所学的知识进行运用,并且也可以作为契机,进行我本人的个人提升。祝大家与我一起进行提升。1.本…...
传感器模块有助于加速嵌入式视觉开发
传感器模块是一种小型成像解决方案,用于轻松将定制的视觉技术集成到机器和设备中,使其具备“视觉”功能。机器人、无人机、物联网、消费电子设备和监控应用的开发人员在设计中使用传感器模块,可以节省开发时间和资源。FRAMOS 推出了一个创新的可互换传感器模块和适配器生态系…...

Spring AI 快速入门:从环境搭建到核心组件集成
Spring AI 快速入门:从环境搭建到核心组件集成 一、前言:Java开发者的AI开发捷径 对于Java生态的开发者来说,将人工智能技术融入企业级应用往往面临技术栈割裂、依赖管理复杂、多模型适配困难等挑战。Spring AI的出现彻底改变了这一局面——…...

http://noi.openjudge.cn/——2.5基本算法之搜索——200:Solitaire
文章目录 题目宽搜代码总结 题目 总时间限制: 5000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB 描述 Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left t…...

架构师面试(三十六):广播消息
题目 在像 IM、短视频、游戏等实时在线类的业务系统中,一般会有【广播消息】业务,这类业务具有瞬时高流量的特点。 在对【广播消息】业务实现时通常需要同时写 “系统消息库” 和更新用户的 “联系人库” 的操作,用户的联系人表中会有未读数…...
如何开启远程桌面连接外网访问?异地远程控制内网主机
实现远程桌面连接外网访问,能够突破地域限制,随时随地访问远程计算机,满足远程办公、技术支持等多种需求。下面为你详细介绍开启方法。 一、联网条件 确保本地计算机和远程计算机都有稳定的网络连接,有联网能上网。 二、开启远程…...
基于 Python(selenium) 的百度新闻定向爬虫:根据输入的关键词在百度新闻上进行搜索,并爬取新闻详情页的内容
该项目能够根据输入的关键词在百度新闻上进行搜索,并爬取新闻详情页的内容。 一、项目准备 1. 开发环境配置 操作系统:支持 Windows、macOS、Linux 等主流操作系统,本文以 Windows 为例进行说明。Python 版本:建议使用 Python 3.8 及以上版本,以确保代码的兼容性和性能。…...

TortoiseGit使用图解
前言 记录GitTortoiseGit使用,记录下开发中常用命令,健忘时用到方知好。 TortoiseGit使用 图解 commit-提交代码 pull-拉取远程分支最新代码 push-将本地分支代码推送到远程分支 show log-查看分支提交记录 show log - 切换分支查看 show log - 远程分…...

【时时三省】(C语言基础)循环程序举例
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 例题: 用公式4/π≈1-3/1+5/1-7/1+...求π的近似值,直到发现某一项的绝对值小于10的-6次方为止(该项不累加)。 解题思路: 这是求值的近似方法中的一种。求π值可以用不同的近似方法。如下面的表达式都可以…...
根据JSON动态生成表单表格
根据JSON动态生成表单表格 一. 子组件 DynamicFormTable.vue1,根据JSON数据动态生成表单表格,支持表单验证JS部分1.1,props数据1.2,表单数据和数据监听1.3,自动验证1.4,表单验证1.5,获取表单数据1.6,事件处理1.7,暴露方法给父组件2,HTML部分二,父组件1, 模拟数据2,…...

珍爱网:从降本增效到绿色低碳,数字化新基建价值凸显
2024年12月24日,法大大联合企业绿色发展研究院发布《2024签约减碳与低碳办公白皮书》,深入剖析电子签在推动企业绿色低碳转型中的关键作用,为企业实现环境、社会和治理(ESG)目标提供新思路。近期,法大大将陆…...

电子电子架构 --- 主机厂视角下ECU开发流程
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…...

PyQt6基础_QTableWidget
目录 描述: 代码 演示 描述: 1 单击选中一行 2 右键菜单 3 填充数据 4 提取行数据 5 删除行数据 代码 from PyQt6.QtCore import (Qt ) from PyQt6.QtGui import ( QAction ) from PyQt6.QtWidgets import (QApplication,QAbstractItemView,QL…...

uniapp 上传二进制流图片
文章目录 场景🟢一、步骤1.1、选择图片1.2、 读取图片为二进制数据1.3、上传二进制数据到服务器 🟢二、项目案例2.1、替换头像案例2.1、uView u-upload 上传封面 🟢 三、关键注意事项3.1 二进制流与 FormData 区别3.2 性能优化3.3 跨平台适配…...

赛灵思 XCKU115-2FLVB2104I Xilinx Kintex UltraScale FPGA
XCKU115-2FLVB2104I 是 AMD Xilinx Kintex UltraScale FPGA,基于 20 nm 先进工艺,提供高达 1 451 100 个逻辑单元(Logic Cells),77 721 600 bit 的片上 RAM 资源,以及 5 520 个 DSP 切片(DSP48E…...

Unreal Niagara制作SubUV贴图翻页动画
SubUV翻页动画是游戏中的常见功能,通过对每一小块UV进行移动可以模拟动画效果,接下来对下图进行SubUV动画的制作。 (金币测试图下载地址:https://download.csdn.net/download/grayrail/90684422) 最终效果如下: 1.…...

「零配置陷阱」:现代全栈工具链的复杂度管控实践
一、工具链膨胀的「死亡螺旋」 2024年典型全栈项目的初始化噩梦: $ npm create vitelatest ✔ Project name: … demo ✔ Select a framework: › React ✔ Select a variant: › TypeScript SWC ✔ Install shadcn/ui? … Yes ✔ Add Storybook? … Yes ✔ Co…...

金仓数据库KingbaseES技术实践类深度剖析与实战指南
一、语法兼容及迁移实战 (一)语法兼容的多元魅力 在当今多元化的数据库应用环境中,金仓数据库管理系统KingbaseES凭借其卓越的语法兼容能力脱颖而出。它采用的融合数据库架构,通过多语法体系一体化架构,实现了对Orac…...

基于ssm的个人博客管理系统(源码+数据库+万字文档)
57基于ssm的个人博客管理系统:前端jsp、jquery、easyui,后端 spring、mybatis、maven,集成个人博客浏览、详情查看、博客发布、富文本编辑、评论等功能于一体的系统。 ## 功能介绍 ### 用户 - 首页:博客列表、博客详情、关键词…...
c#加密证件号的中间部分,改为*号
前言 使用场景:在我项目中,我需要给前端提供接口,所以我要吧证件号进行加密。例如:411421199510225612,这是一个身份证号,18为的,那么我加密完成之后就会是 411421********5612,类似…...

综述 | GUI Agent:让AI学会「玩手机」的新革命
想象一下,你的手机里住着一个隐形助理:你说“把亮度调到50%”,它自动操作;你说“下载最新游戏”,它一键完成。这就是GUI智能体——一种能“看懂”屏幕并操作的AI。 论文:A Survey on (M)LLM-Based GUI Agen…...

Canvas入门教程!!【Canvas篇二】
没有一朵花,从一开始就是花。 目录 translate() 方法:rotate() 方法:scale() 方法: translate() 方法: Canvas 2D API 的 CanvasRenderingContext2D.translate() 方法用于对当前网格添加平移变换。 translate() 方法通…...

【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题)
【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题) 目录 【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题)一、历年真题二、考点:函数调用 —— 传值调用和传地址调用🔺1、传值调用🔺2、传引用(地址)调…...

第七届能源系统与电气电力国际学术会议(ICESEP 2025)
重要信息 时间:2025年6月20-22日 地点:中国-武汉 官网:www.icesep.net 主题 能源系统 节能技术、能源存储技术、可再生能源、热能与动力工程 、能源工程、可再生能源技术和系统、风力发…...

大数据分析04 数据查询分析
构建数据源 引入pandas包 数据map中ID为列,值为行,每一列中值个数要一致 import pandas as pd data {ID: [000001, 000002, 000003, 000004, 000005, 000006, 000007],name:[黎明, 赵怡春, 张富平, 白丽, 牛玉德, 姚华, 李南], gender:[True, False, …...