[PATCH v4 1/1] gdb: avoid conversion of SIGSEGV to SIGTRAP on user breakpoints
Klaus Gerlicher <[email protected]>
| Newsgroups | gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
From: "Gerlicher, Klaus" <[email protected]> GDB converts signals GDB_SIGNAL_ILL, GDB_SIGNAL_SEGV and GDB_SIGNAL_EMT to GDB_SIGNAL_TRAP if a breakpoint is inserted at the fault location. If, due to imprecise page fault reporting, a breakpoint is at the same address as the fault address, this signal would always be reported as GDB_SIGNAL_TRAP. Add a new gdbarch function, imprecise_pagefault_reporting, that allows the signal conversion from GDB_SIGNAL_SEGV to GDB_SIGNAL_TRAP to be skipped for an architecture. The default is false (conversion enabled), preserving existing behavior. --- gdb/gdbarch-gen.c | 22 ++++++++++++++++++++++ gdb/gdbarch-gen.h | 7 +++++++ gdb/gdbarch_components.py | 12 ++++++++++++ gdb/infrun.c | 4 +++- 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c index f424fa2a86e..d9bb3e7078c 100644 --- a/gdb/gdbarch-gen.c +++ b/gdb/gdbarch-gen.c @@ -253,6 +253,7 @@ struct gdbarch gdbarch_core_parse_exec_context_ftype *core_parse_exec_context = default_core_parse_exec_context; gdbarch_shadow_stack_push_ftype *shadow_stack_push = nullptr; gdbarch_get_shadow_stack_pointer_ftype *get_shadow_stack_pointer = default_get_shadow_stack_pointer; + gdbarch_imprecise_pagefault_reporting_ftype *imprecise_pagefault_reporting = [] () -> bool {return false;}; }; /* Create a new ``struct gdbarch'' based on information provided by @@ -513,6 +514,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of core_parse_exec_context, invalid_p == 0. */ /* Skip verify of shadow_stack_push, has predicate. */ /* Skip verify of get_shadow_stack_pointer, invalid_p == 0. */ + /* Skip verify of imprecise_pagefault_reporting, invalid_p == 0. */ if (!log.empty ()) internal_error (_("verify_gdbarch: the following are invalid ...%s"), log.c_str ()); @@ -1339,6 +1341,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) gdb_printf (file, "gdbarch_dump: get_shadow_stack_pointer = <%s>\n", host_address_to_string (gdbarch->get_shadow_stack_pointer)); + gdb_printf (file, + "gdbarch_dump: imprecise_pagefault_reporting = <%s>\n", + host_address_to_string (gdbarch->imprecise_pagefault_reporting)); if (gdbarch->dump_tdep != nullptr) gdbarch->dump_tdep (gdbarch, file); } @@ -5286,3 +5291,20 @@ set_gdbarch_get_shadow_stack_pointer (struct gdbarch *gdbarch, { gdbarch->get_shadow_stack_pointer = get_shadow_stack_pointer; } + +bool +gdbarch_imprecise_pagefault_reporting (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->imprecise_pagefault_reporting != NULL); + if (gdbarch_debug >= 2) + gdb_printf (gdb_stdlog, "gdbarch_imprecise_pagefault_reporting called\n"); + return gdbarch->imprecise_pagefault_reporting (); +} + +void +set_gdbarch_imprecise_pagefault_reporting (struct gdbarch *gdbarch, + gdbarch_imprecise_pagefault_reporting_ftype imprecise_pagefault_reporting) +{ + gdbarch->imprecise_pagefault_reporting = imprecise_pagefault_reporting; +} diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index 678b308fba5..bb95df25eb6 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -1752,3 +1752,10 @@ void set_gdbarch_shadow_stack_push (struct gdbarch *gdbarch, gdbarch_shadow_stac using gdbarch_get_shadow_stack_pointer_ftype = std::optional<CORE_ADDR> (struct gdbarch *gdbarch, regcache *regcache, bool &shadow_stack_enabled); std::optional<CORE_ADDR> gdbarch_get_shadow_stack_pointer (struct gdbarch *gdbarch, regcache *regcache, bool &shadow_stack_enabled); void set_gdbarch_get_shadow_stack_pointer (struct gdbarch *gdbarch, gdbarch_get_shadow_stack_pointer_ftype *get_shadow_stack_pointer); + +/* Returns true if architecture has imprecise pagefault reporting. This is + used in conversion of SIGSEGV to SIGTRAP for an architecture. */ + +typedef bool (gdbarch_imprecise_pagefault_reporting_ftype) (); +extern bool gdbarch_imprecise_pagefault_reporting (struct gdbarch *gdbarch); +extern void set_gdbarch_imprecise_pagefault_reporting (struct gdbarch *gdbarch, gdbarch_imprecise_pagefault_reporting_ftype *imprecise_pagefault_reporting); diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index b9304d3036d..d903446435f 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -2781,3 +2781,15 @@ SHADOW_STACK_ENABLED to false. predefault="default_get_shadow_stack_pointer", invalid=False, ) + +Function( + comment=""" +Returns true if architecture has imprecise pagefault reporting. This is +used in conversion of SIGSEGV to SIGTRAP for an architecture. +""", + type="bool", + name="imprecise_pagefault_reporting", + params=[], + predefault="[] () -> bool {return false;}", + invalid=False +) diff --git a/gdb/infrun.c b/gdb/infrun.c index c0767e7f764..25ed7e7523f 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -6331,7 +6331,9 @@ handle_inferior_event (struct execution_control_state *ecs) stack. */ if (ecs->ws.kind () == TARGET_WAITKIND_STOPPED && (ecs->ws.sig () == GDB_SIGNAL_ILL - || ecs->ws.sig () == GDB_SIGNAL_SEGV + || (ecs->ws.sig () == GDB_SIGNAL_SEGV + && !gdbarch_imprecise_pagefault_reporting + (target_thread_architecture (ecs->event_thread->ptid))) || ecs->ws.sig () == GDB_SIGNAL_EMT)) { struct regcache *regcache = get_thread_regcache (ecs->event_thread); -- 2.34.1 Intel Deutschland GmbH Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany Tel: +49 89 991 430, www.intel.de Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell Chairperson of the Supervisory Board: Nicole Lau Registered Seat: Munich Commercial Register: Amtsgericht Muenchen HRB 186928