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。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77119.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77119.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77119.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Git基本使用(很詳細)

一&#xff1a;Git 概述 1.1 定義&#xff1a;分布式版本控制系統 1.2 版本控制 &#xff08;1&#xff09;定義&#xff1a; 版本控制時一種記錄文件內容變化&#xff0c;以便將來查閱特定版本修訂情況的系統 &#xff08;2&#xff09;舉例 多副本 優化&#xff1a; 不使用多…

23種設計模式-結構型模式之橋接模式(Java版本)

Java 橋接模式&#xff08;Bridge Pattern&#xff09;詳解 &#x1f309; 什么是橋接模式&#xff1f; 橋接模式用于將抽象部分與實現部分分離&#xff0c;使它們可以獨立變化。 通過在兩個獨立變化的維度之間建立“橋”&#xff0c;避免因多維度擴展導致的類爆炸。 &#x…

基于SIMMECHANICS的單自由度磁懸浮隔振器PID控制系統simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序與模型 4.系統原理簡介 4.1 單自由度磁懸浮減振器工作原理簡介 4.2 SIMMECHANICS工具箱 5.完整工程文件 1.課題概述 基于SIMMECHANICS的單自由度磁懸浮隔振器PID控制系統simulink建模與仿真。其中&#xff0c;SIMMECHANICS是M…

contenthash 持久化緩存

以下是關于持久化緩存(contenthash)的深度技術解析,涵蓋原理、配置策略及最佳實踐,幫助我們構建高性能前端應用的緩存體系: 一、緩存機制核心原理 1. 瀏覽器緩存決策矩陣 觸發條件緩存行為對應場景URL 未變化 + 強緩存有效直接讀取磁盤/內存緩存未修改的靜態資源URL 變化…

【前端記事】關于electron的入門使用

electron入門使用 背景how to start第一步 創建一個vite-vue3項目第二步 裝各種依賴第三步 配置vite.config.jspackage.jsonelectron入口 啟動重寫關閉、隱藏、最大化最小化 背景 最近對electron比較感興趣&#xff0c;折騰一段時間后有了點眉目&#xff0c;記錄一下 how to …

跨瀏覽器音頻錄制:實現兼容的音頻捕獲與WAV格式生成

在現代Web開發中&#xff0c;音頻錄制功能越來越受到開發者的關注。無論是在線會議、語音識別還是簡單的語音留言&#xff0c;音頻錄制都是一個重要的功能。然而&#xff0c;實現一個跨瀏覽器的音頻錄制功能并非易事&#xff0c;因為不同瀏覽器對音頻錄制API的支持存在差異。本…

Semantic Kernel也能充當MCP Client

背景 筆者之前&#xff0c;分別寫過兩篇關于Semantic Kernel&#xff08;下簡稱SK&#xff09;相關的博客&#xff0c;最近模型上下文協議&#xff08;下稱MCP&#xff09;大火&#xff0c;實際上了解過SK的小伙伴&#xff0c;一看到 MCP的一些具體呈現&#xff0c;會發現&…

識別圖片內容OCR并重命名文件

在工作場景中&#xff0c;經常出現通過拍攝設備獲取圖片后&#xff0c;未及時進行有效命名的情況。這些圖片中往往包含關鍵信息&#xff08;如合同編號、產品型號、日期等&#xff09;&#xff0c;需要人工識別并命名&#xff0c;存在以下痛點&#xff1a; 效率低下&#xff1…

【防火墻 pfsense】3 portal

&#xff08;1&#xff09;應該考慮的問題&#xff1a; ->HTTPS 連接的干擾問題&#xff1a;HTTPS 是一種旨在防止惡意第三方截取和篡改流量的協議。但強制門戶的工作原理是截取并改變終端用戶與網絡之間的連接。這對于 HTTP 流量來說不是問題&#xff0c;但使用 HTTPS 加密…

銀發科技:AI健康小屋如何破解老齡化困局

隨著全球人口老齡化程度的不斷加深&#xff0c;如何保障老年人的健康、提升他們的生活質量&#xff0c;成為了社會各界關注的焦點。 在這場應對老齡化挑戰的戰役中&#xff0c;智紳科技順勢而生&#xff0c;七彩喜智慧養老系統構筑居家養老安全網。 而AI健康小屋作為一項創新…

TCP協議理解

文章目錄 TCP協議理解理論基礎TCP首部結構圖示字段逐項解析 TCP是面向連接&#xff08;Connection-Oriented&#xff09;面向連接的核心表現TCP 面向連接的核心特性TCP 與UDP對比 TCP是一個可靠的(reliable)序號與確認機制&#xff08;Sequencing & Acknowledgment&#xf…

什么是機器視覺3D碰撞檢測?機器視覺3D碰撞檢測是機器視覺3D智能系統中安全運行的核心技術之一

機器視覺3D碰撞檢測是一種結合計算機視覺和三維空間分析的技術,旨在檢測三維場景中物體之間是否發生碰撞(即物理接觸或交疊)。它通過分析物體的形狀、位置、運動軌跡等信息,預測或實時判斷物體間的碰撞可能性。以下是其核心要點: 基本原理 三維感知:利用深度相機(如RGB-…

nacos設置權重進行負載均衡不生效

nacos設置權重進行負載均衡不生效&#xff0c;必須在啟動類下加上這個bean Beanpublic IRule nacosRule(){return new NacosRule();}如下圖所示

創建 Node.js Playwright 項目:從零開始搭建自動化測試環境

一、環境準備 在開始創建 Playwright 項目之前&#xff0c;確保你的電腦上已經安裝了以下工具&#xff1a; Node.js&#xff1a;Playwright 依賴于 Node.js 環境&#xff0c;確保你已經安裝了最新版本的 Node.js。可以通過以下命令檢查是否安裝成功&#xff1a; node -v npm -…

日語學習-日語知識點小記-構建基礎-JLPT-N4階段(11): てあります。

日語學習-日語知識點小記-構建基礎-JLPT-N4階段&#xff08;11&#xff09;&#xff1a; てあります。 1、前言&#xff08;1&#xff09;情況說明&#xff08;2&#xff09;工程師的信仰 2、知識點&#xff08;1&#xff09;てあります。&#xff08;&#xff12;&#xff09;…

【金倉數據庫征文】- 深耕國產數據庫優化,筑牢用戶體驗新高度

目錄 引言 一、性能優化&#xff1a;突破數據處理極限&#xff0c;提升運行效率 1.1 智能查詢優化器&#xff1a;精準優化數據檢索路徑 1.2 并行處理技術&#xff1a;充分釋放多核計算潛力 1.3 智能緩存機制&#xff1a;加速數據訪問速度 二、穩定性提升&#xff1a;筑牢…

Java代理講解

代理 代理模式是一種結構型設計模式&#xff0c;它允許我們通過添加一個代理對象來控制對另一個對象的訪問。代理對象和實際對象具有相同的接口&#xff0c;使得客戶端在不知情的情況下可以使用代理對象進行操作。代理對象在與客戶端進行交互時&#xff0c;可以控制對實際對象…

利用deepseek快速生成甘特圖

一、什么是甘特圖 甘特圖&#xff08;Gantt Chart&#xff09;是一種直觀的項目管理工具&#xff0c;廣泛應用于多個領域&#xff0c;主要用于??時間規劃、任務分配和進度跟蹤??。 直觀性??&#xff1a;時間軸清晰展示任務重疊或延遲。 ??靈活性??&#xff1a;支持…

從零開始學習SLAM|技術路線

概念 視覺SLAM&#xff08;Simultaneous Localization and Mapping&#xff09;系統中&#xff0c;整個過程通常分為 前端 和 后端 兩個主要部分。前端處理的是從傳感器數據&#xff08;如相機圖像、激光雷達等&#xff09;中提取和處理信息&#xff0c;用于實時定位和建圖&am…

LeetCode 解題思路 44(Hot 100)

解題思路&#xff1a; dp 數組的含義&#xff1a; 以 nums[i] 為結尾的最長遞增子序列的長度。遞推公式&#xff1a; dp[i] Math.max(dp[i], dp[j] 1)。dp 數組初始化&#xff1a; dp[i] 1。遍歷順序&#xff1a; 從小到大去遍歷&#xff0c;從 i 1 開始&#xff0c;直到 …