如何获取exception的名称/描述?

如何获得SEHexception的名称和/或描述, 而不必将string硬编码到应用程序中?

我尝试使用FormatMessage() ,但是它有时会截断消息,即使您指定忽略插入:

 __asm { // raise access violation xor eax, eax mov eax, [eax] } 

引发exception,代码为0xC0000005 (EXCEPTION_ACCESS_VIOLATION)

 char msg[256]; FormatMessageA(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, GetModuleHandleA("ntdll.dll"), 0xC0000005, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msg, sizeof(msg), NULL); 

用截断的string填充msg :“ The instruction at 0x ”。

Solutions Collecting From Web of "如何获取exception的名称/描述?"

结构化的异常代码是通过NTSTATUS号码定义的。 尽管来自MS的人建议使用FormatMessage()将NTSTATUS数字转换为字符串,但我不会这样做。 标志FORMAT_MESSAGE_FROM_SYSTEM用于将GetLastError()的结果转换为一个字符串,所以在这里没有意义。 对于某些代码,使用标志FORMAT_MESSAGE_FROM_HMODULEntdll.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 longunsigned long unsigned long unsigned longchar* )。 而这种方法有一个主要的缺点:在ntdll.dll参数的数量,顺序或大小的任何变化可能会打破你的代码。

因此,将字符串硬编码到自己的代码中会更安全,更简单。 我觉得使用别人编写的字符串而不与我协调:)是危险的,而且还有其他功能。 这只是一个更多的故障的可能性。