我不情愿地再次处理Win32结构化异常.我正在尝试生成描述异常的字符串.大多数都很简单,但我坚持一些基本的东西:如何将异常代码(结果GetExceptionCode()或者ExceptionCode成员EXCEPTION_RECORD)转换为描述异常的字符串?
我正在寻找能够将例如0xC0000005转换为"访问冲突"的内容.这只是一个电话FormatMessage()吗?
结构化异常代码通过NTSTATUS编号定义.虽然MS的某些人建议使用FormatMessage()将NTSTATUS数字转换为字符串,但我不会这样做.Flag FORMAT_MESSAGE_FROM_SYSTEM用于将GetLastError()的结果转换为字符串,因此这里没有意义.使用标志FORMAT_MESSAGE_FROM_HMODULE沿ntdll.dll将导致对某些代码不正确的结果.例如,因为EXCEPTION_ACCESS_VIOLATION你会得到The instruction at 0x,这不是很有用的信息:).
当你看到存储在ntdll.dll其中的字符串时,很明显很多字符串应该与printf()函数一起使用,而不是与FormatMessage()一起使用.例如,字符串为EXCEPTION_ACCESS_VIOLATION:
The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
%0由FormatMessage()作为转义序列处理,表示消息终止符,而不是插入.插入是%1到%99.这就是旗帜FORMAT_MESSAGE_IGNORE_INSERTS没有任何区别的原因.
您可能希望加载从字符串ntdll.dll,并将它传递给vprintf,但你需要准备完全相同的参数作为字符串指定(例如EXCEPTION_ACCESS_VIOLATION它的unsigned long,unsigned long,char*).这种方法有一个主要缺点:参数的数量,顺序或大小的任何变化都ntdll.dll可能会破坏您的代码.
因此,将字符串硬编码到您自己的代码中更安全,更容易.我发现使用别人准备的字符串而不与我协调是危险的:)而且还有其他功能.这只是故障的另一种可能性.
是。这是NTSTATUS,因此请使用FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_FROM_HMODULE,并HMODULE从传递LoadLibrary("NTDLL.DLL")
正确管理某些 NTSTATUS 字符串所具有的流格式很复杂。您应该考虑使用RtlNtStatusToDosError()将其转换为 Win32 消息,该消息位于 header Winternl.h 中。您需要在链接器输入中包含 ntdll.lib。
实施示例:
// Returns length of resulting string, excluding null-terminator.
// Use LocalFree() to free the buffer when it is no longer needed.
// Returns 0 upon failure, use GetLastError() to get error details.
DWORD FormatNtStatus(NTSTATUS nsCode, TCHAR **ppszMessage) {
// Get handle to ntdll.dll.
HMODULE hNtDll = LoadLibrary(_T("NTDLL.DLL"));
// Check for fail, user may use GetLastError() for details.
if (hNtDll == NULL) return 0;
// Call FormatMessage(), note use of RtlNtStatusToDosError().
DWORD dwRes = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
hNtDll, RtlNtStatusToDosError(nsCode), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)ppszMessage, 0, NULL);
// Free loaded dll module and decrease its reference count.
FreeLibrary(hNtDll);
return dwRes;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3427 次 |
| 最近记录: |