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?

Class Skeleton
  • 2,913
  • 6
  • 31
  • 51
  • You should always check the return value of system calls ! It may shine some light on your issue. – engf-010 Jun 03 '16 at 11:39
  • @engf-010 - If I set the last error as 0 before `FormatMessageW`, `GetLastError()` immediately after `FormatMessageW` shows as 0. – Class Skeleton Jun 03 '16 at 11:43
  • 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. – Christian.K Jun 03 '16 at 11:51
  • Not using `FORMAT_MESSAGE_IGNORE_INSERTS` for arbitrary system error codes is a bug (as [documented](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx)). Please include it in your code (and not just mention it further down). – IInspectable Jun 03 '16 at 11:55
  • @Christian.K - yes, this is in the production code. – Class Skeleton Jun 03 '16 at 11:55
  • 1
    Somewhat reassuring : the Error Lookup utility gives the same error description ,so if MS can't do it right ... – engf-010 Jun 03 '16 at 15:18
  • Was this ever solved? – mrexodia Oct 29 '17 at 00:41

1 Answers1

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.

jdigital
  • 11,926
  • 4
  • 34
  • 51
  • I'm totally more inclined to believe, that the return value of [FormatMessage](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx) shouldn't be flushed down the drains... – IInspectable Jun 03 '16 at 12:09
  • *"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. – IInspectable Jun 03 '16 at 12:30
  • @IInspectable I've updated the answer to indicate this terminology (Fatal System Error) comes from the text of the error message. – jdigital Jun 03 '16 at 12:35
  • 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. – Class Skeleton Jun 03 '16 at 12:53
  • If I understand these error codes, you won't be seeing them in your app. – jdigital Jun 03 '16 at 12:54
  • 1
    @jdigital: `ERROR_UNHANDLED_EXCEPTION` is likely to show up in an unhandled exception filter (see [SetUnhandledExceptionFilter](https://msdn.microsoft.com/en-us/library/windows/desktop/ms680634.aspx)), so it can occur in your process. – IInspectable Jun 03 '16 at 13:58
  • @IInspectable: can you expand on that? I don't see how it would happen. – Harry Johnston Jun 04 '16 at 02:00