在Windows XP上,當CPU引發異常(中斷)時,我嘗試打印官方字符串消息。在這裏,我有一段代碼,它試圖訪問系統異常處理:嘗試獲取帶參數的字符串消息
#include <stdio.h>
#include <windows.h>
LONG WINAPI e(LPEXCEPTION_POINTERS ExceptionInfo) {
printf("Exception Handled ...\n");
char buf[8192];
memset(buf, 0, 8192);
void * pArgs[ExceptionInfo->ExceptionRecord->NumberParameters];
for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) {
printf("arg[%d] = %d\n", i, ExceptionInfo->ExceptionRecord->ExceptionInformation[i+1]);
pArgs[i] = (void *) ExceptionInfo->ExceptionRecord->ExceptionInformation[i+1];
}
HMODULE Hand = LoadLibrary("NTDLL.DLL");
int res = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_FROM_HMODULE,
Hand,
ExceptionInfo->ExceptionRecord->ExceptionCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buf,
8192,
(va_list *) pArgs);
printf("res=%d\n", res);
FreeLibrary(Hand);
printf("ExceptionCode=0x%08x (%s)\n", ExceptionInfo->ExceptionRecord->ExceptionCode, buf);
printf("ExceptionFlags=%d\n", ExceptionInfo->ExceptionRecord->ExceptionFlags);
printf("ExceptionAddress=0x%08x\n", ExceptionInfo->ExceptionRecord->ExceptionAddress);
printf("NumberParameters=%d\n", ExceptionInfo->ExceptionRecord->NumberParameters);
printf("ExceptionInformation=%s\n", ExceptionInfo->ExceptionRecord->ExceptionInformation);
return EXCEPTION_EXECUTE_HANDLER;
}
int main() {
LPTOP_LEVEL_EXCEPTION_FILTER p = SetUnhandledExceptionFilter(e);
for (int i = 10; i < 256; i++) {
int *p = (int *) i;
printf("address pointed by p = 0x%08x\n", *p);
}
}
它產生以下輸出:
Exception Handled ...
arg[0] = 10
arg[1] = 65599
res=22
ExceptionCode=0xc0000005 (The instruction at "0x)
ExceptionFlags=0
ExceptionAddress=0x004018da
NumberParameters=2
ExceptionInformation=
正如你可以看到消息被截斷。
在ntdll.dll
有字符串消息:
[email protected] /c/WINDOWS/system32
$ strings ntdll.dll | grep instruction
The instruction at %p referenced memory at %p.
The instruction at %p tried to %s
應該是什麼得到充分的信息以正確的方式你知道嗎?謝謝。
+1是爲測試目的。事實上,對於這個異常(訪問衝突),第一個參數是NULL。 對於FORMAT_MESSAGE_ARGUMENT_ARRAY,是的,我同意,它在文檔中,但它不能解決問題。 Microsoft建議將FormatMessage API與ntdll.dll消息一起使用(http://support.microsoft.com/kb/259693)。他們的方法的優點是使用預定義的字符串。你提出的代碼不幸的不是。 – jlguenego
[閱讀文檔](http://msdn.microsoft.com/en-us/library/windows/desktop/aa363082.aspx)。訪問衝突的第一個參數是**讀/寫標誌**,而不是指針。 0表示在讀取時發生AV,1表示寫入時發生AV,8表示DEP被違反。如果您閱讀了鏈接到的支持頁面,則不會使用格式參數。正如我們可以清楚地看到的那樣,這兩個異常的參數不能用FormatMessage()格式化,它們不匹配。 –