From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id CdybDCqEkWqrYgsAWB0awg (envelope-from ) for ; Fri, 28 Aug 2026 08:50:50 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=aOj9lyg7; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 23B481E166; Fri, 28 Aug 2026 08:50:50 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 8A2D11E033 for ; Fri, 28 Aug 2026 08:50:48 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4E3794BA9012 for ; Fri, 28 Aug 2026 12:50:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4E3794BA9012 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=aOj9lyg7 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by sourceware.org (Postfix) with ESMTPS id 27D4F4BA2E07 for ; Fri, 28 Aug 2026 12:50:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 27D4F4BA2E07 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 27D4F4BA2E07 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=198.175.65.12 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787921420; cv=none; b=gXcE2JjZr8CujBNOF1nznVft7V8uS27B6KqEEMou8OkZ9MzwhLmhtd9QXCh8OwAMmUTGy8y+XgXoHpWcek6TiQQD9TQEUU/f/C/E4mXOYXjK6Xr4JRy4HeBeokORuncW40v1r7/KG49y2PgxuDk2Xk5rRFmvMEa0JT/0YepDBw8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787921420; c=relaxed/simple; bh=HfBl+kWyuzvt9H8IQAOIJIztkOMGZ2BkeUkEN8iObDY=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=JZzsmbH5lDUazy4bmGnxP1HMIhhTq1SF5obHhnn0z3gJCs2B5Z7gJfRMkFFuvdAvYPqpjIGflXri/+ZT6pz2cVsCW/iwH+g72yb5Biwhi8+wdgjVeHVMBs6FPy9z3g8x7jn3ht4oAoPMYc1eiQqbkI4SEF3Q/RgfdG+69stxYRM= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=aOj9lyg7 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 27D4F4BA2E07 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787921421; x=1819457421; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=HfBl+kWyuzvt9H8IQAOIJIztkOMGZ2BkeUkEN8iObDY=; b=aOj9lyg7m3VvqyBn1sgPvhFCJF6w7iyOPAPc94lwckM8zT44IzNuYr49 mn+PJLF/skmIsSp6yGwf3ShKCi9yH+tksy946mzR2etIA/FKy2gLFNq1H 5AihDaFXPUrnlJgOfv3oW2+eWO1urGepR0lYMqEa9AbN0RvPsTjsDoD86 vi4izJjaw5T9GtylH/W9jKCTs5B+pRU9qqZrxMs6hbe+3Jq9VnDRuZ4e5 +W30yLBB9lWO7WE4OI0qvd5Q7bac2inbiyZP/EZzL+AaskYFeQhy51cco Y3Vq9sOeSNNhd3F97EjqBP4J0HZ7U0/vK6LijCUlOY+TgoMRddD39Rbz5 g==; X-CSE-ConnectionGUID: El0vqTFdQZ+5yxLiz2voSA== X-CSE-MsgGUID: jYjVmo4cSs22Ff3wfIlvAw== X-IronPort-AV: E=McAfee;i="6800,10657,11888"; a="99943167" X-IronPort-AV: E=Sophos;i="6.25,248,1779174000"; d="scan'208";a="99943167" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Aug 2026 05:50:19 -0700 X-CSE-ConnectionGUID: +EEi3y6US2OfCRR14Erl6w== X-CSE-MsgGUID: m6ZogYm6R7uncOMb2eFpPQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,248,1779174000"; d="scan'208";a="266341604" Received: from dut1583dg2frd.igk.intel.com (HELO localhost) ([10.211.179.243]) by orviesa006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Aug 2026 05:50:18 -0700 From: Klaus Gerlicher To: gdb-patches@sourceware.org Cc: TankutBaris.Aktemur@amd.com, aburgess@redhat.com, simark@simark.ca Subject: [PATCH v5 1/1] gdb: avoid conversion of SIGSEGV to SIGTRAP on user breakpoints Date: Fri, 28 Aug 2026 12:50:03 +0000 Message-Id: <20260828125003.253648-1-klaus.gerlicher@intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org From: "Gerlicher, Klaus" 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. This conversion logic assumes that when these signals occur at a breakpoint location, the signal was actually caused by hitting the breakpoint rather than a genuine fault. However, some architectures have "imprecise page fault reporting," where a memory access violation can be reported several instructions after the faulting instruction. For example: INSN1 <-- generates a SIGSEGV INSN2 INSN3 <-- breakpoint installed here If INSN1 causes a memory access violation, the backend may report the stop at INSN3, where a breakpoint happens to be installed. GDB's logic then incorrectly assumes "there is a breakpoint at INSN3, so this SIGSEGV must mean we hit the breakpoint" and converts it to SIGTRAP. On architectures with imprecise fault reporting, this is wrong: if a breakpoint is never reported via SIGSEGV, then receiving a SIGSEGV at a breakpoint location means we have a genuine SIGSEGV, not a breakpoint hit. 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. Architectures with imprecise fault reporting should override this to return true. --- gdb/gdbarch-gen.c | 22 ++++++++++++++++++++++ gdb/gdbarch-gen.h | 24 ++++++++++++++++++++++++ gdb/gdbarch_components.py | 29 +++++++++++++++++++++++++++++ gdb/infrun.c | 4 +++- 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c index 6008003466c..b3a699598f9 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 != nullptr); + gdb_assert (gdbarch->imprecise_pagefault_reporting != nullptr); + 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 6eda8693d58..3175e712c55 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -1758,3 +1758,27 @@ void set_gdbarch_shadow_stack_push (struct gdbarch *gdbarch, gdbarch_shadow_stac using gdbarch_get_shadow_stack_pointer_ftype = std::optional (struct gdbarch *gdbarch, regcache *regcache, bool &shadow_stack_enabled); std::optional 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 page fault reporting, where a + memory access violation may be reported several instructions after the + faulting instruction. + + On such architectures, if an instruction causes a memory access violation, + the backend may report the stop at a later instruction where a breakpoint + happens to be installed. GDB's normal logic would incorrectly assume that + the SIGSEGV was caused by hitting the breakpoint and convert it to SIGTRAP. + + However, if an architecture never reports breakpoints via SIGSEGV (e.g., + breakpoints are always reported via a dedicated mechanism), then receiving + a SIGSEGV at a breakpoint location means we have a genuine SIGSEGV, not a + breakpoint hit. + + Return true for architectures with imprecise fault reporting to disable the + SIGSEGV-to-SIGTRAP conversion. The default is false (conversion enabled) + to preserve existing behavior for architectures where breakpoints may be + reported as SIGSEGV (e.g., executing a breakpoint instruction on a + non-executable stack). */ + +using gdbarch_imprecise_pagefault_reporting_ftype = bool (); +bool gdbarch_imprecise_pagefault_reporting (struct gdbarch *gdbarch); +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 d8b2d114909..09d3130e753 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -2789,3 +2789,32 @@ SHADOW_STACK_ENABLED to false. predefault="default_get_shadow_stack_pointer", invalid=False, ) + +Function( + comment=""" +Returns true if architecture has imprecise page fault reporting, where a +memory access violation may be reported several instructions after the +faulting instruction. + +On such architectures, if an instruction causes a memory access violation, +the backend may report the stop at a later instruction where a breakpoint +happens to be installed. GDB's normal logic would incorrectly assume that +the SIGSEGV was caused by hitting the breakpoint and convert it to SIGTRAP. + +However, if an architecture never reports breakpoints via SIGSEGV (e.g., +breakpoints are always reported via a dedicated mechanism), then receiving +a SIGSEGV at a breakpoint location means we have a genuine SIGSEGV, not a +breakpoint hit. + +Return true for architectures with imprecise fault reporting to disable the +SIGSEGV-to-SIGTRAP conversion. The default is false (conversion enabled) +to preserve existing behavior for architectures where breakpoints may be +reported as SIGSEGV (e.g., executing a breakpoint instruction on a +non-executable stack). +""", + 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) 99143-0 www.intel.de Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman Chairperson of the Supervisory Board: Sonja Pierer Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.