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