內存越界引發線程函數調用堆棧回溯異常以及INT 3軟中斷實戰分析案例分享

目錄

1、問題說明

2、導出dump文件時只是遇到了INT 3軟中斷,并沒有發生異常崩潰

3、函數中發生了棧內存越界,導致線程的棧回溯出異常,堆棧中只顯示一行函數調用記錄

3.1、處理Json數據時產生了異常

3.2、函數中發生棧內存越界,可能會導致線程的棧回溯出異常

3.3、將打印出來的Json數據與代碼對照起來看,發現是數組越界了(棧內存越界)

4、遇到INT 3中斷,可能此時代碼出現了問題,可以查看此時的函數調用堆棧(附上INT 3軟中斷的詳細說明)

5、最后


C++軟件異常排查從入門到精通系列教程(核心精品專欄,訂閱量已達8000多個,歡迎訂閱,持續更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++實戰專欄(重點專欄,專欄文章已更新500多篇,訂閱量已達6000多個,歡迎訂閱,持續更新中...)https://blog.csdn.net/chenlycly/article/details/140824370C++ 軟件開發從入門到實戰(重點專欄,專欄文章已更新300多篇,歡迎訂閱,持續更新中...)https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能開發匯總(專欄文章列表,歡迎訂閱,持續更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++軟件分析工具從入門到精通案例集錦(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/article/details/131405795開源組件及數據庫技術(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/category_12458859.html網絡編程與網絡問題分享(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/category_2276111.html? ? ? ?近日項目中遇到了一個比較有代表性的軟件異常案例,其中有兩點值得關注,一是在崩潰前先產生了INT 3軟中斷(系統模塊中人為添加了INT 3軟中斷),二是代碼中發生了棧內存越界導致線程棧回溯出異常。本文來詳細講述一下該案例的排查過程以及涉及到的這兩個要點,以供大家借鑒或參考。

1、問題說明

? ? ? ?測試同事那邊反饋了一個崩潰,但軟件中安裝的異常捕獲模塊并沒有感知到,沒有生成dump文件。這個問題在當前場景下是必現的,于是測試同事直接將Windbg附加到目標進程上進行調試,然后復現問題,嘗試通過動態調試的Windbg去感知并捕獲異常。

? ? ? ?問題復現后,Windbg中斷下來,測試同事輸入kn命令將此時的函數調用堆棧打印出來,然后將堆棧截圖發到討論群中:

然后用.dump命令從當前正在調試的Windbg中導出了dump文件,將dump文件發給我。

? ? ? ?取到dump文件后,用Windbg打開,輸入.ecxr切換到異常上下文,然后輸入kn,打印出來的堆棧只顯示一行,如下所示:

這行中調用的是系統庫接口(ntdll庫中的RtlCaptureStackContext接口),并沒有看到我們軟件業務模塊的接口調用,這點很奇怪。

2、導出dump文件時只是遇到了INT 3軟中斷,并沒有發生異常崩潰

? ? ? ? 后來看到討論群里的截圖,截圖中可以看到當時只是產生了一個INT 3中斷:

并不是崩潰,這個INT 3會讓正在調試的Windbg中斷下來,測試同事以為Windbg中斷下來就是發生崩潰了(測試同事只會簡單地使用Windbg,對于一些細節不了解),于是導出了dump文件。所以后面我們拿到dump文件后,使用.ecxr和kn命令并沒看到有效的函數調用堆棧,只能看到系統庫接口的調用。

? ? ? ?因為這個問題是必現的,我這邊想直接用Windbg抓一次,抓一次發生異常崩潰時的dump。我先將軟件運行起來,然后將Windbg附加到軟件進程上,讓測試同事把問題復現出來。問題復現時,先產生了一個INT 3中斷:

輸入g命令將這個中斷跳過去,然后就發生了Access Violation內存訪問違例的異常(此時才發生異常崩潰),于是用.dump命令導出了dump文件。

因為Windbg動態調試時非常卡,根本沒法輸入命令,使用事先拷貝好的.dump命令導出了dump文件。

? ? ? ?關于如何使用Windbg靜態分析dump文件如何使用Windbg動態調試目標進程何時使用Windbg靜態分析及何時動態調試以及使用Windbg分析問題的諸多細節與技巧,我在此就不贅述了,可以查看我之前寫的專題文章:
使用Windbg分析dump文件定位軟件異常的方法與操作步驟https://blog.csdn.net/chenlycly/article/details/146005441使用Windbg調試目標進程排查C++軟件異常的一般步驟與要點分享https://blog.csdn.net/chenlycly/article/details/145826705何時使用Windbg靜態分析?何時使用Windbg動態調試?https://blog.csdn.net/chenlycly/article/details/131806819【C++軟件調試技術】使用Windbg分析軟件異常時的諸多細節與技巧總結 https://blog.csdn.net/chenlycly/article/details/140742933

3、函數中發生了棧內存越界,導致線程的棧回溯出異常,堆棧中只顯示一行函數調用記錄

3.1、處理Json數據時產生了異常

? ? ? ?接下來用Windbg打開dump文件進行分析,輸入.ecxr切換到發生異常的上下文,輸入kn命令,結果堆棧中也只顯示一行,不過這行中看到了業務模塊接口的調用:

于是找到堆棧中模塊的pdb文件,設置到Windbg中,重新將函數調用堆棧打印出來,可以看到函數中的具體行號,提供給該模塊的維護人員,讓他們詳細分析一下崩潰的原因。

? ? ? 點開這行前面的索引鏈接,顯示出當前函數中相關變量的值,看到傳入該函數的是Json數據,函數中要把這個Json數據要按節點讀取出來,保存結構體變量中,然后投遞給上層。看到Json數據,猜測可能是處理Json數據時出了異常,可能是以下原因導致的

1)在解析Json數據時產生了異常,比如平臺側修改了Json數據的格式,沒通知終端側,導致終端側解析Json數據的代碼產生了異常,這樣的問題我們以前遇到過。
2)可能是Json串中某個節點的值是不正常的異常值,導致代碼處理邏輯出問題。比如是個異常大的值,如果用該值作為for循環的條件,則會導致死循環。
3)Json數據中包含的數據對象個數大于本地對應的數組的個數,而本地沒有判斷數組是否超過長度,從而導致操作數組越界。本案例中的問題,就是這個原因導致的。下面會詳細講解本案例的這個問題場景。

3.2、函數中發生棧內存越界,可能會導致線程的棧回溯出異常

? ? ? ?此處堆棧中只顯示一行,有些奇怪,難道是當前函數中發生了棧內存越界,直接把堆棧中保存的主調函數的ebp棧基址覆蓋了(通過函數中的棧基址將函數調用堆棧回溯出來),導致線程棧回溯不出來了?經后面分析,確實是這個原因導致的。

因為棧是從大地址向小地址方向分配使用的,如果當前函數中發生在棧內存越界,是從操作的起始地址向后面的大地址方向越界,可能會越界到存放主調函數的ebp棧基址值的內存區域(篡改了棧基址值),這樣會導致回溯函數調用堆棧時出現問題,所以上面只能看到當前函數的調用, 且只顯示一行調用記錄:

? ? ? ? 關于函數調用的棧分布以及線程函數調用堆棧的棧回溯原理,可以查看我之前寫的專題文章:
C++函數調用棧分布詳解(理解多個問題的切入點)https://blog.csdn.net/chenlycly/article/details/121001096C++棧回溯原理(C++異常排查面試題)https://blog.csdn.net/chenlycly/article/details/121002139


??? ? ? ?在這里,給大家重點推薦一下我的幾個熱門暢銷專欄,歡迎訂閱:(博客主頁還有其他專欄,可以去查看)

專欄1:【C++軟件異常與異常排查從入門到精通系列教程】該精品技術專欄的訂閱量已達到10000多個,專欄中包含大量項目實戰分析案例,有很強的實戰參考價值,廣受好評!專欄文章持續更新中,已經更新到200篇以上!歡迎訂閱!)

C++軟件調試與異常排查從入門到精通系列文章匯總https://blog.csdn.net/chenlycly/article/details/125529931

本專欄根據多年C++軟件異常排查的項目實踐,系統地總結了引發C++軟件異常的常見原因以及排查C++軟件異常的常用思路與方法詳細講述了C++軟件的調試方法與手段詳細介紹分析C++軟件問題的常用分析工具,以圖文并茂的方式給出具體的項目問題實戰分析實例(詳細講述分析排查過程,很有實戰參考價值),帶領大家逐步掌握C++軟件調試與異常排查的相關技術,適合基礎進階和想做技術提升的相關C++開發人員!

考察一個開發人員的水平,一是看其編碼及設計能力,二是要看其軟件調試能力!所以軟件調試能力(排查軟件異常的能力)很重要,必須重視起來!能解決一般人解決不了的問題,既能提升個人能力及價值,也能體現對團隊及公司的貢獻!

專欄中的文章都是通過項目實戰總結出來的,包含大量項目問題實戰分析案例,有很強的實戰參考價值!專欄文章還在持續更新中,預計文章篇數能更新到200篇以上!

專欄2:【C/C++實戰進階】(該專欄涵蓋了C++多方面的內容,是當前重點打造的專欄,訂閱量已達8000多個,專欄文章已經更新到500多篇,持續更新中...)

C/C++實戰進階(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/category_11931267.html

以多年的開發實戰為基礎,總結并講解一些的C/C++基礎與項目實戰進階內容,以圖文并茂的方式對相關知識點進行詳細地展開與闡述!專欄涉及了C/C++領域多個方面的內容,包括C++基礎及編程要點(模版泛型編程、STL容器及算法函數的使用等)、數據結構與算法C++11及以上新特性(開源代碼中可能會用到很多新特性(比如WebRTC開源庫),日常編碼中也會用到部分新特性,面試時也會頻繁地涉及到,學習新特性很有必要)、常用C++開源庫的介紹與使用(比如SQLite、libcurl、libwebsockets、libevent、jsoncpp/RapidJson、Redis、RabbitMQ、MongoDB、MQTT、ZooKeeper、OpenCV、FFmpeg、SDL、GStreamer、Live555、ReactOS等)、代碼分享(調用系統API、使用開源庫)、常用編程技術(動態庫、多線程、多進程、數據庫及網絡編程等)、軟件UI編程(Win32/duilib/QT/MFC)、C++軟件調試技術(引發C++軟件異常的常見原因分析與總結、排查C++軟件異常的手段與方法、分析C++軟件異常的基礎知識、使用常用軟件分析工具分析C++軟件問題、多個項目實戰問題分析案例分享等)、設計模式(單例模式、工廠模式、觀察者模式、狀態模式等)、網絡基礎知識與網絡問題分析進階內容(實戰問題分析實例分享)等。本專欄的內容都是建立在項目實踐的基礎上,來源于項目實戰,服務于項目實戰,很有實戰參考價值!

專欄3:【分析C++軟件問題的實用軟件與高效工具實戰案例集錦】

C++常用軟件分析工具從入門到精通案例集錦匯總(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/article/details/131405795

常用的C++軟件輔助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro以及內存泄漏檢測工具等,本專欄詳細介紹如何使用這些工具去巧妙地分析和解決日常工作中遇到的問題,很有實戰參考價值!

專欄4:【VC++常用功能代碼封裝】

VC++常用功能開發匯總(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/article/details/124272585

將10多年C++開發實踐中常用的功能,以高質量的代碼展現出來。這些常用的高質量規范代碼,可以直接拿到項目中使用,能有效地解決軟件開發過程中遇到的問題。

專欄5:【C/C++軟件開發從入門到實戰】(本專欄涵蓋了C++多方面的內容,是當前重點打造的專欄,專欄文章已經更新到300多篇,持續更新中!歡迎訂閱!)?

C++ 軟件開發從入門到精通(專欄文章,持續更新中...)https://blog.csdn.net/chenlycly/category_12695902.html

根據多年C++軟件開發實踐,詳細地總結了C/C++軟件開發相關技術實現細節,分享了大量的實戰案例,很有實戰參考價值。


3.3、將打印出來的Json數據與代碼對照起來看,發現是數組越界了(棧內存越界)

? ? ? ?查看運行日志看到平臺傳過來的Json數據中某類對象有26個:

但本端存放這些對象的數組中只有10個元素(數組長度是10),如下所示:

代碼中在將Json串中某對象數據保存到數組中時,沒有判斷數組的長度,直接將26個對象保存進來了,所以導致操作數組時越界了。該數組所在的結構體定義成局部變量,所以發生的內存越界應該是棧內存越界,然后將堆棧中存放的主調函數的ebp棧基址給覆蓋了,導致棧回溯出現了問題,所以堆棧中只看到一行記錄。這樣引發問題的原因和現象就完全一致了,能對得上了!

4、遇到INT 3中斷,可能此時代碼出現了問題,可以查看此時的函數調用堆棧(附上INT 3軟中斷的詳細說明)

? ? ? ?如果要查看完整的函數調用堆棧,可能產生INT 3中斷時可以看到,查看此時的函數調用堆棧可能也能找到問題。

? ? ? 在代碼的異常分支中可以插入軟中斷的匯編代碼_asm INT 3:

// manual breakpoint
_asm INT 3;
printt("HeLlo INT 3!\n");

當代碼執行到該異常分支時就會產生INT 3軟中斷,所以遇到INT 3中斷可能就是為了提示當前代碼可能出問題了。

? ? ? ?關于INT 3軟中斷的詳細說明,翻看了張銀奎老師的《軟件調試》一書部分章節:(這本書推薦大家看一下,要多看書、看好書!

? ? ? ?可能是在代碼的問題分支中添加了_asm INT 3這條語句,當代碼執行到該異常分支時就會產生INT 3軟中斷,讓調試器中斷下來,提示用戶當前程序可能出了異常,中斷下來好讓用戶查看此時的函數調用堆棧,然后進行分析。

5、最后

? ? ? ?軟件中發生棧內存越界,將主調函數的ebp棧基址給改寫了,導致函數調用堆棧回溯出問題,以及代碼中人為加入INT 3軟中斷,之前很少遇到,這次算是見識到實戰案例了,所以在此記錄總結一下,分享給大家。

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

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

相關文章

LeetCode 240: 搜索二維矩陣 II - 算法詳解(秒懂系列

文章目錄LeetCode 240: 搜索二維矩陣 II - 算法詳解題目描述Java解決方案算法思路核心理念為什么選擇右上角?可視化演示過程示例1:查找 target 5示例2:查找 target 20 (不存在)算法分析時間復雜度空間復雜度算法優勢關鍵要點擴展思考LeetCo…

洛谷 B4071 [GESP202412 五級] 武器強化

思考難度低,但是代碼難度相對較高的題,故做個記錄。首先,題目說了要花費最少的錢,所以我們每次拿最便宜的材料給武器1思想:每次都拿最便宜的材料然后考慮一下這個思想是否正確,找一下反例,每次拿…

SQL工具30年演進史:從Oracle到Navicat、DBeaver,再到Web原生SQLynx

目錄 一、1990s:廠商自帶的數據庫工具時代 二、2000s:Navicat等商業數據庫管理工具崛起 三、2010s:DBeaver等開源SQL工具興起 四、2020s:SQLynx,Web原生數據庫管理工具 五、SQL工具30年時間線對比 六、總結&…

C語言制作掃雷游戲(拓展版賦源碼)

目錄 引言: 三個新功能實現 1.可以選擇難度或自定義 實現難點解析 代碼實現(附源碼) 掃雷.c game.h game.c 2.對選擇位置進行標記或取消標記 一.框架 我們先理一下思路 如何構造框架 二.取消標記函數 三.標記函數 四.加入清屏,進…

Python快速入門專業版(十):字符串特殊操作:去除空格、判斷類型與編碼轉換

目錄引1.去除空格:清理字符串的實用技巧1.1 三類去空格方法:strip()、lstrip()、rstrip()1.2 實戰案例:處理用戶輸入的空格問題2.判斷類型:驗證字符串內容的特性2.1 常用類型判斷方法2.2 實戰案例:驗證用戶輸入的合法性…

Gamma AI:AI演示文稿制作工具,高效解決PPT框架搭建難與排版耗時問題

你做 PPT 的時候是不是也常陷入 “兩難”?要么對著空白幻燈片發呆,不知道怎么搭框架 —— 比如要做 “產品季度迭代復盤”,既想放數據又想講問題,結果頁面堆得像亂燉;要么好不容易湊完內容,又花兩小時調排版…

【應用案例】AI 給醫用過濾器 “找茬”:3 大難點 + 全流程解決方案

【應用案例】AI 給醫用過濾器 “找茬”:3 大難點 全流程解決方案🎯醫用過濾器進行醫療AI檢測🎯先看痛點:醫用過濾器檢測難在哪?🎯AI檢測方案:3步實現“零漏檢”1. 硬件定制:讓缺陷“…

【數據庫相關】TxSQL新增數據庫節點步驟

TxSQL新增數據庫節點步驟準備工作與注意事項具體操作步驟第 1 步:在主庫上創建復制專用賬號第 2 步:對主庫進行鎖表并獲取二進制日志坐標第 3 步:備份主庫數據并傳輸到新從庫第 4 步:主庫解鎖第 5 步:在新從庫服務器上…

Jmeter快速安裝配置全指南

1、JDK安裝(Java Development Kit) 1.1.JDK下載 JDK下載址: Java Downloads | Oracle (jdk-8u211-windows-x64.exe) Android 基于 Java 語言開發,所以必須安裝Java環境,Java 環境分JDK 和JRE ,JDK提…

設計模式最佳實踐 - 模板模式 + 責任鏈模式

廢話不多說,直接切入正題,本篇要講的是 模板模式 責任鏈模式 實踐。該最佳實踐本身就是一種對 責任鏈模式的增強,模板模式通過 父類 強耦合,預定義好 責任鏈 next 方法 的前后一些切面行為,優雅簡潔。先上示例&#x…

Python快速入門專業版(十一):布爾值與None:Python中的“真假”與“空值”(附邏輯判斷案例)

目錄引言:為什么“真假”與“空值”是編程的核心邏輯1.布爾值(bool):Python中的“真”與“假”1.1 布爾值的基礎特性1.2 布爾運算:and、or、not的邏輯規則代碼示例:基礎布爾運算進階特性:短路求…

C++學習知識小結

1. 什么是類?什么是對象?兩者之間什么關系? 類是一類事物的共同特征的抽象描述,它定義這類所有的屬性和方法 可以理解為模版類本身不占用空間,它只是一種定義,描述了對象一個是什么樣子、能做什么 對象是根…

9. Mono項目與Unity的關系

1.Mono項目簡介 2.Mono項目與Unity是如何結合的 3.從Mono到IL2CPP演變過程1.Mono項目簡介 1).定義Mono是一個自由、開源的項目, 由Xamarin現屬于微軟主導開發; 它的目標是創建一個一套兼容于微軟.NET Framework 的跨平臺工具2).核心功能a.C#編譯器能將你寫的C#代碼編譯成IL(中間…

谷歌Genie 3:讓你的照片變成可以玩的游戲世界

你是否曾凝視著一張完美的旅行照片,想象著如果能走進那個畫面,自由探索會是怎樣一種體驗?或者,你是否曾被一幅畫的奇幻氛圍所吸引,渴望能在那片色彩斑斕的世界里奔跑跳躍?過去,這只是白日夢。而…

Cursor 提示詞探索——如何打造真正懂自己的Agent

最近看到魚皮的Cursor提示詞分享(微信公眾平臺),剛好之前也在做Agent開發,跟提示詞打交道的多,也經常發現 ai 蠢蠢的,一點不會根據提示詞設計的來,按魚皮的分享研究了一下,寫了這篇博客。 Curs…

C++ 內存模型:用生活中的例子理解并發編程

C 內存模型:用生活中的例子理解并發編程 文章目錄C 內存模型:用生活中的例子理解并發編程引言:為什么需要內存模型?核心概念:改動序列原子類型:不可分割的操作內存次序:不同的同步級別1. 寬松次…

AI急速搭建網站:Gemini、Bolt或Jules、GitHub、Cloudflare Pages實戰全流程!

文章目錄AI急速搭建網站:Gemini、Bolt或Jules、GitHub、Cloudflare Pages實戰全流程!🚀 極速建站新范式:Gemini、Bolt.new、GitHub & Cloudflare Pages 全流程實戰!第一步:創意可視化與代碼生成 — Goo…

Qwen2.5-VL實現本地GPTQ量化

本文不生產技術,只做技術的搬運工!! 前言 公開的Qwen2.5-VL模型雖然功能非常強大,但有時面對專業垂直領域的問題往往會出現一些莫名其妙的回復,這時候大家一版選擇對模型進行微調,而微調后的模型如果直接部署則顯存開銷過大,這時就需要執行量化,下面將介紹執行本地GPT…

【Redis】常用數據結構之Hash篇:從常用命令到使用場景詳解

目錄 1.前言 插播一條消息~ 2.正文 2.1Hash與String對比 2.2常用命令 2.2.1HSET 2.2.2HGET 2.2.3HEXISTS 2.2.4HDEL 2.2.5HKEYS 2.2.6HVALS 2.2.7HGETALL 2.2.8HMGET 2.2.9HLEN 2.2.10HSETNX 2.2.11HINCRBY 2.2.12HINCRBYFLOAT 2.3內部編碼 2.3.1. ziplist&…

OSPF基礎部分知識點

OSPF基礎 前言 路由器 根據 路由表 轉發數據包,路由表項 可通過手動配置 和動態路由協議 生成。(兩種生成方式)靜態路由比動態路由使用更少的帶寬,并且不占用CPU資源來計算和分析路由更新。當網絡結構比較簡單時,只需配…