Display ExceptionRecord for $_siginfo
Uses the $_siginfo convenience variable to show the last exception. The type looks like this: (gdb) pt $_siginfo type = struct EXCEPTION_RECORD { DWORD ExceptionCode; DWORD ExceptionFlags; struct EXCEPTION_RECORD *ExceptionRecord; PVOID ExceptionAddress; DWORD NumberParameters; ULONG_PTR ExceptionInformation[15]; } EXCEPTION_RECORD is documented at [1]. Example: Program received signal SIGSEGV, Segmentation fault. main () at crasher.c:4 4 *(int*)0x123 = 0; (gdb) p $_siginfo $1 = { ExceptionCode = 3221225477, ExceptionFlags = 0, ExceptionRecord = 0x0, ExceptionAddress = 0x401632 <main+18>, NumberParameters = 2, ExceptionInformation = {1, 291, 0 <repeats 13 times>} } (gdb) p/x $_siginfo.ExceptionCode $2 = 0xc0000005 (gdb) p/x $_siginfo.ExceptionInformation[1] $3 = 0x123 And 0xc0000005 is the value of EXCEPTION_ACCESS_VIOLATION. [1] https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record gdb/ChangeLog: 2020-02-09 Hannes Domani <ssbssa@yahoo.de> * NEWS: Mention $_siginfo support for Windows. * windows-nat.c (handle_exception): Set siginfo_er. (windows_nat_target::mourn_inferior): Reset siginfo_er. (windows_xfer_siginfo): New function. (windows_nat_target::xfer_partial): Call windows_xfer_siginfo. * windows-tdep.c (struct windows_gdbarch_data): New struct. (init_windows_gdbarch_data): New function. (get_windows_gdbarch_data): New function. (windows_get_siginfo_type): New function. (windows_init_abi): Register windows_get_siginfo_type. (_initialize_windows_tdep): Register init_windows_gdbarch_data. gdbserver/ChangeLog: 2020-02-09 Hannes Domani <ssbssa@yahoo.de> * win32-low.c (win32_clear_inferiors): Reset siginfo_er. (handle_exception): Set siginfo_er. (win32_xfer_siginfo): New function.
This commit is contained in:
parent
98d3eb9390
commit
7928d571c5
|
@ -1,3 +1,17 @@
|
|||
2020-02-09 Hannes Domani <ssbssa@yahoo.de>
|
||||
|
||||
* NEWS: Mention $_siginfo support for Windows.
|
||||
* windows-nat.c (handle_exception): Set siginfo_er.
|
||||
(windows_nat_target::mourn_inferior): Reset siginfo_er.
|
||||
(windows_xfer_siginfo): New function.
|
||||
(windows_nat_target::xfer_partial): Call windows_xfer_siginfo.
|
||||
* windows-tdep.c (struct windows_gdbarch_data): New struct.
|
||||
(init_windows_gdbarch_data): New function.
|
||||
(get_windows_gdbarch_data): New function.
|
||||
(windows_get_siginfo_type): New function.
|
||||
(windows_init_abi): Register windows_get_siginfo_type.
|
||||
(_initialize_windows_tdep): Register init_windows_gdbarch_data.
|
||||
|
||||
2020-02-08 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* dwarf2/read.c (class cutu_reader) <cutu_reader,
|
||||
|
|
3
gdb/NEWS
3
gdb/NEWS
|
@ -10,6 +10,9 @@
|
|||
that support it (see entry for GDB 9, below), providing faster
|
||||
performance for programs with many symbols.
|
||||
|
||||
* The $_siginfo convenience variable now also works on Windows targets,
|
||||
and will display the EXCEPTION_RECORD of the last handled exception.
|
||||
|
||||
* New commands
|
||||
|
||||
set exec-file-mismatch -- Set exec-file-mismatch handling (ask|warn|off).
|
||||
|
|
|
@ -236,6 +236,7 @@ static DEBUG_EVENT current_event; /* The current debug event from
|
|||
WaitForDebugEvent */
|
||||
static HANDLE current_process_handle; /* Currently executing process */
|
||||
static windows_thread_info *current_thread; /* Info on currently selected thread */
|
||||
static EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
|
||||
|
||||
/* Counts of things. */
|
||||
static int exception_count = 0;
|
||||
|
@ -1167,6 +1168,8 @@ handle_exception (struct target_waitstatus *ourstatus)
|
|||
DWORD code = rec->ExceptionCode;
|
||||
handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
|
||||
|
||||
memcpy (&siginfo_er, rec, sizeof siginfo_er);
|
||||
|
||||
ourstatus->kind = TARGET_WAITKIND_STOPPED;
|
||||
|
||||
/* Record the context of the current thread. */
|
||||
|
@ -2863,6 +2866,7 @@ windows_nat_target::mourn_inferior ()
|
|||
CHECK (CloseHandle (current_process_handle));
|
||||
open_process_used = 0;
|
||||
}
|
||||
siginfo_er.ExceptionCode = 0;
|
||||
inf_child_target::mourn_inferior ();
|
||||
}
|
||||
|
||||
|
@ -2996,6 +3000,30 @@ windows_xfer_shared_libraries (struct target_ops *ops,
|
|||
return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
|
||||
}
|
||||
|
||||
/* Helper for windows_nat_target::xfer_partial that handles signal info. */
|
||||
|
||||
static enum target_xfer_status
|
||||
windows_xfer_siginfo (gdb_byte *readbuf, ULONGEST offset, ULONGEST len,
|
||||
ULONGEST *xfered_len)
|
||||
{
|
||||
if (siginfo_er.ExceptionCode == 0)
|
||||
return TARGET_XFER_E_IO;
|
||||
|
||||
if (readbuf == nullptr)
|
||||
return TARGET_XFER_E_IO;
|
||||
|
||||
if (offset > sizeof (siginfo_er))
|
||||
return TARGET_XFER_E_IO;
|
||||
|
||||
if (offset + len > sizeof (siginfo_er))
|
||||
len = sizeof (siginfo_er) - offset;
|
||||
|
||||
memcpy (readbuf, (char *) &siginfo_er + offset, len);
|
||||
*xfered_len = len;
|
||||
|
||||
return TARGET_XFER_OK;
|
||||
}
|
||||
|
||||
enum target_xfer_status
|
||||
windows_nat_target::xfer_partial (enum target_object object,
|
||||
const char *annex, gdb_byte *readbuf,
|
||||
|
@ -3011,6 +3039,9 @@ windows_nat_target::xfer_partial (enum target_object object,
|
|||
return windows_xfer_shared_libraries (this, object, annex, readbuf,
|
||||
writebuf, offset, len, xfered_len);
|
||||
|
||||
case TARGET_OBJECT_SIGNAL_INFO:
|
||||
return windows_xfer_siginfo (readbuf, offset, len, xfered_len);
|
||||
|
||||
default:
|
||||
if (beneath () == NULL)
|
||||
{
|
||||
|
|
|
@ -153,6 +153,30 @@ static const int FULL_TIB_SIZE = 0x1000;
|
|||
|
||||
static bool maint_display_all_tib = false;
|
||||
|
||||
static struct gdbarch_data *windows_gdbarch_data_handle;
|
||||
|
||||
struct windows_gdbarch_data
|
||||
{
|
||||
struct type *siginfo_type;
|
||||
};
|
||||
|
||||
/* Allocate windows_gdbarch_data for an arch. */
|
||||
|
||||
static void *
|
||||
init_windows_gdbarch_data (struct gdbarch *gdbarch)
|
||||
{
|
||||
return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct windows_gdbarch_data);
|
||||
}
|
||||
|
||||
/* Get windows_gdbarch_data of an arch. */
|
||||
|
||||
static struct windows_gdbarch_data *
|
||||
get_windows_gdbarch_data (struct gdbarch *gdbarch)
|
||||
{
|
||||
return ((struct windows_gdbarch_data *)
|
||||
gdbarch_data (gdbarch, windows_gdbarch_data_handle));
|
||||
}
|
||||
|
||||
/* Define Thread Local Base pointer type. */
|
||||
|
||||
static struct type *
|
||||
|
@ -656,6 +680,49 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Implement the "get_siginfo_type" gdbarch method. */
|
||||
|
||||
static struct type *
|
||||
windows_get_siginfo_type (struct gdbarch *gdbarch)
|
||||
{
|
||||
struct windows_gdbarch_data *windows_gdbarch_data;
|
||||
struct type *dword_type, *pvoid_type, *ulongptr_type;
|
||||
struct type *siginfo_ptr_type, *siginfo_type;
|
||||
|
||||
windows_gdbarch_data = get_windows_gdbarch_data (gdbarch);
|
||||
if (windows_gdbarch_data->siginfo_type != NULL)
|
||||
return windows_gdbarch_data->siginfo_type;
|
||||
|
||||
dword_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
|
||||
1, "DWORD");
|
||||
pvoid_type = arch_pointer_type (gdbarch, gdbarch_ptr_bit (gdbarch), "PVOID",
|
||||
builtin_type (gdbarch)->builtin_void);
|
||||
ulongptr_type = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch),
|
||||
1, "ULONG_PTR");
|
||||
|
||||
siginfo_type = arch_composite_type (gdbarch, "EXCEPTION_RECORD",
|
||||
TYPE_CODE_STRUCT);
|
||||
siginfo_ptr_type = arch_pointer_type (gdbarch, gdbarch_ptr_bit (gdbarch),
|
||||
NULL, siginfo_type);
|
||||
|
||||
append_composite_type_field (siginfo_type, "ExceptionCode", dword_type);
|
||||
append_composite_type_field (siginfo_type, "ExceptionFlags", dword_type);
|
||||
append_composite_type_field (siginfo_type, "ExceptionRecord",
|
||||
siginfo_ptr_type);
|
||||
append_composite_type_field (siginfo_type, "ExceptionAddress",
|
||||
pvoid_type);
|
||||
append_composite_type_field (siginfo_type, "NumberParameters", dword_type);
|
||||
/* The 64-bit variant needs some padding. */
|
||||
append_composite_type_field_aligned (siginfo_type, "ExceptionInformation",
|
||||
lookup_array_range_type (ulongptr_type,
|
||||
0, 14),
|
||||
TYPE_LENGTH (ulongptr_type));
|
||||
|
||||
windows_gdbarch_data->siginfo_type = siginfo_type;
|
||||
|
||||
return siginfo_type;
|
||||
}
|
||||
|
||||
/* To be called from the various GDB_OSABI_CYGWIN handlers for the
|
||||
various Windows architectures and machine types. */
|
||||
|
||||
|
@ -675,6 +742,8 @@ windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||
set_gdbarch_gdb_signal_to_target (gdbarch, windows_gdb_signal_to_target);
|
||||
|
||||
set_solib_ops (gdbarch, &solib_target_so_ops);
|
||||
|
||||
set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
|
||||
}
|
||||
|
||||
/* Implementation of `tlb' variable. */
|
||||
|
@ -690,6 +759,9 @@ void _initialize_windows_tdep ();
|
|||
void
|
||||
_initialize_windows_tdep ()
|
||||
{
|
||||
windows_gdbarch_data_handle
|
||||
= gdbarch_data_register_post_init (init_windows_gdbarch_data);
|
||||
|
||||
init_w32_command_list ();
|
||||
add_cmd ("thread-information-block", class_info, display_tib,
|
||||
_("Display thread information block."),
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2020-02-09 Hannes Domani <ssbssa@yahoo.de>
|
||||
|
||||
* win32-low.c (win32_clear_inferiors): Reset siginfo_er.
|
||||
(handle_exception): Set siginfo_er.
|
||||
(win32_xfer_siginfo): New function.
|
||||
|
||||
2020-02-07 Tom Tromey <tom@tromey.com>
|
||||
Pedro Alves <palves@redhat.com>
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ static int attaching = 0;
|
|||
static HANDLE current_process_handle = NULL;
|
||||
static DWORD current_process_id = 0;
|
||||
static DWORD main_thread_id = 0;
|
||||
static EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
|
||||
static enum gdb_signal last_sig = GDB_SIGNAL_0;
|
||||
|
||||
/* The current debug event from WaitForDebugEvent. */
|
||||
|
@ -801,6 +802,7 @@ win32_clear_inferiors (void)
|
|||
CloseHandle (current_process_handle);
|
||||
|
||||
for_each_thread (delete_thread_info);
|
||||
siginfo_er.ExceptionCode = 0;
|
||||
clear_inferiors ();
|
||||
}
|
||||
|
||||
|
@ -1230,6 +1232,9 @@ handle_exception (struct target_waitstatus *ourstatus)
|
|||
{
|
||||
DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
|
||||
|
||||
memcpy (&siginfo_er, ¤t_event.u.Exception.ExceptionRecord,
|
||||
sizeof siginfo_er);
|
||||
|
||||
ourstatus->kind = TARGET_WAITKIND_STOPPED;
|
||||
|
||||
switch (code)
|
||||
|
@ -1772,6 +1777,29 @@ wince_hostio_last_error (char *buf)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Write Windows signal info. */
|
||||
|
||||
static int
|
||||
win32_xfer_siginfo (const char *annex, unsigned char *readbuf,
|
||||
unsigned const char *writebuf, CORE_ADDR offset, int len)
|
||||
{
|
||||
if (siginfo_er.ExceptionCode == 0)
|
||||
return -1;
|
||||
|
||||
if (readbuf == nullptr)
|
||||
return -1;
|
||||
|
||||
if (offset > sizeof (siginfo_er))
|
||||
return -1;
|
||||
|
||||
if (offset + len > sizeof (siginfo_er))
|
||||
len = sizeof (siginfo_er) - offset;
|
||||
|
||||
memcpy (readbuf, (char *) &siginfo_er + offset, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Write Windows OS Thread Information Block address. */
|
||||
|
||||
static int
|
||||
|
@ -1833,7 +1861,7 @@ static process_stratum_target win32_target_ops = {
|
|||
hostio_last_error_from_errno,
|
||||
#endif
|
||||
NULL, /* qxfer_osdata */
|
||||
NULL, /* qxfer_siginfo */
|
||||
win32_xfer_siginfo,
|
||||
NULL, /* supports_non_stop */
|
||||
NULL, /* async */
|
||||
NULL, /* start_non_stop */
|
||||
|
|
Loading…
Reference in New Issue