How do you get the name and/or description of an SEH exception without having to hard-code the strings into your application?
I tried to use FormatMessage()
, but it truncates the message sometimes, even if you specify to ignore inserts:
__asm { // raise access violation
xor eax, eax
mov eax, [eax]
}
Raises an exception with the code 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);
Fills msg
with the truncated string: "The instruction at 0x
".
Structured exception codes are defined through NTSTATUS numbers. Although someone from MS suggests using FormatMessage() to convert NTSTATUS numbers to strings, I would not do this. Flag FORMAT_MESSAGE_FROM_SYSTEM
is used to convert result of GetLastError() into a string, so it makes no sense here. Using flag FORMAT_MESSAGE_FROM_HMODULE
along with ntdll.dll
will lead to incorrect results for some codes. E.g., for EXCEPTION_ACCESS_VIOLATION
you will get The instruction at 0x
, which is not very informative :) .
When you look at the strings that are stored in ntdll.dll
it becomes obvious that many of them are supposed to be used with the printf() function, not with the FormatMessage(). For example, the string for EXCEPTION_ACCESS_VIOLATION
is:
The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
%0
is treated by FormatMessage() as the escape sequence meaning message terminator, not an insert. Inserts are %1 to %99. That's why flag FORMAT_MESSAGE_IGNORE_INSERTS
does not make any difference.
You might want to load the string from ntdll.dll
and pass it to vprintf() but you will need to prepare arguments exactly as the string specifies (e.g. for EXCEPTION_ACCESS_VIOLATION
it's unsigned long
, unsigned long
, char*
). And this approach has major drawback: any change in the number, order or size of arguments in ntdll.dll
may break your code.
So it's safer and easier to hard code the strings into your own code. I find it dangerous to use strings prepared by someone else without coordination with me :) and moreover for other function. This is just one more possibility for malfunction.
Does this apply?
http://www.winehq.org/pipermail/wine-devel/2001-May/000801.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With