操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    微軟原定于5月28日向普通用戶推送Windows10 v2004版,也就是五月更新版。想必很多人已經躍躍欲試,迫不及待的想要嘗試新的系統。

    Windows v2004版,改進了機械硬盤的性能表現,可以在任務管理器中查看顯卡的溫度,虛擬桌面重命名,更新限速,云下載和云重裝等。我來簡單說一下,升級安裝優化攻略。

    升級系統

    升級系統,好處毋庸置疑,保留用戶的文件和大部分應用程序,免去了重新安裝后再次配置應用環境的麻煩。壞處嘛,如果用戶的系統環境復雜,可能會帶來一些莫名其妙的后遺癥。筆者升級清理后,磁盤空間占用沒有增加多少,使用效果不錯,值得升級。

    升級方法有兩種:

    第一種,在5月28日后,微軟對用戶推送,在更新處手動升級。不用多說,大家都懂。

    Windows更新

    第二種,下載在MSDN放出的鏡像,解壓縮在C盤以外的空間,直接執行 setup.exe 。筆者是更新選擇保留文件后,就去睡覺了。第二天早晨,電腦都已經升級好了,只是空間略大,漲到40G左右。升級后,可以在一定時間內恢復到上一個版本,系統會保留舊的文件備份,不被磁盤清理刪除的。

    全新安裝

    U盤安裝

    現在放出的鏡像很大,有5G多,用4GU盤是容納不下的。也許等5月28日放出的消費版體積會減小(希望不大),制作安裝U盤至少8G。使用Rufus 刻錄鏡像到U盤,鏡像選擇,可以選“標準Windows安裝”和“Windows to go”,我們這里選標準Windows安裝。分區類型有GPT和MBR,根據情況選擇,現在主板都支持uefi,所以選GPT。 GPT沒有4個主分區的限制。設置BIOS或者EFI從USB啟動,即可安裝。

    PE安裝

    一般的PE安裝是把U盤做成PE啟動環境,在PE環境中執行安裝。此種方法,比U盤安裝節約U盤空間,安裝時使用PE環境的安裝工具。實際,我們可以把PE安裝到本地硬盤,省去制作U盤的步驟,也算在沒有U盤的情況下圍魏救趙的辦法。

    把PE安裝到本地

    在PE中先把Windows安裝鏡像裝載到虛擬光驅,找到“WinNTSetup”這個程序。在程序中依次選擇,安裝源(虛擬光驅中sources中的install鏡像),引導分區(gpt模式下為EFI分區),系統分區,安裝操作系統版本等。操作過程如圖。

    系統優化

    必裝組件:.Netframe 3.5 ,VC運行庫。VC庫可以搜索下載。

    本地安裝 .Netframe 3.5,其中X:為裝載安裝鏡像虛擬光驅盤符。

    dism.exe /online /enable-feature /featurename:NetFX3 /All /Source:X:\Sources\sxs /LimitAccess

    關閉Windows更新,都知道Windows10 有著 Bug10的美譽。常規方法,打開服務……其實,我在這里介紹一個軟件就可以。

    Windows Update Blocker

    好了,筆者裝系統就是這么做的。有更好的方法,歡迎大家留言討論,不吝給個贊吧。

    一、簡介
        今天是《Net 高級調試》的第七篇文章。上一篇文章我們說了值類型,引用類型,數組等的內存表現形式。有了這個基礎,我們可以更好的了解我們的程序在運行時的狀態,內存里有什么東西,它們的結構組成是什么樣子的,對我們調試程序是更有幫助的。今天,我們要說一些和線程有關的話題,雖然和線程相關,但是不是多線程的知識,不是線程安全的知識。今天我們討論的是如何查看線程,它的表現形式,以及線程的調用棧,調用棧,又分為托管線程的調用棧和非托管線程的調用棧,這些也是我們高級調試必須掌握的。有了這些基礎,我們就知道了程序的開始端點,調試的起點我們就找到了。雖然這些都是基礎,如果這些掌握不好,以后的高級調試的道路,也不好走。當然了,第一次看視頻或者看書,是很迷糊的,不知道如何操作,還是那句老話,一遍不行,那就再來一遍,還不行,那就再來一遍,俗話說的好,書讀千遍,其意自現。
         如果在沒有說明的情況下,所有代碼的測試環境都是 Net Framewok 4.8,但是,有時候為了查看源碼,可能需要使用 Net Core 的項目,我會在項目章節里進行說明。好了,廢話不多說,開始我們今天的調試工作。

        
    調試環境我需要進行說明,以防大家不清楚,具體情況我已經羅列出來。
              
    操作系統:Windows Professional 10
              調試工具:Windbg Preview(可以去Microsoft Store 去下載)
              開發工具:Visual Studio 2022
              Net 版本:Net Framework 4.8
              CoreCLR源碼:源碼下載

    二、基礎知識
        
        
    1、線程類相關介紹
            
    1.1、簡介
                在高級調試的過程中,很難不和 線程、線程棧 打交道,所以好好的學習并掌握有關線程操作的命令是很有必要的。

        
    2、獲取 線程列表 的命令
            
    2.1、查看線程列表。
                可以使用【!t】命令獲取所有的托管線程。

            
    2.2、使用 Net 7.0 查看線程列表
                可以使用【!t】命令獲取所有的托管線程,如果我們想查看 CLR 的線程對象的結構就只能使用開源版本了,這里使用Net 7.0。

        
    3、查看非托管線程棧
            Windbg 是隨 Windows 成長起來的非托管調試器,它自帶的命令只能查看非托管調用棧,因為 C# 中的線程棧是托管函數,而托管函數是一種運行時編譯的,所以這個命令往往看不到托管部分。

            
    3.1、使用 k 命令查看非托管線程棧
                【k】命令可以查看線程棧,但是么有辦法展示托管函數,作為補充,可以使用【!clrstack】命令。

            
    3.2、使用 kb 命令查看線程棧。
                很多時候我們需要獲取非托管函數的參數,這個時候我們可以使用【kb】命令。

            
    3.3、查看托管函數棧
                SOS 提供了一個專門查看托管函數調用棧的命令,畢竟只有 JIT更熟悉托管函數,也知道編譯后的機器碼放在什么位置。
                這個命令就是【!clrstack】。
                !clrstack -a:這個命令表示將線程棧中的所有局部變量和參數全部輸出。
                !clrstack -p:這個命令表示將線程棧中的參數全部輸出。
                !clrstack -l:這個命令表示將線程棧中的所有局部變量全部輸出。

                我們還可以查看所有托管線程棧,可以使用【~*e】命令。

            
    3.4、查看托管和非托管合體
                使用【!dumpstack】命令查看托管和非托管的線程棧


            
    3.5、執行所有線程的 DumpStack。
                如果我們想查看所有線程的線程棧,可以使用【!EEStack】,也可以使用【~*e !dumpstack】,結果是一樣的。
    三、測試過程
        廢話不多說,這一節是具體的調試操作的過程,又可以說是眼見為實的過程,在開始之前,我還是要啰嗦兩句,這一節分為兩個部分,第一部分是測試的源碼部分,沒有代碼,當然就談不上測試了,調試必須有載體。第二部分就是根據具體的代碼來證實我們學到的知識,是具體的眼見為實。

        
    1、測試源碼
            1.1、Example_7_1_1

     1 namespace Example_7_1_1
     2 {
     3     internal class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             int a = 10;
     8             int b = 11;
     9             Test(12);
    10             Console.ReadLine();
    11         }
    12 
    13         private static void Test(int c)
    14         {
    15             Task.Run(() => { Run1(); });
    16             Task.Run(() => { Run2(); });
    17             Task.Run(() => { Run3(); });
    18         }
    19 
    20         private static void Run1()
    21         {
    22             Console.WriteLine($"tid={Environment.CurrentManagedThreadId},Run1 正在運行");
    23             Console.ReadLine();
    24             Console.WriteLine($"tid={Environment.CurrentManagedThreadId},Run1 結束運行");
    25         }
    26 
    27         private static void Run2()
    28         {
    29             Console.WriteLine($"tid={Environment.CurrentManagedThreadId},Run2 正在運行");
    30             Console.ReadLine();
    31             Console.WriteLine($"tid={Environment.CurrentManagedThreadId},Run2 結束運行");
    32         }
    33 
    34         private static void Run3()
    35         {
    36             Console.WriteLine($"tid={Environment.CurrentManagedThreadId},Run3 正在運行");
    37             Console.ReadLine();
    38             Console.WriteLine($"tid={Environment.CurrentManagedThreadId},Run3 結束運行");
    39         }
    40     }
    41 }


            1.2、Example_7_1_2(特別說明,這個項目是 Net 7.0)

     1 namespace Example_7_1_2
     2 {
     3     internal class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             Console.WriteLine("Hello, World!");
     8             Debugger.Break();
     9         }
    10     }
    11 }


        
    2、眼見為實
            項目的所有操作都是一樣的,所以就在這里說明一下,但是每個測試例子,都需要重新啟動,并加載相應的應用程序,加載方法都是一樣的。流程如下:我們編譯項目,打開 Windbg,點擊【文件】----》【launch executable】附加程序,打開調試器的界面,程序已經處于中斷狀態。我們需要使用【g】命令,繼續運行程序,然后到達指定地點停止后,我們可以點擊【break】按鈕,就可以調試程序了。有時候可能需要切換到主線程,可以使用【~0s】命令。

            
    2.1、使用 【!t】命令查看進程中有多少個托管線程。
                  
    測試源碼:Example_7_1_1

     1 0:012> !t
     2 ThreadCount:      6
     3 UnstartedThread:  0
     4 BackgroundThread: 5
     5 PendingThread:    0
     6 DeadThread:       0
     7 Hosted Runtime:   no
     8                                                                          Lock  
     9        ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
    10    0    1 2ef4 00c73930     2a020 Preemptive  02B94F38:00000000 00c6d758 1     MTA 
    11    5    2 39c0 00cb0728     2b220 Preemptive  00000000:00000000 00c6d758 0     MTA (Finalizer) 
    12    9    3 17dc 00cdc010   3029220 Preemptive  02B9C6C8:00000000 00c6d758 0     MTA (Threadpool Worker) 
    13   10    4  a18 00cdc9b8   3029220 Preemptive  02B98350:00000000 00c6d758 0     MTA (Threadpool Worker) 
    14   11    5 31d0 00cdd360   3029220 Preemptive  02B9A350:00000000 00c6d758 0     MTA (Threadpool Worker) 
    15   13    6  9a0 00ce05c0   1029220 Preemptive  02B9E1E8:00000000 00c6d758 0     MTA (Threadpool Worker) 

                  ThreadCount:有多少個托管線程,這個進程里面有6個。
                  UnstartedThread:已經創建,但是還沒有使用的線程,當前數量是0。
                  BackgroundThread:后臺線程的數量,這個進程里面有5個。
                  PendingThread:阻塞的線程的數量,當前這個進程是0個阻塞的線程。
                  DeadThread:當一個線程完成任務,但是還沒有被回收,這個階段的線程就是死線程,也就是說這個線程對象底層的數據結構的 OSID 已經銷毀。

                  以上就是介紹的主要名稱,下面接著介紹,列表的每一項。我們使用 C# Thread 類型聲明一個線程的時候,其實在操作系統和CLR都有一個數據結構相對應,有了 OSID我們才可以在任務管理器中看到線程對象。

                  第一列,沒有標題,是 WindbgThreadId,Windbg 自己的給 Thread 打了一個標記,便于以后使用,也可以區分托管線程和非托管線程。
                  第二列
    ID:是托管線程,也就是我們 Thread 類型的標識符 Id,就是 這段代碼的值:Environment.CurrentManagedThreadId
                  第三列 OSID:操作系統線程的 ID,
                  第四列 ThreadOBJ:CLR 底層的 Thread 線程對象,可以使用【dp】命令觀察其中的內容,我們查看托管線程 ID=3 的【00cdc010】內容,紅色標注就是托管線程的ID,就是3。

    1 0:012> dp 00cdc010
    2 00cdc010  72074bd4 03029220 00000000 055ff680
    3 00cdc020  00000000 00c6d758 00000000 00000003
    4 00cdc030  00cdc034 00cdc034 00cdc034 00000000
    5 00cdc040  00000000 baad0000 00c6ed50 0094f000
    6 00cdc050  02b9c6c8 02b9dfe8 00003d10 00000000
    7 00cdc060  00000000 00000000 00000000 00000000
    8 00cdc070  00000000 baadf00d 70ad2c60 00cdc850
    9 00cdc080  00000000 00000000 00000000 00000000


                   第五列 State:CLR 層面的線程狀態,
    03029220 就是托管線程的狀態。我們可以點進去或者使用【!threadstate】命令查看線程狀態詳情,當前就是托管線程是3的狀態。

    1 0:012> !ThreadState 3029220
    2     Legal to Join(可以執行 join 操作)
    3     Background(是后臺線程)
    4     CLR Owns(是CLR 擁有的線程)
    5     In Multi Threaded Apartment(是MTA模式)
    6     Fully initialized(已經完全初始化)
    7     Thread Pool Worker Thread(是線程池線程)
    8     Interruptible(可執行中斷操作)


                  第六列 GC Mode:表示當前的線程有沒有操作托管堆的權限。
                  第七列 GC Alloc Context:緩沖區的開始節點和結束節點,每個線程在托管堆中分配一個對象,都有一個緩沖區,這個就是確定了緩沖區起始和結束。
                  第八列 Domain:表示當前線程所屬于的域。
                  第九列 Lock Count:表示當前的線程有多少個托管鎖。
                  第十列 Apt:表示線程是 STA(線程串行模式,WPF、WinForm) 模式還是 MTA (多線程并行模式)模式。
                  第十一列 Exception:在當前線程上發生了異常,會把這個異常和這個線程關聯起來。
                  Finalizer 表示當前是終結器線程,Threadpool Worker 表示線程是線程池的線程。

            2.2、如何查看 CLR Thread 的結構,也就是查看 ThreadOBJ 的結構。
                  測試源碼:Example_7_1_2(Net 7.0項目
                  如果我們想在 Net Framework 環境下查看 CLR 線程對象的結構是很難的,因為他是不開源的,所以我們只能新建 Net 7.0 的項目。
                  輸出所有的線程列表。

     1 0:000> !t
     2 ThreadCount:      3
     3 UnstartedThread:  0
     4 BackgroundThread: 2
     5 PendingThread:    0
     6 DeadThread:       0
     7 Hosted Runtime:   no
     8                                                                                                             Lock  
     9  DBG   ID     OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception
    10    0    1      624 00000199DFD0CAE0    2a020 Preemptive  00000199E440AD60:00000199E440C750 00000199dfd02dd0 -00001 MTA 
    11    5    2     1344 00000199DFD51DD0    21220 Preemptive  0000000000000000:0000000000000000 00000199dfd02dd0 -00001 Ukn (Finalizer) 
    12    6    3     3b40 000001DA763B15E0    2b220 Preemptive  0000000000000000:0000000000000000 00000199dfd02dd0 -00001 MTA 

                  然后,我們使用【dt】命令,查看線程的結構。

      1 0:000> dt coreclr!Thread 00000199DFD0CAE0
      2    +0x000 m_stackLocalAllocator : (null) 
      3    =00007ffd`027a8af0 m_DetachCount    : 0n0
      4    =00007ffd`027a8af4 m_ActiveDetachCount : 0n0
      5    +0x008 m_State          : Volatile<enum Thread::ThreadState>
      6    +0x00c m_fPreemptiveGCDisabled : Volatile<unsigned long>
      7    +0x010 m_pFrame         : 0x0000008a`24f7e478 Frame
      8    +0x018 m_pDomain        : 0x00000199`dfd02dd0 AppDomain
      9    +0x020 m_ThreadId       : 1
     10    +0x028 m_pHead          : 0x00000199`dfd0cb10 LockEntry
     11    +0x030 m_embeddedEntry  : LockEntry
     12    +0x050 m_pBlockingLock  : VolatilePtr<DeadlockAwareLock,DeadlockAwareLock *>
     13    +0x058 m_alloc_context  : gc_alloc_context
     14    +0x090 m_thAllocContextObj : TypeHandle
     15    +0x098 m_pTEB           : 0x0000008a`24c20000 _NT_TIB
     16    +0x0a0 m_pRCWStack      : 0x00000199`dfd0d710 RCWStackHeader
     17    +0x0a8 m_ThreadTasks    : 0 (No matching name)
     18    +0x0ac m_StateNC        : 100 ( TSNC_ExistInThreadStore )
     19    +0x0b0 m_dwForbidSuspendThread : Volatile<long>
     20    +0x0b4 m_dwHashCodeSeed : 0xdfca504a
     21    +0x0b8 m_pLoadLimiter   : (null) 
     22    +0x0c0 m_AbortType      : 0
     23    +0x0c8 m_AbortEndTime   : 0xffffffff`ffffffff
     24    +0x0d0 m_RudeAbortEndTime : 0xffffffff`ffffffff
     25    +0x0d8 m_fRudeAbortInitiated : 0n0
     26    +0x0dc m_AbortController : 0n0
     27    +0x0e0 m_AbortRequestLock : 0n0
     28    +0x0e4 m_ThrewControlForThread : 0
     29    +0x0e8 m_OSContext      : 0x00000199`dfd0d210 _CONTEXT
     30    +0x0f0 m_pPendingTypeLoad : (null) 
     31    +0x0f8 m_Link           : SLink
     32    +0x100 m_dwLastError    : 0
     33    +0x108 m_CacheStackBase : 0x0000008a`24f80000 Void
     34    +0x110 m_CacheStackLimit : 0x0000008a`24e00000 Void
     35    +0x118 m_CacheStackSufficientExecutionLimit : 0x0000008a`24e20000
     36    +0x120 m_CacheStackStackAllocNonRiskyExecutionLimit : 0x0000008a`24e80000
     37    +0x128 m_pvHJRetAddr    : 0xcccccccc`cccccccc Void
     38    +0x130 m_ppvHJRetAddrPtr : 0xcccccccc`cccccccc  -> ???? 
     39    +0x138 m_HijackedFunction : 0xbaadf00d`baadf00d MethodDesc
     40    +0x140 m_UserInterrupt  : 0n0
     41    +0x148 m_DebugSuspendEvent : CLREvent
     42    +0x158 m_EventWait      : CLREvent
     43    +0x168 m_WaitEventLink  : WaitEventLink
     44    +0x198 m_ThreadHandle   : 0x00000000`000001e0 Void
     45    +0x1a0 m_ThreadHandleForClose : 0xffffffff`ffffffff Void
     46    +0x1a8 m_ThreadHandleForResume : 0xffffffff`ffffffff Void
     47    +0x1b0 m_WeOwnThreadHandle : 0n1
     48    +0x1b8 m_OSThreadId     : 0x624
     49    +0x1c0 m_ExposedObject  : 0x00000199`dfc411f8 OBJECTHANDLE__
     50    +0x1c8 m_StrongHndToExposedObject : 0x00000199`dfc413f8 OBJECTHANDLE__
     51    +0x1d0 m_Priority       : 0x80000000
     52    +0x1d4 m_ExternalRefCount : 1
     53    +0x1d8 m_TraceCallCount : 0n0
     54    +0x1e0 m_LastThrownObjectHandle : (null) 
     55    +0x1e8 m_ltoIsUnhandled : 0n0
     56    +0x1f0 m_ExceptionState : ThreadExceptionState
     57    +0x398 m_debuggerFilterContext : (null) 
     58    +0x3a0 m_pProfilerFilterContext : (null) 
     59    +0x3a8 m_hijackLock     : Volatile<long>
     60    +0x3b0 m_hCurrNotification : 0xbaadf00d`baadf00d OBJECTHANDLE__
     61    +0x3b8 m_fInteropDebuggingHijacked : 0n0
     62    +0x3bc m_profilerCallbackState : 0
     63    +0x3c0 m_dwProfilerEvacuationCounters : [33] Volatile<unsigned long>
     64    +0x444 m_workerThreadPoolCompletionCount : 0
     65    =00007ffd`027b3cc0 s_workerThreadPoolCompletionCountOverflow : 0
     66    +0x448 m_ioThreadPoolCompletionCount : 0
     67    =00007ffd`027b3cc8 s_ioThreadPoolCompletionCountOverflow : 0
     68    +0x44c m_monitorLockContentionCount : 0
     69    =00007ffd`027a8ad8 s_monitorLockContentionCountOverflow : 0
     70    +0x450 m_PreventAsync   : 0n0
     71    =00007ffd`027a6204 m_DebugWillSyncCount : 0n-1
     72    +0x458 m_pSavedRedirectContext : (null) 
     73    +0x460 m_pOSContextBuffer : (null) 
     74    +0x468 m_ThreadLocalBlock : ThreadLocalBlock
     75    +0x490 m_tailCallTls    : TailCallTls
     76    +0x4a0 m_dwAVInRuntimeImplOkayCount : 0
     77    +0x4a8 m_pExceptionDuringStartup : (null) 
     78    +0x4b0 m_debuggerActivePatchSkipper : VolatilePtr<DebuggerPatchSkip,DebuggerPatchSkip *>
     79    +0x4b8 m_fAllowProfilerCallbacks : 0n1
     80    +0x4c0 m_pIOCompletionContext : 0x00000199`dfd0da40 Void
     81    +0x4c8 m_dwThreadHandleBeingUsed : Volatile<long>
     82    =00007ffd`027a8ad0 s_fCleanFinalizedThread : 0n0
     83    +0x4d0 m_pCreatingThrowableForException : (null) 
     84    +0x4d8 m_dwIndexClauseForCatch : 0
     85    +0x4e0 m_sfEstablisherOfActualHandlerFrame : StackFrame
     86    +0x4e8 DebugBlockingInfo : ThreadDebugBlockingInfo
     87    +0x4f0 m_fDisableComObjectEagerCleanup : 0
     88    +0x4f1 m_fHasDeadThreadBeenConsideredForGCTrigger : 0
     89    +0x4f4 m_random         : CLRRandom
     90    +0x5e0 m_uliInitializeSpyCookie : _ULARGE_INTEGER 0x0
     91    +0x5e8 m_fInitializeSpyRegistered : 0
     92    +0x5f0 m_pLastSTACtxCookie : (null) 
     93    +0x5f8 m_fGCSpecial     : 0
     94    +0x600 m_pGCFrame       : 0x0000008a`24f7e790 GCFrame
     95    +0x608 m_wCPUGroup      : 0
     96    +0x610 m_pAffinityMask  : 0
     97    +0x618 m_pAllLoggedTypes : (null) 
     98    +0x620 m_gcModeOnSuspension : Volatile<unsigned long>
     99    +0x624 m_activityId     : _GUID {00000000-0000-0000-0000-000000000000}
    100    +0x634 m_HijackReturnKind : ff ( RT_Illegal )
    101    =00007ffd`027a8b40 dead_threads_non_alloc_bytes : 0
    102    +0x638 m_currentPrepareCodeConfig : (null) 
    103    +0x640 m_isInForbidSuspendForDebuggerRegion : 0
    104    =00007ffd`027ba3d0 s_pfnQueueUserAPC2Proc : (null) 
    105    +0x641 m_hasPendingActivation : 0

                  +0x020 m_ThreadId : 1表示托管線程的ID。因為我打印的是 ThreadOBJ 為00000199DFD0CAE0 線程的結構。m 表示Management 托管的。
                  我們可以繼續看看 GC Alloc Context,在輸出的結構中有這樣一行代碼:+0x058 m_alloc_context : gc_alloc_context,藍色的字體,可以點擊,相當于執行【dx】命令。

    1 0:000> dx -r1 (*((coreclr!gc_alloc_context *)0x199dfd0cb38))
    2 (*((coreclr!gc_alloc_context *)0x199dfd0cb38))                 [Type: gc_alloc_context]
    3     [+0x000] alloc_ptr        : 0x199e440ad60 : 0x0 [Type: unsigned char *]
    4     [+0x008] alloc_limit      : 0x199e440c750 : 0x0 [Type: unsigned char *]
    5     [+0x010] alloc_bytes      : 50920 [Type: __int64](小對象堆的大小)
    6     [+0x018] alloc_bytes_uoh  : 17416 [Type: __int64](大對象堆的大小)
    7     [+0x020] gc_reserved_1    : 0x0 [Type: void *]
    8     [+0x028] gc_reserved_2    : 0x0 [Type: void *]
    9     [+0x030] alloc_count      : 0 [Type: int]


            
    2.3、使用 Windbg 的【k】命令查看非托管函數。
                  測試源碼:Example_7_1_1
                  這里操作需要切換到主線程上,執行命令【~0s】,然后使用【k】命令。

     1 0:010> ~0s
     2 eax=00000000 ebx=00000090 ecx=00000000 edx=00000000 esi=00f3f444 edi=00000000
     3 eip=77c310fc esp=00f3f32c ebp=00f3f38c iopl=0         nv up ei pl nz na po nc
     4 cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
     5 ntdll!NtReadFile+0xc:
     6 77c310fc c22400          ret     24h
     7 
     8 
     9 0:000> k
    10  # ChildEBP RetAddr      
    11 00 00f3f38c 75dbf25c     ntdll!NtReadFile+0xc
    12 01 00f3f38c 70f79b71     KERNELBASE!ReadFile+0xec
    13 02 00f3f3fc 716ab275     mscorlib_ni+0x4b9b71
    14 03 00f3f428 716ab17b     ...
    15 WARNING: Frame IP not in any known module. Following frames may be wrong.(無法顯示托管函數)
    16 09 00f3f4b8 71faf036     0x2e9088e
    17 0a 00f3f4c4 71fb22da     clr!CallDescrWorkerInternal+0x34
    18 0b 00f3f518 71fb859b     clr!CallDescrWorkerWithHandler+0x6b
    19 0c 00f3f588 7215b11b     clr!MethodDescCallSite::CallTargetWorker+0x16a
    20 0d 00f3f6ac 7215b7fa     clr!RunMain+0x1b3
    21 0e 00f3f918 7215b727     clr!Assembly::ExecuteMainMethod+0xf7
    22 0f 00f3fdfc 7215b8a8     clr!SystemDomain::ExecuteMainMethod+0x5ef
    23 10 00f3fe54 7215b9ce     clr!ExecuteEXE+0x4c
    24 11 00f3fe94 72157305     clr!_CorExeMainInternal+0xdc
    25 12 00f3fed0 7275fa84     clr!_CorExeMain+0x4d
    26 13 00f3ff08 7285e81e     mscoreei!_CorExeMain+0xd6
    27 14 00f3ff18 72864338     MSCOREE!ShellShim__CorExeMain+0x9e
    28 15 00f3ff30 7636f989     MSCOREE!_CorExeMain_Exported+0x8
    29 16 00f3ff30 77c27084     KERNEL32!BaseThreadInitThunk+0x19
    30 17 00f3ff8c 77c27054     ntdll!__RtlUserThreadStart+0x2f
    31 18 00f3ff9c 00000000     ntdll!_RtlUserThreadStart+0x1b

                  但是我們可以使用 SOS的【!clrstack】命令顯示托管函數。

     1 0:000> !clrstack
     2 OS Thread Id: 0xc08 (0)
     3 Child SP       IP Call Site
     4 00f3f3ac 77c310fc [InlinedCallFrame: 00f3f3ac] 
     5 00f3f3a8 70f79b71 DomainNeutralILStubClass.IL_STUB_PInvoke(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)
     6 00f3f3ac 716ab275 [InlinedCallFrame: 00f3f3ac] Microsoft.Win32.Win32Native.ReadFile(..., Int32, Int32 ByRef, IntPtr)
     7 00f3f410 716ab275 System.IO.__ConsoleStream.ReadFileNative(.., Int32 ByRef) [f:\dd\ndp\clr\src\BCL\system\io\__consolestream.cs @ 205]
     8 00f3f444 716ab17b System.IO.__ConsoleStream.Read(Byte[], Int32, Int32) [f:\dd\ndp\clr\src\BCL\system\io\__consolestream.cs @ 134]
     9 00f3f464 70f5e6a3 System.IO.StreamReader.ReadBuffer() [f:\dd\ndp\clr\src\BCL\system\io\streamreader.cs @ 595]
    10 00f3f474 70f5eb5b System.IO.StreamReader.ReadLine() [f:\dd\ndp\clr\src\BCL\system\io\streamreader.cs @ 748]
    11 00f3f490 717f3786 System.IO.TextReader+SyncTextReader.ReadLine() [f:\dd\ndp\clr\src\BCL\system\io\textreader.cs @ 363]
    12 00f3f4a0 71651845 System.Console.ReadLine() [f:\dd\ndp\clr\src\BCL\system\console.cs @ 1984]
    13 00f3f4a8 02e9088e Example_7_1_1.Program.Main(System.String[]) [E:\Visual Studio 2022\...\Example_7_1_1\Program.cs @ 13]
    14 00f3f62c 71faf036 [GCFrame: 00f3f62c] 


            
    2.4、使用【kb】命令查看線程棧,提取 ntdll!NtReadFile 的第一個參數。
                  測試源碼:Example_7_1_1              

     1 0:000> kb
     2  # ChildEBP RetAddr      Args to Child              
     3 00 00f3f38c 75dbf25c     00000090 00000000 00000000 ntdll!NtReadFile+0xc
     4 01 00f3f38c 70f79b71     00000090 02f35d18 00000100 KERNELBASE!ReadFile+0xec
     5 02 00f3f3fc 716ab275     00000000 00f3f444 00000100 mscorlib_ni+0x4b9b71
     6 03 00f3f428 716ab17b     00f3f444 00000000 00000001 mscorlib_ni!System.IO.__ConsoleStream.ReadFileNative+0x89 [f:\dd\ndp\clr\src\BCL\system\io\__consolestream.cs @ 205] 
     7 04 00f3f454 70f5e6a3     00000100 00000000 02f3a210 mscorlib_ni!System.IO.__ConsoleStream.Read+0x9f [f:\dd\ndp\clr\src\BCL\system\io\__consolestream.cs @ 134] 
     8 05 00f3f46c 70f5eb5b     00000001 00000000 00f3f55c mscorlib_ni!System.IO.StreamReader.ReadBuffer+0x33 [f:\dd\ndp\clr\src\BCL\system\io\streamreader.cs @ 595] 
     9 06 00f3f488 717f3786     00000000 00f3f4d0 00f3f4a0 mscorlib_ni!System.IO.StreamReader.ReadLine+0xe3 [f:\dd\ndp\clr\src\BCL\system\io\streamreader.cs @ 748] 
    10 07 00f3f498 71651845     00f3f4b8 02e9088e 00000000 mscorlib_ni!System.IO.TextReader.SyncTextReader.ReadLine+0x1a [f:\dd\ndp\clr\src\BCL\system\io\textreader.cs @ 363] 
    11 08 00f3f4a0 02e9088e     00000000 0000000b 0000000a mscorlib_ni!System.Console.ReadLine+0x15 [f:\dd\ndp\clr\src\BCL\system\console.cs @ 1984] 
    12 WARNING: Frame IP not in any known module. Following frames may be wrong.
    13 09 00f3f4b8 71faf036     0116a628 00f3f518 71fb22da 0x2e9088e
    14 0a 00f3f4c4 71fb22da     00f3f55c 00f3f508 720a23d0 clr!CallDescrWorkerInternal+0x34
    15 0b 00f3f518 71fb859b     00f3f570 02f324bc 00000000 clr!CallDescrWorkerWithHandler+0x6b
    16 0c 00f3f588 7215b11b     00f3f664 6a38df42 02d04d78 clr!MethodDescCallSite::CallTargetWorker+0x16a
    17 0d 00f3f6ac 7215b7fa     00f3f6f0 00000000 6a38d0f6 clr!RunMain+0x1b3
    18 0e 00f3f918 7215b727     00000000 6a38d412 00b70000 clr!Assembly::ExecuteMainMethod+0xf7
    19 0f 00f3fdfc 7215b8a8     6a38d7ba 00000000 00000000 clr!SystemDomain::ExecuteMainMethod+0x5ef
    20 10 00f3fe54 7215b9ce     6a38d77a 00000000 721572e0 clr!ExecuteEXE+0x4c
    21 11 00f3fe94 72157305     6a38d73e 00000000 721572e0 clr!_CorExeMainInternal+0xdc
    22 12 00f3fed0 7275fa84     8ee8ef1f 72864330 7275fa20 clr!_CorExeMain+0x4d
    23 13 00f3ff08 7285e81e     72864330 72750000 00f3ff30 mscoreei!_CorExeMain+0xd6
    24 14 00f3ff18 72864338     72864330 7636f989 00c95000 MSCOREE!ShellShim__CorExeMain+0x9e
    25 15 00f3ff30 7636f989     00c95000 7636f970 00f3ff8c MSCOREE!_CorExeMain_Exported+0x8
    26 16 00f3ff30 77c27084     00c95000 281a60a3 00000000 KERNEL32!BaseThreadInitThunk+0x19
    27 17 00f3ff8c 77c27054     ffffffff 77c462ae 00000000 ntdll!__RtlUserThreadStart+0x2f
    28 18 00f3ff9c 00000000     00000000 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b

                  ntdll!NtReadFile 方法的第一個參數是一個 Handle,我們可以使用【!handle】命令+ f 參數顯示詳情。Console.ReadLine()方法底層就是 File 的句柄。

     1 0:000> !handle 00000090 f
     2 Handle 90
     3   Type             File
     4   Attributes       0
     5   GrantedAccess    0x12019f:
     6          ReadControl,Synch
     7          Read/List,Write/Add,Append/SubDir/CreatePipe,ReadEA,WriteEA,ReadAttr,WriteAttr
     8   HandleCount      2
     9   PointerCount     65531
    10   No Object Specific Information available


            
    2.5、我們使用【!clrstack】命令查看托管函數。
                  測試源碼:Example_7_1_1
                  !clrstack 執行效果

     1 0:000> !clrstack
     2 OS Thread Id: 0xc08 (0)
     3 Child SP       IP Call Site
     4 00f3f3ac 77c310fc [InlinedCallFrame: 00f3f3ac] 
     5 00f3f3a8 70f79b71 DomainNeutralILStubClass.IL_STUB_PInvoke(..., Byte*, Int32, Int32 ByRef, IntPtr)
     6 00f3f3ac 716ab275 [InlinedCallFrame: 00f3f3ac] Microsoft.Win32.Win32Native.ReadFile(... Byte*, Int32, Int32 ByRef, IntPtr)
     7 00f3f410 716ab275 System.IO.__ConsoleStream.ReadFileNative(.. Int32 ByRef) [f:\dd\ndp\clr\src\BCL\system\io\__consolestream.cs @ 205]
     8 00f3f444 716ab17b System.IO.__ConsoleStream.Read(Byte[], Int32, Int32) [f:\dd\ndp\clr\src\BCL\system\io\__consolestream.cs @ 134]
     9 00f3f464 70f5e6a3 System.IO.StreamReader.ReadBuffer() [f:\dd\ndp\clr\src\BCL\system\io\streamreader.cs @ 595]
    10 00f3f474 70f5eb5b System.IO.StreamReader.ReadLine() [f:\dd\ndp\clr\src\BCL\system\io\streamreader.cs @ 748]
    11 00f3f490 717f3786 System.IO.TextReader+SyncTextReader.ReadLine() [f:\dd\ndp\clr\src\BCL\system\io\textreader.cs @ 363]
    12 00f3f4a0 71651845 System.Console.ReadLine() [f:\dd\ndp\clr\src\BCL\system\console.cs @ 1984]
    13 00f3f4a8 02e9088e Example_7_1_1.Program.Main(System.String[]) [E:\Visual Studio 2022\...\Example_7_1_1\Program.cs @ 13]
    14 00f3f62c 71faf036 [GCFrame: 00f3f62c] 

                  !clrstack -a:顯示所有參數和局部變量,關注紅色標注的。

     1 0:000> !clrstack -a
     2 OS Thread Id: 0xc08 (0)
     3 Child SP       IP Call Site
     4 00f3f3ac 77c310fc [InlinedCallFrame: 00f3f3ac] 
     5 00f3f3a8 70f79b71 DomainNeutralILStubClass.IL_STUB_PInvoke(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)
     6     PARAMETERS:
     7         <no data>
     8         <no data>
     9         <no data>
    10         <no data>
    11         <no data>
    12 ...(內容太多,就省略了,也沒用)
    13 
    14 00f3f4a8 02e9088e Example_7_1_1.Program.Main(System.String[]) [E:\Visual Studio 2022\..\Example_7_1_1\Program.cs @ 13]
    15     PARAMETERS:(參數)
    16         args (0x00f3f4b4) = 0x02f324bc(參數)
    17     LOCALS:(局部變量)
    18         0x00f3f4b0 = 0x0000000a
    19         0x00f3f4ac = 0x0000000b
    20 
    21 00f3f62c 71faf036 [GCFrame: 00f3f62c] 


                  !clrstack -l:顯示所有局部變量,關注紅色標注的。

     1 0:000> !clrstack -l
     2 OS Thread Id: 0xc08 (0)
     3 Child SP       IP Call Site
     4 00f3f3ac 77c310fc [InlinedCallFrame: 00f3f3ac] 
     5 00f3f3a8 70f79b71 DomainNeutralILStubClass.IL_STUB_PInvoke(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)
     6 ...(內容太多,就省略了,也沒用)
     7 
     8 00f3f4a8 02e9088e Example_7_1_1.Program.Main(System.String[]) [E:\Visual Studio 2022\...\Example_7_1_1\Program.cs @ 13]
     9     LOCALS:(只有局部變量)
    10         0x00f3f4b0 = 0x0000000a
    11         0x00f3f4ac = 0x0000000b
    12 
    13 00f3f62c 71faf036 [GCFrame: 00f3f62c] 


                  !clrstack -p:顯示所有參數,關注紅色標注的。

     1 0:000> !clrstack -p
     2 OS Thread Id: 0xc08 (0)
     3 Child SP       IP Call Site
     4 00f3f3ac 77c310fc [InlinedCallFrame: 00f3f3ac] 
     5 00f3f3a8 70f79b71 DomainNeutralILStubClass.IL_STUB_PInvoke(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr)
     6     PARAMETERS:
     7         <no data>
     8         <no data>
     9         <no data>
    10         <no data>
    11         <no data>
    12 
    13 ...(內容太多,就省略了,也沒用)
    14 
    15 00f3f4a8 02e9088e Example_7_1_1.Program.Main(System.String[]) [E:\Visual Studio 2022\...\Example_7_1_1\Program.cs @ 13]
    16     PARAMETERS:(只有參數)
    17         args (0x00f3f4b4) = 0x02f324bc
    18 
    19 00f3f62c 71faf036 [GCFrame: 00f3f62c] 


            
    2.6、使用【~*e】查看所有托管線程棧。
                  測試源碼:Example_7_1_1
                  ~ 命令輸出所有線程列表。

     1 0:000> ~
     2 .  0  Id: 2074.c08 Suspend: 1 Teb: 00c98000 Unfrozen
     3    1  Id: 2074.2cdc Suspend: 1 Teb: 00c9b000 Unfrozen
     4    2  Id: 2074.3bec Suspend: 1 Teb: 00c9e000 Unfrozen
     5    3  Id: 2074.1a34 Suspend: 1 Teb: 00ca1000 Unfrozen
     6    4  Id: 2074.3858 Suspend: 1 Teb: 00ca4000 Unfrozen
     7    5  Id: 2074.379c Suspend: 1 Teb: 00ca7000 Unfrozen
     8    6  Id: 2074.3088 Suspend: 1 Teb: 00caa000 Unfrozen
     9    7  Id: 2074.2c54 Suspend: 1 Teb: 00cad000 Unfrozen
    10    8  Id: 2074.20dc Suspend: 1 Teb: 00cb0000 Unfrozen
    11    9  Id: 2074.2014 Suspend: 1 Teb: 00cb3000 Unfrozen
    12 # 10  Id: 2074.187c Suspend: 1 Teb: 00cc2000 Unfrozen
    13   11  Id: 2074.2b64 Suspend: 1 Teb: 00cb9000 Unfrozen
    14   12  Id: 2074.1358 Suspend: 1 Teb: 00cbc000 Unfrozen
    15   13  Id: 2074.6e8 Suspend: 1 Teb: 00cbf000 Unfrozen

                  ~* 命令,顯示所有線程列表和入口函數。

     1 0:000> ~*
     2 .  0  Id: 2074.c08 Suspend: 1 Teb: 00c98000 Unfrozen
     3       Start: 00402bca
     4       Priority: 0  Priority class: 32  Affinity: f
     5    1  Id: 2074.2cdc Suspend: 1 Teb: 00c9b000 Unfrozen
     6       Start: ntdll!TppWorkerThread (77c10c90)
     7       Priority: 0  Priority class: 32  Affinity: f
     8    2  Id: 2074.3bec Suspend: 1 Teb: 00c9e000 Unfrozen
     9       Start: ntdll!TppWorkerThread (77c10c90)
    10       Priority: 0  Priority class: 32  Affinity: f
    11    3  Id: 2074.1a34 Suspend: 1 Teb: 00ca1000 Unfrozen
    12       Start: ntdll!TppWorkerThread (77c10c90)
    13       Priority: 0  Priority class: 32  Affinity: f
    14    4  Id: 2074.3858 Suspend: 1 Teb: 00ca4000 Unfrozen
    15       Start: clr!DebuggerRCThread::ThreadProcStatic (721565d0)
    16       Priority: 0  Priority class: 32  Affinity: f
    17    5  Id: 2074.379c Suspend: 1 Teb: 00ca7000 Unfrozen
    18       Start: clr!Thread::intermediateThreadProc (72074b60)
    19       Priority: 2  Priority class: 32  Affinity: f
    20    6  Id: 2074.3088 Suspend: 1 Teb: 00caa000 Unfrozen
    21       Start: combase!CRpcThreadCache::RpcWorkerThreadEntry (7731bcc0)
    22       Priority: 0  Priority class: 32  Affinity: f
    23    7  Id: 2074.2c54 Suspend: 1 Teb: 00cad000 Unfrozen
    24       Start: ntdll!TppWorkerThread (77c10c90)
    25       Priority: 0  Priority class: 32  Affinity: f
    26    8  Id: 2074.20dc Suspend: 1 Teb: 00cb0000 Unfrozen
    27       Start: ntdll!TppWorkerThread (77c10c90)
    28       Priority: 0  Priority class: 32  Affinity: f
    29    9  Id: 2074.2014 Suspend: 1 Teb: 00cb3000 Unfrozen
    30       Start: clr!Thread::intermediateThreadProc (72074b60)
    31       Priority: 0  Priority class: 32  Affinity: f
    32 # 10  Id: 2074.187c Suspend: 1 Teb: 00cc2000 Unfrozen
    33       Start: ntdll!DbgUiRemoteBreakin (77c6cee0)
    34       Priority: 0  Priority class: 32  Affinity: f
    35   11  Id: 2074.2b64 Suspend: 1 Teb: 00cb9000 Unfrozen
    36       Start: clr!Thread::intermediateThreadProc (72074b60)
    37       Priority: 0  Priority class: 32  Affinity: f
    38   12  Id: 2074.1358 Suspend: 1 Teb: 00cbc000 Unfrozen
    39       Start: clr!Thread::intermediateThreadProc (72074b60)
    40       Priority: 0  Priority class: 32  Affinity: f
    41   13  Id: 2074.6e8 Suspend: 1 Teb: 00cbf000 Unfrozen
    42       Start: clr!Thread::intermediateThreadProc (72074b60)
    43       Priority: 0  Priority class: 32  Affinity: f

                  ~*e !clrstack 命令執行的結果,內容太多,折疊了。

    View Code


            
    2.7、使用【!dumpstack】命令查看托管和非托管的線程棧。
                  測試源碼:Example_7_1_1
                  需要切換到主線程,然后執行命令【!dumpstack】

     1 0:000> !dumpstack
     2 OS Thread Id: 0x710 (0)
     3 Current frame: ntdll!NtReadFile+0xc
     4 ChildEBP RetAddr  Caller, Callee
     5 00daef38 75dbf25c KERNELBASE!ReadFile+0xec, calling ntdll!NtReadFile
     ......
    66 00daf7d0 71fb9704 clr!Alloc+0x142, calling clr!_EH_epilog3
    67 00daf7d8 71fc3cbc clr!HndLogSetEvent+0x15, calling clr!GCEventEnabledSetGCHandle
    68 00daf9b0 77c052fe ntdll!RtlAllocateHeap+0x3e, calling ntdll!RtlpAllocateHeapInternal
    69 00daf9d0 7213ca2c clr!EEStartupHelper+0xabb, calling clr!_EH_epilog3
    70 00daf9d4 7213b55b clr!EEStartup+0xb8, calling clr!_SEH_epilog4
    71 00dafa0c 7215b8a8 clr!ExecuteEXE+0x4c, calling clr!SystemDomain::ExecuteMainMethod
    72 00dafa64 7215b9ce clr!_CorExeMainInternal+0xdc, calling clr!ExecuteEXE
    73 00dafaa4 72157305 clr!_CorExeMain+0x4d, calling clr!_CorExeMainInternal
    74 00dafae0 7275fa84 mscoreei!_CorExeMain+0xd6
    75 00dafafc 7636f4c4 KERNEL32!GetProcAddressStub+0x14, calling KERNELBASE!GetProcAddressForCaller
    76 00dafb18 7285e81e MSCOREE!ShellShim__CorExeMain+0x9e
    77 00dafb28 72864338 MSCOREE!_CorExeMain_Exported+0x8, calling MSCOREE!ShellShim__CorExeMain
    78 00dafb30 7636f989 KERNEL32!BaseThreadInitThunk+0x19
    79 00dafb40 77c27084 ntdll!__RtlUserThreadStart+0x2f
    80 00dafb9c 77c27054 ntdll!_RtlUserThreadStart+0x1b, calling ntdll!__RtlUserThreadStart

                  我們可以使用【!dumpstack -ee】只查看托管棧。

     1 0:000> !dumpstack -ee
     2 OS Thread Id: 0x710 (0)
     3 Current frame: 
     4 ChildEBP RetAddr  Caller, Callee
     5 00daef9c 70f79b71 (MethodDesc 70c438c4 +0x69 DomainNeutralILStubClass.IL_STUB_PInvoke(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr))
     6 00daefc8 70f79b71 (MethodDesc 70c438c4 +0x69 DomainNeutralILStubClass.IL_STUB_PInvoke(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte*, Int32, Int32 ByRef, IntPtr))
     7 00daf00c 716ab275 (MethodDesc 70cf7a24 +0x89 System.IO.__ConsoleStream.ReadFileNative(Microsoft.Win32.SafeHandles.SafeFileHandle, Byte[], Int32, Int32, Boolean, Boolean, Int32 ByRef))
     8 00daf038 716ab17b (MethodDesc 70cf7a4c +0x9f System.IO.__ConsoleStream.Read(Byte[], Int32, Int32))
     9 00daf064 70f5e6a3 (MethodDesc 70c2d964 +0x33 System.IO.StreamReader.ReadBuffer())
    10 00daf07c 70f5eb5b (MethodDesc 70c2d96c +0xe3 System.IO.StreamReader.ReadLine())
    11 00daf098 717f3786 (MethodDesc 70d22100 +0x1a System.IO.TextReader+SyncTextReader.ReadLine())
    12 00daf0a8 71651845 (MethodDesc 70c19e00 +0x15 System.Console.ReadLine())
    13 00daf0b0 0144088e (MethodDesc 01184d78 +0x46 Example_7_1_1.Program.Main(System.String[]))


            
    2.8、使用【!eestack】和【~*e !dumpstack】查看所有的線程棧。
                  測試源碼:Example_7_1_1

    1 0:000> !eestack
    2 ---------------------------------------------
    3 Thread   0
    4 Current frame: ntdll!NtReadFile+0xc
    5 ChildEBP RetAddr  Caller, Callee
    6 。。。。
    7 內容太多,省略了。

                ~*e !dumpstack執行效果

    1 0:000> ~*e !dumpstack
    2 OS Thread Id: 0x710 (0)
    3 Current frame: ntdll!NtReadFile+0xc
    4 ChildEBP RetAddr  Caller, Callee
    5 00daef38 75dbf25c KERNELBASE!ReadFile+0xec, calling ntdll!NtReadFile
    6 ......
    7 內容太多,省略了。

                eestack 命令,可以增加參數,比如:-short,我們可以使用 SOS 的幫助命令查看某個命令的解釋,比如:eestack。

     1 0:010> !sos.help eestack
     2 -------------------------------------------------------------------------------
     3 !EEStack [-short] [-EE]
     4 
     5 This command runs !DumpStack on all threads in the process. The -EE option is 
     6 passed directly to !DumpStack. The -short option tries to narrow down the 
     7 output to "interesting" threads only, which is defined by
     8 
     9 1) The thread has taken a lock.(可以顯示具有鎖的線程)
    10 2) The thread has been "hijacked" in order to allow a garbage collection.(可以顯示被“劫持”的線程)
    11 3) The thread is currently in managed code.(可以顯示托管線程)
    12 
    13 See the documentation for !DumpStack for more info.


    四、總結
        終于寫完了,今天這篇文章是第六篇。我們了解了線程和線程調用棧,那調試起來我們就知道如何開始了,知道如何查找參數和局部變量,知道線程棧地址,哦我們可以輸出線程棧的內容,對值類型和引用類型了解的也更深入了,當然對線程了解也更深入了,終于做到知其一也知其二了。其實這些知識是相互作用的,不是獨立的,任何一個環節的調試,都需要很多技巧。好了,不說了,不忘初心,繼續努力,希望老天不要辜負努力的人。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有