[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.