Windows gdb+gdbserver: Decode Cygwin ExitProcess codes

On native Cygwin, GDB misreports the inferior's exit reason in several
common cases, resulting in several gdb.base/exitsignal.exp failures:

 $ grep FAIL gdb.sum
 FAIL: gdb.base/exitsignal.exp: how=run: signal: program terminated with SIGSEGV (the program exited)
 FAIL: gdb.base/exitsignal.exp: how=run: signal: $_exitsignal is 11 (SIGSEGV) after SIGSEGV.
 FAIL: gdb.base/exitsignal.exp: how=run: signal: $_exitcode is still void after SIGSEGV
 FAIL: gdb.base/exitsignal.exp: how=run: signal: $_exitsignal is 11 (SIGSEGV) after restarting the inferior
 FAIL: gdb.base/exitsignal.exp: how=run: signal: $_exitcode is still void after restarting the inferior
 FAIL: gdb.base/exitsignal.exp: how=run: normal: continue to exit
 FAIL: gdb.base/exitsignal.exp: how=run: normal: $_exitcode is one after normal inferior is executed
 FAIL: gdb.base/exitsignal.exp: how=run: normal: $_exitsignal is still void after normal inferior is executed
 FAIL: gdb.base/exitsignal.exp: how=attach: normal: continue to exit (the program exited)
 FAIL: gdb.base/exitsignal.exp: how=attach: normal: $_exitcode is one after normal inferior is executed

For example, from gdb.log, the normal exit case:

 ...
 [Thread 14300.0x4214 (id 1) exited with code 1]
 [Thread 14300.0x1b1c (id 4) exited with code 1]
 [Thread 14300.0x1e2c (id 2) exited with code 1]

 Program terminated with signal SIGHUP, Hangup.
 The program no longer exists.
 (gdb) FAIL: gdb.base/exitsignal.exp: how=run: normal: continue to exit

The program in fact exited normally with code 1.  SIGHUP happens to be
signal 1, and GDB picked the wrong interpretation.

Similarly, for the signal termination case:

 ...
 continue
 Continuing.
 [Thread 4600.0x3104 (id 4) exited with code 2816]
 [Thread 4600.0x2bcc (id 3) exited with code 2816]
 [Thread 4600.0x2f44 (id 1) exited with code 2816]
 [Inferior 1 (process 4600) exited with code 05400]
 (gdb) FAIL: gdb.base/exitsignal.exp: how=run: signal: program terminated with SIGSEGV (the program exited)

Here the inferior died with SIGSEGV, but GDB reported exit decimal
2816 / octal 05400 / hex 0x0B00, which is SIGSEGV swapped into the
high byte of a waitpid exit status.

The problem is that Cygwin waitpid exit status and Windows exit codes
do not have the same encoding, and GDB & GDBserver do not know about
this.

This commit fixes it.  It adds a Cygwin-specific branch to the code
that determines the terminating signal and status of a program.  The
branch for native Windows/MinGW GDB is left intact, no behavior change
there.

The way to decode the exit codes is a little bit tricky, see detailed
comments added by the patch.  To exercise the "raw NTSTATUS error
code" path in windows_process_info::exit_process_to_target_status,
gdb.base/exitsignal.exp is extended to debug a native Windows program
that crashes with a segfault (STATUS_ACCESS_VIOLATION).

With this, gdb.base/exitsignal.exp passes cleanly on Cygwin.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Change-Id: Icaebcc234b71927915c996fd120884604441415b
5 files changed