Why does FormatMessage only create partial messages for ERROR_SYSTEM_PROCESS_TERMINATED and ERROR_UNHANDLED_EXCEPTION system errors?
Asked Answered
T

1

1

I have been using the FormatMessage function within the Windows API to generate message strings from system error codes. I noticed that for some error codes the full message doesn't appear to be created.

Take this sample program as an example:

int main()
{
  wchar_t * buffer = nullptr;
  FormatMessageW(
    FORMAT_MESSAGE_FROM_SYSTEM 
    | FORMAT_MESSAGE_ALLOCATE_BUFFER 
    | FORMAT_MESSAGE_IGNORE_INSERTS, 
    nullptr, 
    ERROR_SYSTEM_PROCESS_TERMINATED,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    reinterpret_cast<LPWSTR>(&buffer), 
    0, 
    nullptr);

  std::wcout << buffer << std::endl;
  return 0;
}

According to MSDN I should see the following:

{Fatal System Error}
The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 0x%08x). The system has been shut down.

However, in the sample program I will see:

{Fatal System Error}
The %hs system process terminated unexpectedly with a status of 0x

I noticed that ERROR_UNHANDLED_EXCEPTION also doesn't create the full message (when compared to the list on MSDN). Both of the expected messages contain 0x%08 placeholders, but the message ends after 0x.

From what I can see, other error messages appear to match the lists on MSDN (i.e. the issue appears to be restricted to ERROR_UNHANDLED_EXCEPTION and ERROR_SYSTEM_PROCESS_TERMINATED).


Credit to engf-010 - you get the same if you use the Error Lookup tool in Visual Studio (Tools - Error Lookup). The error codes are 574 and 591.


Does anyone know why these messages are being cropped?

Is there anyway to get the full message?

Tasty answered 3/6, 2016 at 11:30 Comment(7)
You should always check the return value of system calls ! It may shine some light on your issue.Apatetic
@Apatetic - If I set the last error as 0 before FormatMessageW, GetLastError() immediately after FormatMessageW shows as 0.Tasty
As a side note, you should LocalFree/HeapFree the buffer returned when using FORMAT_MESSAGE_ALLOCATE_BUFFER. Even though that might not be relevant in this small example.Spruill
Not using FORMAT_MESSAGE_IGNORE_INSERTS for arbitrary system error codes is a bug (as documented). Please include it in your code (and not just mention it further down).Wordless
@Spruill - yes, this is in the production code.Tasty
Somewhat reassuring : the Error Lookup utility gives the same error description ,so if MS can't do it right ...Apatetic
Was this ever solved?Antenatal
S
2

The messages you mention (ERROR_UNHANDLED_EXCEPTION and ERROR_SYSTEM_PROCESS_TERMINATED) have printf-style inserts (%08x). However, FormatMessage uses %0 to terminate a message.

My guess is that there's another avenue where these messages are returned by the system with the printf-style placeholders already populated; these messages, in their raw form, are not meant to be handled by FormatMessage.

Given that these messages contain the text (Fatal System Error) or (Application Error), it is not altogether surprising that Windows handles these message specially.

Survive answered 3/6, 2016 at 12:7 Comment(7)
I'm totally more inclined to believe, that the return value of FormatMessage shouldn't be flushed down the drains...Wordless
"Given that these are fatal system errors" - No, they aren't. They are (potentially) fatal process errors. Nothing the system is terribly concerned about. The kernel destroys the process objects, and moves on. This happens all the time.Wordless
@Wordless I've updated the answer to indicate this terminology (Fatal System Error) comes from the text of the error message.Survive
I can't say for certain, but it seems that the issue is an oversight/limitation in the API. It goes against the recommended approach for retrieving system error messages. The only workaround I can see is to do a check on the error code before formatting, and then branch off to create the expected messages for the 2 scenarios I have found.Tasty
If I understand these error codes, you won't be seeing them in your app.Survive
@jdigital: ERROR_UNHANDLED_EXCEPTION is likely to show up in an unhandled exception filter (see SetUnhandledExceptionFilter), so it can occur in your process.Wordless
@IInspectable: can you expand on that? I don't see how it would happen.Hydrophyte

© 2022 - 2024 — McMap. All rights reserved.