《軟體除錯》讀書筆記:第13章 硬錯誤和藍屏
Ox9A82發表於2016-04-12
會話管理器程式SMSS.exe是系統啟動後的第一個使用者態程式,負責啟動和監護windows子系統程式:CSRSS.exe和登陸管理程式:WinLogon
SMSS.exe從登錄檔中查詢子系統exe檔案的位置,並且啟動它
CSRSS是windows子系統程式,自NT4以後視窗管理和GDI的主體實現被移出了CSRSS放到了win32k.sys中。
CSRSS監管著所有windows執行緒和程式,每個程式在建立後都要到這裡登記才能執行,退出時也要報告登出。(維護了Windows子系統層面上的記錄結構)
CSRSS具有桌面管理、終端登入、控制檯管理、HardError報告等方面的重要作用。
為了適應惡劣環境下的錯誤提示的需要,Windows定義了硬錯誤提示機制。
硬錯誤本意是硬體有關錯誤,後來泛指嚴重的錯誤。
硬錯誤可以在使用者態使用也可以在核心態使用。
硬錯誤的核心處理函式是核心中的ExpRaiseHardError函式。
在我們看這個函式的原始碼前,先想一想,傳送硬錯誤訊息,首先要的是找到傳送硬錯誤的埠。
這個埠怎麼找?是通過一系列的設定和標誌位來判斷的。
如下是具體的程式內容
1 NTSTATUS 2 ExpRaiseHardError ( 3 IN NTSTATUS ErrorStatus, 4 IN ULONG NumberOfParameters, 5 IN ULONG UnicodeStringParameterMask, 6 IN PULONG_PTR Parameters, 7 IN ULONG ValidResponseOptions, 8 OUT PULONG Response 9 ) 10 { 11 PTEB Teb; 12 PETHREAD Thread; 13 PEPROCESS Process; 14 ULONG_PTR MessageBuffer[PORT_TOTAL_MAXIMUM_MESSAGE_LENGTH/sizeof(ULONG_PTR)]; 15 PHARDERROR_MSG m; 16 NTSTATUS Status; 17 HANDLE ErrorPort; 18 KPROCESSOR_MODE PreviousMode; 19 BOOLEAN DoingShutdown; 20 21 PAGED_CODE(); 22 //要傳送的訊息結構 23 m = (PHARDERROR_MSG)&MessageBuffer[0]; 24 PreviousMode = KeGetPreviousMode(); 25 26 DoingShutdown = FALSE; 27 //如果引數要求關機,就檢查是否有關機許可權 28 if (ValidResponseOptions == OptionShutdownSystem) { 29 30 // 31 // Check to see if the caller has the privilege to make this call. 32 // 33 34 if (!SeSinglePrivilegeCheck (SeShutdownPrivilege, PreviousMode)) { 35 return STATUS_PRIVILEGE_NOT_HELD; 36 } 37 38 ExReadyForErrors = FALSE; 39 HardErrorState = SHUTDOWN; 40 DoingShutdown = TRUE; 41 } 42 43 Thread = PsGetCurrentThread(); 44 Process = PsGetCurrentProcess(); 45 46 // 47 // If the default handler is not installed, then 48 // call the fatal hard error handler if the error 49 // status is error 50 // 51 // Let GDI override this since it does not want to crash the machine 52 // when a bad driver was loaded via MmLoadSystemImage. 53 // 54 55 if ((Thread->CrossThreadFlags & PS_CROSS_THREAD_FLAGS_HARD_ERRORS_DISABLED) == 0) { 56 //如果滿足這個標誌位說明使用者態HardError系統還沒有準備好,只能在核心態去提示這個HardError了 57 if (NT_ERROR(ErrorStatus) && (HardErrorState == STARTING || DoingShutdown)) { 58 //而所謂的在核心態提示HardError就是執行這個函式了,實質上就是一個KeBugCheckEx,也就是說想著核心態提示HardError只能是通過丟擲藍屏 59 ExpSystemErrorHandler ( 60 ErrorStatus, 61 NumberOfParameters, 62 UnicodeStringParameterMask, 63 Parameters, 64 (BOOLEAN)((PreviousMode != KernelMode) ? TRUE : FALSE)); 65 } 66 } 67 68 // 69 // If the process has an error port, then if it wants default 70 // handling, use its port. If it disabled default handling, then 71 // return the error to the caller. If the process does not 72 // have a port, then use the registered default handler. 73 // 74 75 ErrorPort = NULL; 76 //這個就是通過各種標誌位來判斷硬錯誤埠是什麼了。對於一個程式來說只有異常埠和除錯埠兩個東西,並沒有單獨指定硬錯誤埠的結構。 77 if (Process->ExceptionPort) { 78 //異常埠存在時 79 if (Process->DefaultHardErrorProcessing & 1) { 80 //這個標誌位存在時,異常埠就是硬錯誤埠 81 ErrorPort = Process->ExceptionPort; 82 } else { 83 84 // 85 // If error processing is disabled, check the error override 86 // status. 87 // 88 89 if (ErrorStatus & HARDERROR_OVERRIDE_ERRORMODE) { 90 //滿足這個條件的話,也是異常埠 91 ErrorPort = Process->ExceptionPort; 92 } 93 } 94 } else { 95 if (Process->DefaultHardErrorProcessing & 1) { 96 ErrorPort = ExpDefaultErrorPort; 97 } else { 98 99 // 100 // If error processing is disabled, check the error override 101 // status. 102 // 103 104 if (ErrorStatus & HARDERROR_OVERRIDE_ERRORMODE) { 105 ErrorPort = ExpDefaultErrorPort; 106 } 107 } 108 } 109 //雖然上面比較的那麼熱鬧。。但是ExpDefaultErrorPort和ExeceptionPort的值其實是一樣的 110 //都是CSRSS程式的\Windows\ApiPort埠。這是一個LPC埠物件 111 112 if ((Thread->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_HARD_ERRORS_DISABLED) != 0) { 113 ErrorPort = NULL; 114 } 115 //設定了禁止硬錯誤就把ErrorPort清零 116 if ((ErrorPort != NULL) && (!IS_SYSTEM_THREAD(Thread))) { 117 Teb = (PTEB)PsGetCurrentThread()->Tcb.Teb; 118 try { 119 if (Teb->HardErrorMode & RTL_ERRORMODE_FAILCRITICALERRORS) { 120 ErrorPort = NULL; 121 } 122 } except (EXCEPTION_EXECUTE_HANDLER) { 123 ; 124 } 125 } 126 127 if (ErrorPort == NULL) { 128 *Response = (ULONG)ResponseReturnToCaller; 129 return STATUS_SUCCESS; 130 } 131 //自己給自己發異常?出現問題了 132 if (Process == ExpDefaultErrorPortProcess) { 133 if (NT_ERROR(ErrorStatus)) { 134 ExpSystemErrorHandler (ErrorStatus, 135 NumberOfParameters, 136 UnicodeStringParameterMask, 137 Parameters, 138 (BOOLEAN)((PreviousMode != KernelMode) ? TRUE : FALSE)); 139 } 140 *Response = (ULONG)ResponseReturnToCaller; 141 Status = STATUS_SUCCESS; 142 return Status; 143 } 144 145 m->h.u1.Length = HARDERROR_API_MSG_LENGTH; 146 m->h.u2.ZeroInit = LPC_ERROR_EVENT; 147 m->Status = ErrorStatus & ~HARDERROR_OVERRIDE_ERRORMODE; 148 m->ValidResponseOptions = ValidResponseOptions; 149 m->UnicodeStringParameterMask = UnicodeStringParameterMask; 150 m->NumberOfParameters = NumberOfParameters; 151 152 if (Parameters != NULL) { 153 try { 154 RtlCopyMemory (&m->Parameters, 155 Parameters, 156 sizeof(ULONG_PTR)*NumberOfParameters); 157 } except (EXCEPTION_EXECUTE_HANDLER) { 158 } 159 } 160 161 KeQuerySystemTime(&m->ErrorTime); 162 //執行傳送函式 163 Status = LpcRequestWaitReplyPortEx (ErrorPort, 164 (PPORT_MESSAGE) m, 165 (PPORT_MESSAGE) m); 166 167 if (NT_SUCCESS(Status)) { 168 switch (m->Response) { 169 //作為一個返回值 170 case ResponseReturnToCaller : 171 case ResponseNotHandled : 172 case ResponseAbort : 173 case ResponseCancel : 174 case ResponseIgnore : 175 case ResponseNo : 176 case ResponseOk : 177 case ResponseRetry : 178 case ResponseYes : 179 case ResponseTryAgain : 180 case ResponseContinue : 181 break; 182 default: 183 m->Response = (ULONG)ResponseReturnToCaller; 184 break; 185 } 186 *Response = m->Response; 187 } 188 189 return Status; 190 }
這個函式把硬錯誤資訊傳送到了CSRSS程式的\Windows\ApiPort埠上去。
接下來就是看CSRSS程式是怎麼接受並處理這個硬錯誤訊息的。
CSRSS程式中專門啟用了一個執行緒來監聽並處理\Windows\ApiPort埠的內容
CsrApiRequestThread就是這個專門用來監聽的工作執行緒
PORT_MESSAGE是傳送的LPC埠的資料結構。
CSRSS負責後續的處理工作,並進行使用者層面的彈出提示。
相關文章
- 讀書筆記之《格蠹彙編-軟體除錯案例集錦》2013-04-19筆記除錯
- 筆記|軟體除錯的技巧2019-07-07筆記除錯
- 讀書筆記——《軟體工程》第10~12章2015-06-11筆記軟體工程
- 讀書筆記|Windows 除錯原理學習|持續更新2016-03-29筆記Windows除錯
- 逆向除錯時的藍屏處理2015-07-10除錯
- win10藍屏介面不顯示藍屏錯誤資訊怎麼解決_讓Win10藍屏介面顯示藍屏錯誤資訊的步驟2020-06-28Win10
- 讀書筆記之《現代軟體工程》第5.5章、第6章、第7章2015-04-22筆記軟體工程
- 讀書筆記——讀《構建之法:現代軟體工程》第13~17章2015-06-17筆記軟體工程
- 軟體除錯 (轉)2008-01-06除錯
- 軟體除錯斷點之小記2011-09-08除錯斷點
- "軟體隨想錄" 讀書筆記2017-12-29筆記
- [swift 進階]讀書筆記-第八章:錯誤處理 C8P9 高階函式和錯誤2019-04-03Swift筆記函式
- [swift 進階]讀書筆記-第八章:錯誤處理 C8P5 錯誤和函式引數2019-03-26Swift筆記函式
- [swift 進階]讀書筆記-第八章:錯誤處理 C8P2 錯誤和函式引數2019-03-17Swift筆記函式
- nginx 錯誤除錯2021-05-20Nginx除錯
- rac錯誤除錯2016-04-20除錯
- [swift 進階]讀書筆記-第八章:錯誤處理 C8P7 錯誤和可選值 Error and Optionals2019-03-30Swift筆記Error
- JSP筆記-除錯2021-09-28JS筆記除錯
- Chakra除錯筆記 TypedArray2017-08-08除錯筆記
- The art of multipropcessor programming 讀書筆記-硬體基礎22021-10-08筆記
- 《軟體架構設計》讀書筆記2022-03-20架構筆記
- 「修改軟體的藝術」 讀書筆記2017-10-20筆記
- [讀書筆記]軟體估算-估算方法(一)2009-11-17筆記
- [讀書筆記]軟體估算-估算方法(二)2009-11-26筆記
- Python 之 錯誤,除錯和測試2020-03-03Python除錯
- 大多數 SSL 證書籤發錯誤的主要原因是軟體錯誤2019-10-15
- win10系統如何開啟藍屏記錄檢視錯誤資訊2018-09-23Win10
- [swift 進階]讀書筆記-第八章:錯誤處理 C8P8 錯誤鏈 Chaining Errors2019-04-01Swift筆記AIError
- 前端的水平線,錯誤處理和除錯2018-06-06前端除錯
- 《軟體開發本質論》讀書筆記2018-01-04筆記
- [讀書筆記]軟體估算-估算的含義2009-11-15筆記
- kernel_data_inpage_error藍屏錯誤怎麼修復2022-06-22Error
- 《網路和多媒體》讀書筆記2005-10-09筆記
- [swift 進階]讀書筆記-第八章:錯誤處理 C8P3 帶有型別的錯誤2019-03-24Swift筆記型別
- 讀書筆記:深入解析oracle-第5章 記憶體管理2011-06-13筆記Oracle記憶體
- Python學習之錯誤除錯和測試2018-06-20Python除錯
- 讀《軟體驅魔》除錯和優化遺留程式碼的藝術2014-08-18除錯優化
- 軟體安全開發生命週期讀書筆記2010-06-29筆記