* [PATCH 1/2] Display ExceptionRecord for $_siginfo [not found] <20200117153140.2231-1-ssbssa.ref@yahoo.de> @ 2020-01-17 15:32 ` Hannes Domani via gdb-patches 2020-01-17 15:36 ` [PATCH 2/2] Use enums for human-readable exception information Hannes Domani via gdb-patches 2020-02-07 21:56 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Simon Marchi 0 siblings, 2 replies; 9+ messages in thread From: Hannes Domani via gdb-patches @ 2020-01-17 15:32 UTC (permalink / raw) To: gdb-patches Uses the $_siginfo convenience variable to show the last exception. The type looks like this: (gdb) pt $_siginfo type = struct EXCEPTION_RECORD { unsigned int ExceptionCode; unsigned int ExceptionFlags; struct EXCEPTION_RECORD *ExceptionRecord; void *ExceptionAddress; unsigned int NumberParameters; void *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 = {0x1, 0x123, 0x0 <repeats 13 times>} } (gdb) p/x $_siginfo.ExceptionCode $2 = 0xc0000005 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-01-17 Hannes Domani <ssbssa@yahoo.de> * 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. gdb/gdbserver/ChangeLog: 2020-01-17 Hannes Domani <ssbssa@yahoo.de> * win32-low.c (win32_clear_inferiors): Reset siginfo_er. (handle_exception): Set siginfo_er. (win32_xfer_siginfo): New function. --- gdb/gdbserver/win32-low.c | 28 +++++++++++++++++- gdb/windows-nat.c | 29 ++++++++++++++++++ gdb/windows-tdep.c | 62 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c index 2c4a9b1074..223561be54 100644 --- a/gdb/gdbserver/win32-low.c +++ b/gdb/gdbserver/win32-low.c @@ -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,27 @@ wince_hostio_last_error (char *buf) } #endif +static int +win32_xfer_siginfo (const char *annex, unsigned char *readbuf, + unsigned const char *writebuf, CORE_ADDR offset, int len) +{ + if (!siginfo_er.ExceptionCode) + return -1; + + if (!readbuf) + 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 +1859,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 */ diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 901e64263c..824ff4b322 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -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; @@ -1166,6 +1167,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. */ @@ -2862,6 +2865,7 @@ windows_nat_target::mourn_inferior () CHECK (CloseHandle (current_process_handle)); open_process_used = 0; } + siginfo_er.ExceptionCode = 0; inf_child_target::mourn_inferior (); } @@ -2994,6 +2998,28 @@ windows_xfer_shared_libraries (struct target_ops *ops, return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; } +static enum target_xfer_status +windows_xfer_siginfo (gdb_byte *readbuf, ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len) +{ + if (!siginfo_er.ExceptionCode) + return TARGET_XFER_E_IO; + + if (!readbuf) + 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, @@ -3009,6 +3035,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) { diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c index 1fc2748581..50efa31709 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -153,6 +153,26 @@ 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; + }; + +static void * +init_windows_gdbarch_data (struct gdbarch *gdbarch) +{ + return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct windows_gdbarch_data); +} + +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 * @@ -648,6 +668,43 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal) return -1; } +static struct type * +windows_get_siginfo_type (struct gdbarch *gdbarch) +{ + struct windows_gdbarch_data *windows_gdbarch_data; + struct type *uint_type, *void_ptr_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; + + uint_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), + 1, "unsigned int"); + void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); + + 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", uint_type); + append_composite_type_field (siginfo_type, "ExceptionFlags", uint_type); + append_composite_type_field (siginfo_type, "ExceptionRecord", + siginfo_ptr_type); + append_composite_type_field (siginfo_type, "ExceptionAddress", + void_ptr_type); + append_composite_type_field (siginfo_type, "NumberParameters", uint_type); + append_composite_type_field_aligned (siginfo_type, "ExceptionInformation", + lookup_array_range_type (void_ptr_type, + 0, 14), + TYPE_LENGTH (void_ptr_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. */ @@ -667,6 +724,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. */ @@ -682,6 +741,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."), -- 2.25.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] Use enums for human-readable exception information. 2020-01-17 15:32 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Hannes Domani via gdb-patches @ 2020-01-17 15:36 ` Hannes Domani via gdb-patches 2020-02-07 22:02 ` Simon Marchi 2020-02-07 21:56 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Simon Marchi 1 sibling, 1 reply; 9+ messages in thread From: Hannes Domani via gdb-patches @ 2020-01-17 15:36 UTC (permalink / raw) To: gdb-patches Changes to $_siginfo type to this: (gdb) pt $_siginfo type = struct EXCEPTION_RECORD { enum ExceptionCode ExceptionCode; unsigned int ExceptionFlags; struct EXCEPTION_RECORD *ExceptionRecord; void *ExceptionAddress; unsigned int NumberParameters; union { void *ExceptionInformation[15]; struct {...} AccessViolationInformation; }; } (gdb) pt $_siginfo.ExceptionCode type = enum ExceptionCode {FATAL_APP_EXIT = 1073741845, DBG_CONTROL_C = 1073807365, DBG_CONTROL_BREAK = 1073807368, DATATYPE_MISALIGNMENT = 2147483650, BREAKPOINT, SINGLE_STEP, ACCESS_VIOLATION = 3221225477, IN_PAGE_ERROR, ILLEGAL_INSTRUCTION = 3221225501, NONCONTINUABLE_EXCEPTION = 3221225509, INVALID_DISPOSITION, ARRAY_BOUNDS_EXCEEDED = 3221225612, FLOAT_DENORMAL_OPERAND, FLOAT_DIVIDE_BY_ZERO, FLOAT_INEXACT_RESULT, FLOAT_INVALID_OPERATION, FLOAT_OVERFLOW, FLOAT_STACK_CHECK, FLOAT_UNDERFLOW, INTEGER_DIVIDE_BY_ZERO, INTEGER_OVERFLOW, PRIV_INSTRUCTION, STACK_OVERFLOW = 3221225725, FAST_FAIL = 3221226505} (gdb) pt $_siginfo.AccessViolationInformation type = struct { enum ViolationType Type; void *Address; } (gdb) pt $_siginfo.AccessViolationInformation.Type type = enum ViolationType {READ_ACCESS_VIOLATION, WRITE_ACCESS_VIOLATION, DATA_EXECUTION_PREVENTION_VIOLATION = 8} Which makes it easier to understand the reason of the exception: (gdb) p $_siginfo $1 = { ExceptionCode = ACCESS_VIOLATION, ExceptionFlags = 0, ExceptionRecord = 0x0, ExceptionAddress = 0x401632 <main+18>, NumberParameters = 2, { ExceptionInformation = {0x1, 0x123, 0x0 <repeats 13 times>}, AccessViolationInformation = { Type = WRITE_ACCESS_VIOLATION, Address = 0x123 } } } gdb/ChangeLog: 2020-01-17 Hannes Domani <ssbssa@yahoo.de> * windows-tdep.c (struct enum_value_name): New struct. (create_enum): New function. (windows_get_siginfo_type): Create and use enum types. --- gdb/windows-tdep.c | 93 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 7 deletions(-) diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c index 50efa31709..080b3a89d2 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -668,12 +668,75 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal) return -1; } +struct enum_value_name +{ + uint32_t value; + const char *name; +}; + +static struct type * +create_enum (struct gdbarch *gdbarch, int bit, const char *name, + const struct enum_value_name *values, int count) +{ + struct type *type; + int i; + + type = arch_type (gdbarch, TYPE_CODE_ENUM, bit, name); + TYPE_NFIELDS (type) = count; + TYPE_FIELDS (type) = (struct field *) + TYPE_ZALLOC (type, sizeof (struct field) * count); + TYPE_UNSIGNED (type) = 1; + + for (i = 0; i < count; i++) + { + TYPE_FIELD_NAME (type, i) = values[i].name; + SET_FIELD_ENUMVAL (TYPE_FIELD (type, i), values[i].value); + } + + return type; +} + +static const struct enum_value_name exception_values[] = +{ + { 0x40000015, "FATAL_APP_EXIT" }, + { 0x40010005, "DBG_CONTROL_C" }, + { 0x40010008, "DBG_CONTROL_BREAK" }, + { 0x80000002, "DATATYPE_MISALIGNMENT" }, + { 0x80000003, "BREAKPOINT" }, + { 0x80000004, "SINGLE_STEP" }, + { 0xC0000005, "ACCESS_VIOLATION" }, + { 0xC0000006, "IN_PAGE_ERROR" }, + { 0xC000001D, "ILLEGAL_INSTRUCTION" }, + { 0xC0000025, "NONCONTINUABLE_EXCEPTION" }, + { 0xC0000026, "INVALID_DISPOSITION" }, + { 0xC000008C, "ARRAY_BOUNDS_EXCEEDED" }, + { 0xC000008D, "FLOAT_DENORMAL_OPERAND" }, + { 0xC000008E, "FLOAT_DIVIDE_BY_ZERO" }, + { 0xC000008F, "FLOAT_INEXACT_RESULT" }, + { 0xC0000090, "FLOAT_INVALID_OPERATION" }, + { 0xC0000091, "FLOAT_OVERFLOW" }, + { 0xC0000092, "FLOAT_STACK_CHECK" }, + { 0xC0000093, "FLOAT_UNDERFLOW" }, + { 0xC0000094, "INTEGER_DIVIDE_BY_ZERO" }, + { 0xC0000095, "INTEGER_OVERFLOW" }, + { 0xC0000096, "PRIV_INSTRUCTION" }, + { 0xC00000FD, "STACK_OVERFLOW" }, + { 0xC0000409, "FAST_FAIL" }, +}; + +static const struct enum_value_name violation_values[] = +{ + { 0, "READ_ACCESS_VIOLATION" }, + { 1, "WRITE_ACCESS_VIOLATION" }, + { 8, "DATA_EXECUTION_PREVENTION_VIOLATION" }, +}; + static struct type * windows_get_siginfo_type (struct gdbarch *gdbarch) { struct windows_gdbarch_data *windows_gdbarch_data; - struct type *uint_type, *void_ptr_type; - struct type *siginfo_ptr_type, *siginfo_type; + struct type *uint_type, *void_ptr_type, *code_enum, *violation_enum; + struct type *violation_type, *para_type, *siginfo_ptr_type, *siginfo_type; windows_gdbarch_data = get_windows_gdbarch_data (gdbarch); if (windows_gdbarch_data->siginfo_type != NULL) @@ -683,22 +746,38 @@ windows_get_siginfo_type (struct gdbarch *gdbarch) 1, "unsigned int"); void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); + code_enum = create_enum (gdbarch, gdbarch_int_bit (gdbarch), + "ExceptionCode", exception_values, + ARRAY_SIZE (exception_values)); + + violation_enum = create_enum (gdbarch, gdbarch_ptr_bit (gdbarch), + "ViolationType", violation_values, + ARRAY_SIZE (violation_values)); + + violation_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + append_composite_type_field (violation_type, "Type", violation_enum); + append_composite_type_field (violation_type, "Address", void_ptr_type); + + para_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); + append_composite_type_field (para_type, "ExceptionInformation", + lookup_array_range_type (void_ptr_type, 0, 14)); + append_composite_type_field (para_type, "AccessViolationInformation", + violation_type); + 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", uint_type); + append_composite_type_field (siginfo_type, "ExceptionCode", code_enum); append_composite_type_field (siginfo_type, "ExceptionFlags", uint_type); append_composite_type_field (siginfo_type, "ExceptionRecord", siginfo_ptr_type); append_composite_type_field (siginfo_type, "ExceptionAddress", void_ptr_type); append_composite_type_field (siginfo_type, "NumberParameters", uint_type); - append_composite_type_field_aligned (siginfo_type, "ExceptionInformation", - lookup_array_range_type (void_ptr_type, - 0, 14), - TYPE_LENGTH (void_ptr_type)); + append_composite_type_field_aligned (siginfo_type, "", + para_type, TYPE_LENGTH (void_ptr_type)); windows_gdbarch_data->siginfo_type = siginfo_type; -- 2.25.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] Use enums for human-readable exception information. 2020-01-17 15:36 ` [PATCH 2/2] Use enums for human-readable exception information Hannes Domani via gdb-patches @ 2020-02-07 22:02 ` Simon Marchi 0 siblings, 0 replies; 9+ messages in thread From: Simon Marchi @ 2020-02-07 22:02 UTC (permalink / raw) To: Hannes Domani, gdb-patches On 2020-01-17 10:31 a.m., Hannes Domani via gdb-patches wrote: > Changes to $_siginfo type to this: > > (gdb) pt $_siginfo > type = struct EXCEPTION_RECORD { > enum ExceptionCode ExceptionCode; > unsigned int ExceptionFlags; > struct EXCEPTION_RECORD *ExceptionRecord; > void *ExceptionAddress; > unsigned int NumberParameters; > union { > void *ExceptionInformation[15]; > struct {...} AccessViolationInformation; > }; > } > (gdb) pt $_siginfo.ExceptionCode > type = enum ExceptionCode {FATAL_APP_EXIT = 1073741845, > DBG_CONTROL_C = 1073807365, DBG_CONTROL_BREAK = 1073807368, > DATATYPE_MISALIGNMENT = 2147483650, BREAKPOINT, SINGLE_STEP, > ACCESS_VIOLATION = 3221225477, IN_PAGE_ERROR, > ILLEGAL_INSTRUCTION = 3221225501, NONCONTINUABLE_EXCEPTION = 3221225509, > INVALID_DISPOSITION, ARRAY_BOUNDS_EXCEEDED = 3221225612, > FLOAT_DENORMAL_OPERAND, FLOAT_DIVIDE_BY_ZERO, FLOAT_INEXACT_RESULT, > FLOAT_INVALID_OPERATION, FLOAT_OVERFLOW, FLOAT_STACK_CHECK, > FLOAT_UNDERFLOW, INTEGER_DIVIDE_BY_ZERO, INTEGER_OVERFLOW, > PRIV_INSTRUCTION, STACK_OVERFLOW = 3221225725, FAST_FAIL = 3221226505} > (gdb) pt $_siginfo.AccessViolationInformation > type = struct { > enum ViolationType Type; > void *Address; > } > (gdb) pt $_siginfo.AccessViolationInformation.Type > type = enum ViolationType {READ_ACCESS_VIOLATION, WRITE_ACCESS_VIOLATION, > DATA_EXECUTION_PREVENTION_VIOLATION = 8} > > Which makes it easier to understand the reason of the exception: > > (gdb) p $_siginfo > $1 = { > ExceptionCode = ACCESS_VIOLATION, > ExceptionFlags = 0, > ExceptionRecord = 0x0, > ExceptionAddress = 0x401632 <main+18>, > NumberParameters = 2, > { > ExceptionInformation = {0x1, 0x123, 0x0 <repeats 13 times>}, > AccessViolationInformation = { > Type = WRITE_ACCESS_VIOLATION, > Address = 0x123 > } > } > } Well, this kind of goes against the last comment I left on patch 1 (to use the actual types found in the real structure), but I think that what you are suggesting here is quite convenient, so I wouldn't be against doing something like that. Please add a bit of comments to your code to explain what you are doing. Since you are inventing types that don't exist in the documentation, it's not obvious to know what this is doing. Simon ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] Display ExceptionRecord for $_siginfo 2020-01-17 15:32 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Hannes Domani via gdb-patches 2020-01-17 15:36 ` [PATCH 2/2] Use enums for human-readable exception information Hannes Domani via gdb-patches @ 2020-02-07 21:56 ` Simon Marchi 2020-02-07 22:07 ` Simon Marchi ` (2 more replies) 1 sibling, 3 replies; 9+ messages in thread From: Simon Marchi @ 2020-02-07 21:56 UTC (permalink / raw) To: Hannes Domani, gdb-patches On 2020-01-17 10:31 a.m., Hannes Domani via gdb-patches wrote: > diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c > index 901e64263c..824ff4b322 100644 > --- a/gdb/windows-nat.c > +++ b/gdb/windows-nat.c > @@ -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 */ Huh... I was going to say that it shouldn't be a global variable, but a per-inferior thing (or is it per-thread?), but pretty much all the state is already global... so I guess it's fine. I gather that the windows-nat does not support debugging multiple inferiors? Same for win32-low in gdbserver? > > /* Counts of things. */ > static int exception_count = 0; > @@ -1166,6 +1167,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. */ > @@ -2862,6 +2865,7 @@ windows_nat_target::mourn_inferior () > CHECK (CloseHandle (current_process_handle)); > open_process_used = 0; > } > + siginfo_er.ExceptionCode = 0; > inf_child_target::mourn_inferior (); > } > > @@ -2994,6 +2998,28 @@ windows_xfer_shared_libraries (struct target_ops *ops, > return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; > } > > +static enum target_xfer_status > +windows_xfer_siginfo (gdb_byte *readbuf, ULONGEST offset, ULONGEST len, > + ULONGEST *xfered_len) > +{ > + if (!siginfo_er.ExceptionCode) siginfo_er.ExceptionCode != 0 > + return TARGET_XFER_E_IO; > + > + if (!readbuf) 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, > @@ -3009,6 +3035,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) > { > diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c > index 1fc2748581..50efa31709 100644 > --- a/gdb/windows-tdep.c > +++ b/gdb/windows-tdep.c > @@ -153,6 +153,26 @@ 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; > + }; Unindent the curly braces and the field: { struct type *siginfo_type; } I know there are some structures formatted this way, but the new ones we add are aligned on column 0. > + > +static void * > +init_windows_gdbarch_data (struct gdbarch *gdbarch) > +{ > + return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct windows_gdbarch_data); > +} > + > +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 * > @@ -648,6 +668,43 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal) > return -1; > } > > +static struct type * > +windows_get_siginfo_type (struct gdbarch *gdbarch) > +{ > + struct windows_gdbarch_data *windows_gdbarch_data; > + struct type *uint_type, *void_ptr_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; > + > + uint_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), > + 1, "unsigned int"); You should be able to get this one from builtin_type (gdbarch)->builtin_unsigned_int. > + void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); > + > + 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", uint_type); > + append_composite_type_field (siginfo_type, "ExceptionFlags", uint_type); > + append_composite_type_field (siginfo_type, "ExceptionRecord", > + siginfo_ptr_type); > + append_composite_type_field (siginfo_type, "ExceptionAddress", > + void_ptr_type); > + append_composite_type_field (siginfo_type, "NumberParameters", uint_type); > + append_composite_type_field_aligned (siginfo_type, "ExceptionInformation", > + lookup_array_range_type (void_ptr_type, > + 0, 14), > + TYPE_LENGTH (void_ptr_type)); Shouldn't you use "DWORD" and other types named like what is found in the real structure, instead of plain "unsigned int"? Like what is done in windows_get_tlb_type? As a user, I would expect that "ptype $_siginfo" shows me "DWORD" and not "unsigned int", don't you think? Simon ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] Display ExceptionRecord for $_siginfo 2020-02-07 21:56 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Simon Marchi @ 2020-02-07 22:07 ` Simon Marchi 2020-02-07 22:17 ` Hannes Domani via gdb-patches 2020-02-07 22:14 ` Hannes Domani via gdb-patches 2020-02-11 15:28 ` Tom Tromey 2 siblings, 1 reply; 9+ messages in thread From: Simon Marchi @ 2020-02-07 22:07 UTC (permalink / raw) To: Hannes Domani, gdb-patches Btw, as mentioned here: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record#remarks The layout of the structure is different depending on if the debugged process is 32 or 64 bits. From what I understand, you code adapts to both, since it uses gdbarch_ptr_bit and uses proper alignment for the ExceptionInformation field, but I wanted to point it out just to be sure. Simon ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] Display ExceptionRecord for $_siginfo 2020-02-07 22:07 ` Simon Marchi @ 2020-02-07 22:17 ` Hannes Domani via gdb-patches 0 siblings, 0 replies; 9+ messages in thread From: Hannes Domani via gdb-patches @ 2020-02-07 22:17 UTC (permalink / raw) To: Gdb-patches Am Freitag, 7. Februar 2020, 23:07:08 MEZ hat Simon Marchi <simark@simark.ca> Folgendes geschrieben: > Btw, as mentioned here: > > https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record#remarks > > The layout of the structure is different depending on if the debugged process is 32 or 64 bits. > > From what I understand, you code adapts to both, since it uses gdbarch_ptr_bit and uses proper > alignment for the ExceptionInformation field, but I wanted to point it out just to be sure. Yes, that's right. I will add some comments to make this more clear. Regards Hannes Domani ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] Display ExceptionRecord for $_siginfo 2020-02-07 21:56 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Simon Marchi 2020-02-07 22:07 ` Simon Marchi @ 2020-02-07 22:14 ` Hannes Domani via gdb-patches 2020-02-11 15:28 ` Tom Tromey 2 siblings, 0 replies; 9+ messages in thread From: Hannes Domani via gdb-patches @ 2020-02-07 22:14 UTC (permalink / raw) To: Gdb-patches Am Freitag, 7. Februar 2020, 22:56:18 MEZ hat Simon Marchi <simark@simark.ca> Folgendes geschrieben: > On 2020-01-17 10:31 a.m., Hannes Domani via gdb-patches wrote: > > diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c > > index 901e64263c..824ff4b322 100644 > > --- a/gdb/windows-nat.c > > +++ b/gdb/windows-nat.c > > @@ -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 */ > > Huh... I was going to say that it shouldn't be a global variable, but a per-inferior > thing (or is it per-thread?), but pretty much all the state is already global... so > I guess it's fine. I gather that the windows-nat does not support debugging multiple > inferiors? Same for win32-low in gdbserver? > > > > > /* Counts of things. */ > > static int exception_count = 0; > > @@ -1166,6 +1167,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. */ > > @@ -2862,6 +2865,7 @@ windows_nat_target::mourn_inferior () > > CHECK (CloseHandle (current_process_handle)); > > open_process_used = 0; > > } > > + siginfo_er.ExceptionCode = 0; > > inf_child_target::mourn_inferior (); > > } > > > > @@ -2994,6 +2998,28 @@ windows_xfer_shared_libraries (struct target_ops *ops, > > return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF; > > } > > > > +static enum target_xfer_status > > +windows_xfer_siginfo (gdb_byte *readbuf, ULONGEST offset, ULONGEST len, > > + ULONGEST *xfered_len) > > +{ > > + if (!siginfo_er.ExceptionCode) > > siginfo_er.ExceptionCode != 0 > > > + return TARGET_XFER_E_IO; > > + > > + if (!readbuf) > > 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, > > @@ -3009,6 +3035,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) > > { > > diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c > > index 1fc2748581..50efa31709 100644 > > --- a/gdb/windows-tdep.c > > +++ b/gdb/windows-tdep.c > > @@ -153,6 +153,26 @@ 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; > > + }; > > Unindent the curly braces and the field: > > { > struct type *siginfo_type; > } > > I know there are some structures formatted this way, but the new ones we add are > aligned on column 0. OK, I fill fix all these coding style problems and try to remember them. > > + > > +static void * > > +init_windows_gdbarch_data (struct gdbarch *gdbarch) > > +{ > > + return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct windows_gdbarch_data); > > +} > > + > > +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 * > > @@ -648,6 +668,43 @@ windows_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal) > > return -1; > > } > > > > +static struct type * > > +windows_get_siginfo_type (struct gdbarch *gdbarch) > > +{ > > + struct windows_gdbarch_data *windows_gdbarch_data; > > + struct type *uint_type, *void_ptr_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; > > + > > + uint_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), > > + 1, "unsigned int"); > > You should be able to get this one from builtin_type (gdbarch)->builtin_unsigned_int. Good to know. > > + void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); > > + > > + 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", uint_type); > > + append_composite_type_field (siginfo_type, "ExceptionFlags", uint_type); > > + append_composite_type_field (siginfo_type, "ExceptionRecord", > > + siginfo_ptr_type); > > + append_composite_type_field (siginfo_type, "ExceptionAddress", > > + void_ptr_type); > > + append_composite_type_field (siginfo_type, "NumberParameters", uint_type); > > + append_composite_type_field_aligned (siginfo_type, "ExceptionInformation", > > + lookup_array_range_type (void_ptr_type, > > + 0, 14), > > + TYPE_LENGTH (void_ptr_type)); > > > Shouldn't you use "DWORD" and other types named like what is found in the > real structure, instead of plain "unsigned int"? Like what is done in > windows_get_tlb_type? > > As a user, I would expect that "ptype $_siginfo" shows me "DWORD" and not > "unsigned int", don't you think? Personally I didn't really care what the name of the type is, but you are right, it probably is what users expect, so I will change the type names accordingly. Regards Hannes Domani ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] Display ExceptionRecord for $_siginfo 2020-02-07 21:56 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Simon Marchi 2020-02-07 22:07 ` Simon Marchi 2020-02-07 22:14 ` Hannes Domani via gdb-patches @ 2020-02-11 15:28 ` Tom Tromey 2020-02-11 16:56 ` Hannes Domani via gdb-patches 2 siblings, 1 reply; 9+ messages in thread From: Tom Tromey @ 2020-02-11 15:28 UTC (permalink / raw) To: Simon Marchi; +Cc: Hannes Domani, gdb-patches >>>>> "Simon" == Simon Marchi <simark@simark.ca> writes: Simon> Huh... I was going to say that it shouldn't be a global variable, Simon> but a per-inferior thing (or is it per-thread?), but pretty much Simon> all the state is already global... so I guess it's fine. I Simon> gather that the windows-nat does not support debugging multiple Simon> inferiors? Same for win32-low in gdbserver? Yes, that's correct. I think it could be implemented, just nobody has done it yet. Tom ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] Display ExceptionRecord for $_siginfo 2020-02-11 15:28 ` Tom Tromey @ 2020-02-11 16:56 ` Hannes Domani via gdb-patches 0 siblings, 0 replies; 9+ messages in thread From: Hannes Domani via gdb-patches @ 2020-02-11 16:56 UTC (permalink / raw) To: Gdb-patches Am Dienstag, 11. Februar 2020, 16:28:37 MEZ hat Tom Tromey <tom@tromey.com> Folgendes geschrieben: > >>>>> "Simon" == Simon Marchi <simark@simark.ca> writes: > > Simon> Huh... I was going to say that it shouldn't be a global variable, > Simon> but a per-inferior thing (or is it per-thread?), but pretty much > Simon> all the state is already global... so I guess it's fine. I > Simon> gather that the windows-nat does not support debugging multiple > Simon> inferiors? Same for win32-low in gdbserver? > > Yes, that's correct. I think it could be implemented, just nobody has > done it yet. How does debugging multiple inferiors work exactly? Is this only possible with async mode (which doesn't work on Windows)? Regards Hannes Domani ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2020-02-11 16:56 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20200117153140.2231-1-ssbssa.ref@yahoo.de>
2020-01-17 15:32 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Hannes Domani via gdb-patches
2020-01-17 15:36 ` [PATCH 2/2] Use enums for human-readable exception information Hannes Domani via gdb-patches
2020-02-07 22:02 ` Simon Marchi
2020-02-07 21:56 ` [PATCH 1/2] Display ExceptionRecord for $_siginfo Simon Marchi
2020-02-07 22:07 ` Simon Marchi
2020-02-07 22:17 ` Hannes Domani via gdb-patches
2020-02-07 22:14 ` Hannes Domani via gdb-patches
2020-02-11 15:28 ` Tom Tromey
2020-02-11 16:56 ` Hannes Domani via gdb-patches
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox