From patchwork Sat Feb 8 16:26:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Terekhov, Mikhail via Gdb-patches" X-Patchwork-Id: 37770 Received: (qmail 99486 invoked by alias); 8 Feb 2020 16:26:53 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 99474 invoked by uid 89); 8 Feb 2020 16:26:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=15330 X-HELO: sonic301-22.consmr.mail.ir2.yahoo.com Received: from sonic301-22.consmr.mail.ir2.yahoo.com (HELO sonic301-22.consmr.mail.ir2.yahoo.com) (77.238.176.99) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 08 Feb 2020 16:26:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1581179206; bh=5q4Er+ttMycnxK0nsB3HR2aO8wtBtFrYKmgbQDl+/HA=; h=From:To:Subject:Date:References:From:Subject; b=EKdlklqndISBFxRSjUsrF/RxLmgWXsKOYW4MIMULC671IIimMKsYnZvM8keGEjMk4VrCLulaXaIB8Ex11SAVBEMCqMJbScMWbWJizPLnOdyYOIWpU4G0JH7mJUaxb48tEy2xv+j+o8uSdaqqIooeKFCwWui37Ioib4wdO9dKKrefhLyZqqbgxexvYu1z16MzjNwgXz/d02CGjkDB5kIDTdW83esoF4HduLECAWcNaQgLcqBfZvXzmOsMDJtMKMyIjHjMRmMqi6k9h4UwxMmV79keZlnvKKPrdx5FPFPteVMuCP3hNkQhTMct5WHf97k/MNdS26TQdHA1IweJx79Wbg== Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ir2.yahoo.com with HTTP; Sat, 8 Feb 2020 16:26:46 +0000 Received: by smtp422.mail.ir2.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 0733abcbb6ba962e7b0d5cf63f3ad1a7; Sat, 08 Feb 2020 16:26:45 +0000 (UTC) X-Patchwork-Original-From: "Hannes Domani via gdb-patches" From: "Terekhov, Mikhail via Gdb-patches" Reply-To: Hannes Domani To: gdb-patches@sourceware.org Subject: [PATCH v2 1/2] Display ExceptionRecord for $_siginfo Date: Sat, 8 Feb 2020 17:26:13 +0100 Message-Id: <20200208162614.4918-1-ssbssa@yahoo.de> MIME-Version: 1.0 References: <20200208162614.4918-1-ssbssa.ref@yahoo.de> Content-Length: 9897 X-IsSubscribed: yes 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 , NumberParameters = 2, ExceptionInformation = {1, 291, 0 } } (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-08 Hannes Domani * 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-08 Hannes Domani * win32-low.c (win32_clear_inferiors): Reset siginfo_er. (handle_exception): Set siginfo_er. (win32_xfer_siginfo): New function. --- v2: - coding style fixes - more comments - use documented field type names in EXCEPTION_RECORD --- gdb/windows-nat.c | 31 +++++++++++++++++++ gdb/windows-tdep.c | 72 +++++++++++++++++++++++++++++++++++++++++++ gdbserver/win32-low.c | 30 +++++++++++++++++- 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 366c98fbf3..76fcdd6bd4 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; @@ -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) { diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c index 6c9632d035..ad65b1b403 100644 --- a/gdb/windows-tdep.c +++ b/gdb/windows-tdep.c @@ -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."), diff --git a/gdbserver/win32-low.c b/gdbserver/win32-low.c index 2c4a9b1074..9d0343788f 100644 --- a/gdbserver/win32-low.c +++ b/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,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 */