[PATCH] windows-nat: Decode system error numbers

Maciej W. Rozycki
2011-11-09T12:03:28Z

Hi,

A while ago I have come across a problem while debugging a MinGW program
natively where the backend reported an error numerically. As quite
obviously I couldn't figure out what the cause of the error was I went
back to the sources and discovered that we have this piece of code in
windows-nat that fails to decode Windows system errors. With the patch
below I was able to track down what the problem was.

Now I don't have that setup available anymore (that was something weird
anyway), so to validate this change before submission I simulated an error
scenario by running GDB under GDB and deliberately corrupting data. I
chose windows_kill_inferior as it's easy to trigger by just killing the
inferior from the debuggee GDB.

So an example session looks like:

(gdb) break windows_kill_inferior
Breakpoint 1 at 0x519cf4: file .../gdb/windows-nat.c, line 2312.
(gdb) continue
Continuing.
[Switching to Thread 4700.0x1bb4]

Breakpoint 1, windows_kill_inferior (ops=0x953180)
at .../gdb/windows-nat.c:2312
2312 CHECK (TerminateProcess (current_process_handle, 0));
(gdb) print current_process_handle
$1 = (HANDLE) 0x148
(gdb) set variable current_process_handle = 0
(gdb) continue
Continuing.

and as it stands this is printed by the debuggee GDB:

error return .../gdb/windows-nat.c:2312 was 6

but with the patch applied a proper error message is produced instead:

error return .../gdb/windows-nat.c:2332 was: The handle is invalid. (6)

As Windows tends to terminate its error messages with a CR+LF sequence,
these characters are stripped by my code so that the result remains a
single line (I decided not to strip the trailing full stop though and
consequently added one to the fallback message for consistency).

This code builds and works as manually verified above; these errors never
trigger in the test suite so that doesn't really cover it -- my
understanding is they are not meant to trigger unless GDB or the system is
malfunctioning for some reason.

OK to apply?

2011-11-09 Maciej W. Rozycki <macro@codesourcery.com>

gdb/
* windows-nat.c (check): Decode the error number retrieved with
GetLastError.

Maciej

gdb-windows-nat-check.patch
Index: gdb-fsf-trunk-quilt/gdb/windows-nat.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/windows-nat.c 2011-11-09 11:38:15.000000000 +0000
+++ gdb-fsf-trunk-quilt/gdb/windows-nat.c 2011-11-09 11:48:36.765865140 +0000
@@ -274,9 +274,29 @@ windows_set_context_register_offsets (co
static void
check (BOOL ok, const char *file, int line)
{
- if (!ok)
- printf_filtered ("error return %s:%d was %lu\n", file, line,
- GetLastError ());
+ const char *msg = "Unspecified error.";
+ unsigned long err;
+ char buf[1025];
+ size_t size;
+
+ if (ok)
+ return;
+
+ err = GetLastError();
+ size = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buf, (sizeof (buf) - 1) / sizeof (TCHAR), NULL);
+ if (size > 0 && buf[size - 1] == '\n')
+ buf[--size] = '\0';
+ if (size > 0 && buf[size - 1] == '\r')
+ buf[--size] = '\0';
+ if (size > 0)
+ msg = buf;
+
+ printf_filtered ("error return %s:%d was: %s (%lu)\n", file, line, msg, err);
}

/* Find a thread record given a thread id. If GET_CONTEXT is not 0,