記一次 .NET某固高運動卡測試 卡慢分析

一:背景

1. 講故事

年前有位朋友找到我,說他們的程序會偶發性卡慢 10s 鐘,在某些組合下會正常,某些組合下就會出現問題,解釋不了其中的原因,讓我幫忙看下怎么回事?截圖如下:


private void TestRun()
{int encposUpy = 0;Logger Log = new Logger();Task.Factory.StartNew(delegate{Log.Info("GTN_GetEcatEncPos.上探頭Y------start。");while (runFlag){Log.Info($"GTN_GetEcatEncPos.上探頭Y --{encposUpy}");Stopwatch stopwatch = new Stopwatch();stopwatch.Start();mc.GTN_GetEcatEncPos(nCore, 2, out encposUpy);if (stopwatch.ElapsedMilliseconds > 500){Log.Info($"GTN_GetEcatEncPos.上探頭y超時報警------{stopwatch.ElapsedMilliseconds}");MessageBox.Show("卡頓現象出現,測試停止.");runFlag = false;}Thread.Sleep(10);}MessageBox.Show("測試結束.");});
}

這種問題還是挺有意思的,即 GTN_GetEcatEncPos 方法會有 10s 的卡慢情況,接下來我們就來探究下。

二:為什么會卡慢

1. 使用 perfview

像 GTN_GetEcatEncPos 這種動態性的卡死,首先看dump不是一個好的策略,最好的方式就是給程序安裝攝像頭,采集程序的運行狀態,這里推薦的自然是 PerfView,開啟墻鐘模式,即定期的采集線程棧數據。

朋友按照建議拿到了 etl 文件,拿到 etl 文件之后,搜索 TestRun 方法,搜索內部匿名函數,截圖如下:

從卦中看果然給捕獲到了,那個所謂的 10s 卡滿,原來是在 gts(固高運動卡) 下的 kernelbase!WaitForSingleObject 上,由于 gts 是閉源的,拿不到 pdb 符號所以顯示不出內部函數,雖然沒有直接找到禍根,但還是有一點進展的。

有些朋友可能會好奇,這個 perfview 到底追蹤了多久,這個可以通過 TraceInfo 選項卡觀察,截圖如下:

從卦中可知,當前追蹤了 65s。

2. 路在何方

只知道在 kernelbase!WaitForSingleObject 上等待了10s并不能解決問題,那怎么辦呢?剛好朋友也給了我一份當時故障時的dump,這時候就要結合起來一起看,爭取找到突破口。

首先通過 ~*e k 尋找 TestRun 函數的調用棧,輸出如下:

...
0:011:x86> k# ChildEBP RetAddr      
00 0a1ef350 76a024e9     ntdll_77760000!NtWaitForSingleObject+0xc
01 0a1ef350 76a02442     KERNELBASE!WaitForSingleObjectEx+0x99
02 0a1ef364 594a13d8     KERNELBASE!WaitForSingleObject+0x12
WARNING: Stack unwind information not available. Following frames may be wrong.
03 0a1ef388 721d284d     gts!PvSplit+0x3b8
04 0a1ef3c0 06ead2f8     clr!PInvokeStackImbalanceHelper+0x22
05 0a1ef404 06c74476     System_Windows_Forms!DomainBoundILStubClass.IL_STUB_PInvoke(Int16, Int16, Int32 ByRef)+0x78
06 0a1ef4a8 66bad0ab     xxx!xxx.xxx+<>c__DisplayClass136_0.<TestRun>b__0()+0x10e
07 0a1ef4b4 66baa0b1     mscorlib_ni!System.Threading.Tasks.Task.InnerInvoke()+0x4b
08 0a1ef4d8 66baa07c     mscorlib_ni!System.Threading.Tasks.Task.Execute()+0x31
09 0a1ef540 66b48e34     mscorlib_ni!System.Threading.Tasks.Task.ExecutionContextCallback(System.Object)+0x1c
0a 0a1ef540 66b48d67     mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0xc4
...
1e 0a1efb5c 777c806e     ntdll_77760000!__RtlUserThreadStart+0x2f
...

從卦中數據看果然是在 event 事件上等待,使用 kb 5 觀察 event 參數,再使用 !handle 觀察。


0:011:x86> kb 5# ChildEBP RetAddr      Args to Child              
00 0a1ef350 76a024e9     00000818 00000000 00000000 ntdll_77760000!NtWaitForSingleObject+0xc
01 0a1ef350 76a02442     00000818 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x99
02 0a1ef364 594a13d8     00000818 ffffffff 0a1ef3ac KERNELBASE!WaitForSingleObject+0x12
WARNING: Stack unwind information not available. Following frames may be wrong.
03 0a1ef388 721d284d     00000001 00000002 0288a9c8 gts!PvSplit+0x3b8
04 0a1ef3c0 06ead2f8     00000001 00000002 0288a9c8 clr!PInvokeStackImbalanceHelper+0x220:011:x86> !handle 00000818f
Handle 0000818fType         	<Error retrieving type>
0:011:x86> !handle 00000818 f
Handle 00000818Type         	EventAttributes   	0GrantedAccess	0x1f0003:Delete,ReadControl,WriteDac,WriteOwner,SynchQueryState,ModifyStateHandleCount  	3PointerCount 	65540Name         	\BaseNamedObjects\MultiProcessObject specific informationEvent Type Auto ResetEvent is Waiting

從卦中可以看到當前是一個名為 \BaseNamedObjects\MultiProcess 的 AutoResetEvent 事件,正處于等待狀態,驗證了 perfview 的數據,那到底是在等待誰呢?

3. 在絕望中尋找希望

分析dump就是這樣,一步一個坎。。。所以不拋棄不放棄,因為這個程序是一個窗體程序,朋友又提到了卡死的關鍵詞,所以本能的想看看此時的主線程正在做什么,使用 ~0s ; k 命令。


0:000:x86> ~0s; k# ChildEBP RetAddr      
00 006fe638 76a024e9     ntdll_77760000!NtWaitForSingleObject+0xc
01 006fe638 76a02442     KERNELBASE!WaitForSingleObjectEx+0x99
02 006fe64c 75501328     KERNELBASE!WaitForSingleObject+0x12
WARNING: Stack unwind information not available. Following frames may be wrong.
03 006fe668 75544ac5     sysfer+0x1328
04 006fe878 755449c9     sysfer+0x44ac5
05 006fe910 755448ff     sysfer+0x449c9
06 006fe98c 75542ec6     sysfer+0x448ff
07 006fe9d0 777d324c     sysfer+0x42ec6
08 006fea30 76a1ac32     ntdll_77760000!NtSetInformationFile+0xc
09 006fea30 594a1bcc     KERNELBASE!SetFilePointer+0x72
0a 006fea54 594a1fff     gts!PvSplit+0xbac
0b 006fea68 5948164a     gts!PvSplit+0xfdf
0c 006fea88 59442e78     gts!GTN_SetHookSubModuleActive+0x70a
0d 006feaa4 721d284d     gts!GTN_GetDo+0x38
0e 006feadc 06ead2f8     clr!PInvokeStackImbalanceHelper+0x22
0f 006feb20 06ead89b     System_Windows_Forms!DomainBoundILStubClass.IL_STUB_PInvoke(Int16, Int16, Int32 ByRef)+0x78
10 006fec08 06eacfe6     xxx!xxx.xxx.CompareSts()+0x1eb
11 006fed6c 06eacb35     xxx!xxx.xxx.timerSts_Tick(System.Object, System.EventArgs)+0x49e
12 006fed80 06eac3ae     System_Windows_Forms!System.Windows.Forms.Timer.OnTick(System.EventArgs)+0x15
...

不看不知道,一看卦嚇一跳,除了剛才已經熟悉的 gts!PvSplit ,還發現了一個未知的 sysfer.dll ,這是啥玩意,一下子就提起了興趣,使用 lmvm sysfer 觀察。


0:000:x86> lmvm sysfer
Browse full module list
start    end        module name
75500000 7557e000   sysfer     (no symbols)           Loaded symbol image file: sysfer.dllImage path: C:\Windows\SysWOW64\sysfer.dllImage name: sysfer.dllBrowse all global symbols  functions  data  Symbol ReloadTimestamp:        Sat Apr 20 02:38:55 2019 (5CBA15BF)CheckSum:         0006E5AEImageSize:        0007E000File version:     14.2.3329.1000Product version:  14.2.3329.1000File flags:       0 (Mask 0)File OS:          40004 NT Win32File type:        1.0 AppFile date:        00000000.00000000Translations:     0409.04e4Information from resource tables:CompanyName:      Symantec CorporationProductName:      Symantec CMC FirewallInternalName:     sysferOriginalFilename: sysfer.dllProductVersion:   14.2.3329.1000FileVersion:      14.2.3329.1000FileDescription:  Symantec CMC Firewall sysferLegalCopyright:   Copyright (c) 2006-2019 Symantec Corporation. All rights reserved. Use of this product is subject to license terms.

Symantec CMC Firewall sysfer 來看,應該是賽門鐵克的一個 客戶端防火墻組件,再回頭看調用棧,大概就是 gts 在內部設置文件偏移指針(SetFilePointer) 的時候被 賽門鐵克 攔截了。

到這里基本上就弄清楚了卡死 10s 的來龍去脈,11號線程在 gts 中等待 0號線程 喚醒它的 event 事件。 而 0號線程不巧在設置文件指針的時候被 賽門鐵克 攔截了,在這攔截的10s內,導致 0 號線程沒有及時的喚醒 11 號線程所等待的事件,最終導致悲劇的發生。。。

三:總結

這次卡慢事故是由于 賽門鐵克 導致,其實殺毒軟件對我們程序來說真的是一個特別不穩定的因素,在我的分析旅程中,我見過殺毒軟件導致的崩潰,卡死,卡慢,內存泄露 等等奇葩情況,無語了。。。

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

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

相關文章

硬件知識積累 單片機+ 光耦 + 繼電器需要注意的地方

1. 電路圖 與其數值描述 1.1 單片機引腳信號為 OPtoCoupler_control_4 PC817SB 為 光耦 繼電器 SRD-05VDC-SL-A 的線圈電壓為 67Ω。 2. 需注意的地方 1. 單片機的推挽輸出的電流最大為 25mA 2. 注意光耦的 CTR 參數 3. 注意繼電器線圈的 內阻 4. 繼電器的開啟電壓。 因為光耦…

IP組播技術與internet

1.MAC地址分為三類&#xff1a;廣播地址&#xff1b;組播地址&#xff1b;單播地址 2.由一個源向一組主機發送信息的傳輸方式稱為組播。 3.組播MAC地址&#xff0c;第一個字節的最后一位為1&#xff1b; 單播MAC地址&#xff0c;第一個字節的最后一位為0&#xff1b; 4.不能…

vue3+vite+ts使用daisyui/tailwindcss

vite創建vue3腳手架 npm init vitelatest myVue3 – --template vue cd .\myVue3\ npm i npm run dev 安裝tailwindcss/daisyui 依賴安裝 npm install -D tailwindcss postcss autoprefixer daisyui npx tailwindcss init -p 這條命令將生成postcss.config.js(因為加了…

大數據(7)Kafka核心原理揭秘:從入門到企業級實戰應用

目錄 一、大數據時代的技術革命1.1 消息中間件演進史1.2 Kafka核心設計哲學 二、架構深度解構2.1 核心組件拓撲2.1.1 副本同步機制&#xff08;ISR&#xff09; 2.2 生產者黑科技2.3 消費者演進路線 三、企業級應用實戰3.1 金融行業實時風控3.2 物聯網數據管道 四、生產環境優化…

spring boot大文件與多文件下載

一、簡單大文件下載&#xff1a; /*** 下載大文件* param path 路徑* param fileName 文件名* return* throws IOException*/ public static ResponseEntity<InputStreamResource> downloadFile(String path, String fileName) throws IOException {Path filePath Path…

第二節:React 基礎篇-受控組件 vs 非受控組件

一、場景題&#xff1a;設計一個實時搜索輸入框&#xff0c;說明選擇依據 受控組件 vs 非受控組件 核心區別 特征受控組件非受控組件數據管理由React狀態&#xff08;state&#xff09;控制通過DOM元素&#xff08;ref&#xff09;直接訪問更新時機每次輸入觸發onChange提交…

局部路由守衛

局部路由守衛為我們提供了更細粒度的路由控制&#xff0c;允許我們在特定的路由或組件級別添加鑒權和邏輯處理。局部路由守衛分為 path 守衛和 component 守衛&#xff0c;它們分別適用于不同的場景。 path 守衛&#xff08;路由守衛&#xff09; path 守衛用于在進入特定路由…

Android 16應用適配指南

Android 16版本特性介紹 https://developer.android.com/about/versions/16?hlzh-cn Android 16 所有功能和 API 概覽 https://developer.android.com/about/versions/16/features?hlzh-cn#language-switching Android 16 發布時間 Android 16 適配指南 Google開發平臺&…

android display 筆記(十二)CPU,GPU,DPU的區別

CPU&#xff08;Central Processing Unit&#xff09;通用計算&#xff1a;處理復雜邏輯、分支預測、多任務調度。 低延遲&#xff1a;優先快速響應單線程任務。 GPU&#xff08;Graphics Processing Unit&#xff09; 高吞吐量并行計算&#xff1a;適合大規模數據并行處理。…

音頻轉文本:如何識別音頻成文字

Python腳本:MP4轉MP3并語音識別為中文 以下是一個完整的Python腳本,可以將MP4視頻轉換為MP3音頻,然后使用語音識別模型將音頻轉換為中文文本。 準備工作 首先需要安裝必要的庫: pip install moviepy pydub SpeechRecognition openai-whisper完整腳本 import os from m…

理解 MCP 協議的數據傳遞:HTTP 之上的一層“殼子

以下是以 CSDN 博客的風格記錄你對 MCP 協議數據傳遞的理解和發現&#xff0c;內容涵蓋了 MCP 協議基于 HTTP 的本質、JSON-RPC 的“殼子”作用&#xff0c;以及為什么熟悉 HTTP 協議就足以理解 MCP 的數據傳遞。文章面向技術社區&#xff0c;結構清晰&#xff0c;適合分享。 理…

基于ssm網絡游戲推薦系統(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 當今社會進入了科技進步、經濟社會快速發展的新時代。國際信息和學術交流也不斷加強&#xff0c;計算機技術對經濟社會發展和人民生活改善的影響也日益突出&#xff0c;人類的生存和思考方式也產生了變化。傳統網絡游戲管理采取了人工的管理方法&#xff0c;但這種管理方…

vue入門:指令

文章目錄 vue的內置指令說明&#xff1a; 自定義指令 vue的內置指令 Vue 指令的本質是&#xff1a; 聲明式的 DOM 操作接口&#xff08;隱藏底層 JavaScript 代碼&#xff09;。響應式數據的綁定媒介&#xff08;連接數據和視圖&#xff09;。模板編譯的標記&#xff08;最終…

oracle 索引失效

在 Oracle 11g 中&#xff0c;索引失效的常見原因包括函數修改列、隱式類型轉換、統計信息過時等&#xff0c;解決方法需結合版本特性&#xff08;如虛擬列、索引跳躍掃描&#xff09;。通過執行計劃分析、統計信息維護和合理使用提示&#xff08;Hints&#xff09;&#xff0c…

k8s藍綠發布

k8s藍綠發布 什么是藍綠部署K8S中如何實現藍綠部署k8s藍綠部署流程圖 什么是藍綠部署 參考: https://youtu.be/CLq_hA0lAd0 https://help.coding.net/docs/cd/best-practice/blue-green.html 藍綠部署最早是由馬丁福勒 2010年在他的博客中提出. 藍綠部署是一種軟件部署策略,用…

stm32面試

數據結構相關問題 stm32面試 數據結構相關問題 目錄基礎數據結構樹與圖排序與查找算法 Linux相關問題Linux系統基礎Linux命令與腳本Linux網絡與服務 操作系統相關問題操作系統基礎概念操作系統調度算法操作系統同步與通信 STM32相關問題STM32硬件基礎STM32編程與開發STM32應用與…

Mybatis 中 mappers標簽 package的使用

MyBatis 的配置文件中&#xff0c;<mappers> 標簽用于指定 MyBatis 應該加載哪些映射器&#xff08;Mapper&#xff09;。其中 package 屬性是一種便捷的方式來批量注冊多個映射器接口 package 屬性允許你指定一個包名&#xff0c;MyBatis 會自動掃描該包下的所有映射器…

設計模式 --- 訪問者模式

訪問者模式是一種行為設計模式&#xff0c;它允許在不改變對象結構的前提下&#xff0c;定義作用于這些對象元素的新操作。 優點&#xff1a; 1.??符合開閉原則&#xff1a;新增操作只需添加新的訪問者類&#xff0c;無需修改現有對象結構。 ??2.操作邏輯集中管理??&am…

監控docker中的java應用

1)進入指定的容器 docker exec -it demo /bin/bash 2)下載curl root89a67e345354:/# apt install curl -y 3)下載arthas root89a67e345354:/# curl -O https://arthas.aliyun.com/arthas-boot.jar 4)運行 root89a67e345354:/# java -jar arthas-boot.jar 5)監控 […

最新版RubyMine超詳細圖文安裝教程,帶補丁包(2025最新版保姆級教程)

目錄 前言 一、RubyMine最新版下載 二、RubyMine安裝 三、RubyMine補丁 四、運行RubyMine 前言 RubyMine是由JetBrains開發的集成開發環境&#xff08;IDE&#xff09;&#xff0c;專為Ruby和Ruby on Rails開發者設計&#xff0c;提供智能代碼補全、調試、測試、版本控制集…