From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id sUvgI9Lf4WrtNj0AWB0awg (envelope-from ) for ; Wed, 28 Oct 2026 07:43:14 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PrsKNEF9; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 8F0F2378003; Wed, 28 Oct 2026 07:43:14 -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=ham 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 AEE44378002 for ; Wed, 28 Oct 2026 07:43:13 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1995F4BA2E1C for ; Wed, 28 Oct 2026 11:43:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1995F4BA2E1C Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PrsKNEF9 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 9F2094BA23D0 for ; Wed, 28 Oct 2026 11:41:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9F2094BA23D0 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9F2094BA23D0 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1793187673; cv=none; b=HNG8sZUC3fhdq3XRHqKNdcKAJQYhLKC1ri5eZ0yMnPN20dxnVe+bdi2hWpSetcKPRESR2BjIAgwQTyVZxVm8xWg+qNFZbIML5Fup6IEzPJq4z23prV2ASIlhrSl/8ErO+8Ynd/dprYU75HN09BRx6TFLV4ihaX2csB5ONU1MZEU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1793187673; c=relaxed/simple; bh=vAqDpekhQmd6qiUTSnmnviOvQ+Rq+B3F91GynAR/LeY=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=V+DqVPPWpxdDXpd7Q9x+xaH6HBNsjGIrbuxP0oEHUK9kkC2H80XDILXiyUeGAPfNLQXt49Z4t/YASfmNytLrG/4awCKCYZIi6bZKgW55Vc7RpLtPoJ+YzmA0NsXLoc1f//dU53qma2DDv9WN9ppF6bT/D/E2SWYWnu9JBXgFrhQ= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PrsKNEF9 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9F2094BA23D0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1793187672; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=867A7sMpdncPigJtqVsGMTnVHV10lVMiJCCGoHa64Uc=; b=PrsKNEF9W2WjGImNsJLXO9/aKl3Cb59Olk/j54l7oUm4ipcSOyRBV3+KzW+N39EEyPVqoE bEdy0KthQ0cwr27+lscMoa32WCXrXK1TQ9heuktM3d4HMU5jmsEW32OeBUSvKPCIHgXti+ 99yCo4xbTu64gRQGNEpHmSl6pMC0IDc= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-575-KXEnE41xNe-V6t3Li7uMNA-1; Wed, 28 Oct 2026 07:41:07 -0400 X-MC-Unique: KXEnE41xNe-V6t3Li7uMNA-1 X-Mimecast-MFC-AGG-ID: KXEnE41xNe-V6t3Li7uMNA_1793187666 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-48c4445512dso780803f8f.2 for ; Wed, 28 Oct 2026 04:41:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793187666; x=1793792466; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=867A7sMpdncPigJtqVsGMTnVHV10lVMiJCCGoHa64Uc=; b=Zkg+VK5obeNePs9hOFlMCWMJA9MWGhxygAD+qLqd32pFvDbqGudGoEdmmZgXL5yMz6 +SC/SLXj3o3rlXiqFKAmcxUQp+GblNGNyuLnFGtXci9mK/kuCqOwFiACbD2g+e9d3K6Y muQLQIFJhLtFM6ts7bx//zi+Ds8Kb3MM0ZHuf46uI4lHJlJDv2szHdsN5LOlV/b+lO2q cB1tpSQD31U9N9gZagBYXJqwMXxIopSk7tGQP2ezEHz5/3NxOW4r9hU71IzKbnKnApSW GbBpkQDxTtzad/HJ3dvgYjPf93wSI9fFcTjT1Albxm/l1z4rhaPIVb4y0sUTF/WDpCW2 yDhQ== X-Gm-Message-State: AFq9FYLpPOXystmymLBZ1u3aHyMZQlXobuE0/mRIWYsnO1Rb4m8B1Un3 7L7MbLz5Iq6hKFjix/1sMupJwbqeKrqORlewanc6RVeO5e7ALvRiU/DEj/ero3MJ4Sd2PSp4FgY /CAaDe0pwnZPSI2jsVcdzEaDxEZU5wZj2Hph07QIpNUsL4iFxmbrxdHCGf3K2AJGWe6SUd/Tnxw b3xJuNEv3lE1G9NaaIIV77pf7ttrlUkujF9v/tw43zpgf4/1c= X-Gm-Gg: AYBFou0nmRZp9MkhbjIq9wcnDHYENSTOxXPV3V2O0XQKGkH503XofEH9nENg4EyQLsC ieHnaV6fmesOruo5Jw/5AGHrpzC/OlXu132Su7RyRGpIswN3KQ3AZ9gEQnUJ9PJdYZ9WJm/URql jQ+YJDHCOWqajFBds0VZbLWBm7iLll6koLvYghFsT3XNPQCUWgdTLgShuSgk4ShCkZN7iQPEQk2 4IJZbwLFonHsusDZfR/IvM5+O974JoQWNwq4m7XBMjav52npz9JKs9uUs7Qqe1RFLhOXLvvKwvp kooqOgbbb9+ZiZoU6C/Swatts91JMExBbdiuHfOfxa/0vetdZuKV8+8TbqrnqreZ74TXiOanInG J3MZV6dAR+YPiR7LfbCX8+NTaLL0CVWlyUkTjJWPKoXruwDc= X-Received: by 2002:a05:6000:1862:b0:48d:fbe1:bb17 with SMTP id ffacd0b85a97d-48e5d4681femr5262890f8f.41.1793187666199; Wed, 28 Oct 2026 04:41:06 -0700 (PDT) X-Received: by 2002:a05:6000:1862:b0:48d:fbe1:bb17 with SMTP id ffacd0b85a97d-48e5d4681femr5262808f8f.41.1793187665527; Wed, 28 Oct 2026 04:41:05 -0700 (PDT) Received: from localhost ([2a00:23c6:e11d:fb01:6748:4fce:3e30:6e23]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48e3ebcb902sm29479986f8f.24.2026.10.28.04.41.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Oct 2026 04:41:04 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , Tom Tromey Subject: [PATCHv2 2/2] gdb: add debug_file_directory changed observer Date: Wed, 28 Oct 2026 11:40:57 +0000 Message-Id: <0cac73ac37e61ff91ac4448862e390dd8446ddb5.1793187406.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: <878q3oqmzp.fsf@tromey.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: T2IDkyHjlh9q_gMC9C_Nad0ZKhmD5EwLKGb1e__KISw_1793187666 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true 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 Add a new observer gdb::observers::gdb_debugdir_changed; this is triggered whenever the debug_file_directory is updated. This new observer is analogous to the existing gdb_datadir_changed observer. I was motivated to add this when trying to understand some code in auto-load.c. In file_is_auto_load_safe we call filename_is_in_auto_load_safe_path_vec, and if this fails we call auto_load_safe_path_vec_update, then filename_is_in_auto_load_safe_path_vec again. This seemed weird to me, why would we need to update the safe path vector again at this point? I think there are two reasons why this might be needed (before this patch): 1. If the definition of $debugdir changes then the vector needs to be rebuilt based on the new value, and 2. If any symlinks on the filesystem change the gdb_realpath might return new directory or filenames, which would then cause different things to match. The first case here is similar to $datadir, but for $datadir we have an observer which triggers an update of the safe path vector as soon as the variable changes. I figure that it makes sense to add an observer for the $debugdir case too. This leaves just case (2) as being the motivation for rebuilding the vector in the auto-load code. I've also added a comment about this to the code. I extended the existing auto-load-after-debug-dir-change.exp test to cover this case. The setup for the new test is that we set the auto-load safe path to '$debugdir', then set $debugdir to a directory D1 and cause GDB to compute the auto-load safe path vector. We can then set the auto load script path to the same D1 directory. At this point GDB will look for auto load script in D1, find that these match the auto-load safe path, and load them. Now if we change debug file directory (aka $debugdir) to a different directory D2 and try loading an executable, GDB will use the cached auto-load safe path which still contains D1, GDB will incorrectly load the script when the script should be rejected. With this patch the script will be rejected as expected. --- gdb/auto-load.c | 18 +++++++-- gdb/observable.c | 1 + gdb/observable.h | 4 ++ gdb/symfile.c | 12 +++++- .../auto-load-after-debug-dir-change.exp | 39 +++++++++++++++---- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/gdb/auto-load.c b/gdb/auto-load.c index 371d24c2b37..8b597c8070b 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -298,10 +298,11 @@ auto_load_safe_path_vec_update (void) } } -/* Variable gdb_datadir has been set. Update content depending on $datadir. */ +/* One of the variables gdb_datadir or debug_file_directory might have + changed. Update content depending on $datadir and $debugdir. */ static void -auto_load_gdb_datadir_changed (void) +auto_load_gdb_vars_changed () { auto_load_safe_path_vec_update (); } @@ -503,6 +504,15 @@ file_is_auto_load_safe (const char *filename) if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real)) return true; + /* The reason for rebuilding the vector, and retrying the match at + this point is in case the user has updated some symlinks on their + file system. Rebuilding the safe path vector calls gdb_realpath + on each entry and adds the result to the vector. As a result, if + any symlinks change then this update will change the set of paths + we consider safe. + + This does mean that a stale entry might trigger a match in the + above check, for now though we just accept this risk. */ auto_load_safe_path_vec_update (); if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real)) return true; @@ -1677,7 +1687,9 @@ This option has security implications for untrusted inferiors."), show_auto_load_safe_path, auto_load_set_cmdlist_get (), auto_load_show_cmdlist_get ()); - gdb::observers::gdb_datadir_changed.attach (auto_load_gdb_datadir_changed, + gdb::observers::gdb_datadir_changed.attach (auto_load_gdb_vars_changed, + "auto-load"); + gdb::observers::gdb_debugdir_changed.attach (auto_load_gdb_vars_changed, "auto-load"); cmd = add_cmd ("add-auto-load-safe-path", class_support, diff --git a/gdb/observable.c b/gdb/observable.c index 151014590a8..6a658303ee9 100644 --- a/gdb/observable.c +++ b/gdb/observable.c @@ -63,6 +63,7 @@ DEFINE_OBSERVABLE (inferior_cloned); DEFINE_OBSERVABLE (memory_changed); DEFINE_OBSERVABLE (before_prompt); DEFINE_OBSERVABLE (gdb_datadir_changed); +DEFINE_OBSERVABLE (gdb_debugdir_changed); DEFINE_OBSERVABLE (inferior_call_pre); DEFINE_OBSERVABLE (inferior_call_post); DEFINE_OBSERVABLE (register_changed); diff --git a/gdb/observable.h b/gdb/observable.h index 979e9d1c3ac..0581b48b711 100644 --- a/gdb/observable.h +++ b/gdb/observable.h @@ -213,6 +213,10 @@ extern observable before_prompt; change. */ extern observable<> gdb_datadir_changed; +/* Variable debug_file_directory has been set. The value may not + necessarily change. */ +extern observable<> gdb_debugdir_changed; + /* An inferior function at ADDRESS is about to be called in thread THREAD. */ extern observable diff --git a/gdb/symfile.c b/gdb/symfile.c index 017f7a49d8d..f8a7378120f 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1340,6 +1340,16 @@ show_debug_file_directory (struct ui_file *file, int from_tty, value); } +/* Implement 'set debug-file-directory' command. */ + +static void +set_debug_file_directory (const char *args, int from_tty, + struct cmd_list_element *e) +{ + /* The new value has already been installed by this point. */ + gdb::observers::gdb_debugdir_changed.notify (); +} + #if ! defined (DEBUG_SUBDIRECTORY) #define DEBUG_SUBDIRECTORY ".debug" #endif @@ -3885,7 +3895,7 @@ Separate debug symbols are first searched for in the same\n\ directory as the binary, then in the `" DEBUG_SUBDIRECTORY "' subdirectory,\n\ and lastly at the path of the directory of the binary with\n\ each global debug-file-directory component prepended."), - NULL, + set_debug_file_directory, show_debug_file_directory, &setlist, &showlist); diff --git a/gdb/testsuite/gdb.base/auto-load-after-debug-dir-change.exp b/gdb/testsuite/gdb.base/auto-load-after-debug-dir-change.exp index 6cb7a0a8432..4bcdb5670a2 100644 --- a/gdb/testsuite/gdb.base/auto-load-after-debug-dir-change.exp +++ b/gdb/testsuite/gdb.base/auto-load-after-debug-dir-change.exp @@ -76,16 +76,37 @@ proc run_test_1 { search_num debug_num } { gdb_load ${::binfile} - gdb_test {print $script_loaded} " = ${search_num}00" + if { $search_num == $debug_num } { + set expected_num "${search_num}00" + } else { + set expected_num "0" + } - # Check that the expected script shows as auto-loaded in GDB's output. - gdb_assert {[regexp "script_${search_num}_loaded" $::gdb_file_cmd_msg]} \ - "expected script was loaded" + gdb_test {print $script_loaded} " = ${expected_num}" - # The '3 - SEARCH_NUM' converts: 2 => 1 and 1 => 2. This checks - # that the other script was not auto-loaded. - gdb_assert {![regexp "script_[expr {3 - $search_num}]_loaded" $::gdb_file_cmd_msg]} \ - "other script was not loaded" + if { $search_num == $debug_num } { + # Check that the expected script shows as auto-loaded in GDB's output. + gdb_assert {[regexp "script_${search_num}_loaded" \ + $::gdb_file_cmd_msg]} \ + "expected script was loaded" + + # The '3 - SEARCH_NUM' converts: 2 => 1 and 1 => 2. This + # checks that the other script was not auto-loaded. + gdb_assert {![regexp "script_[expr {3 - $search_num}]_loaded" \ + $::gdb_file_cmd_msg]} \ + "other script was not loaded" + } else { + set re "warning: File \[^\r\n\]+/debug_dir_${search_num}/\[^\r\n\]+ auto-loading has been declined" + gdb_assert {[regexp $re $::gdb_file_cmd_msg]} \ + "saw script rejected message" + + gdb_assert {![regexp "script_1_loaded" \ + $::gdb_file_cmd_msg]} \ + "script 1 was not loaded" + gdb_assert {![regexp "script_2_loaded" \ + $::gdb_file_cmd_msg]} \ + "script 2 was not loaded" + } } # Wrapper around run_test_1 which adds a test prefix. See run_test_1 @@ -99,3 +120,5 @@ proc run_test { search_num debug_num } { # Run the tests. run_test 1 1 run_test 2 2 +run_test 2 1 +run_test 1 2 -- 2.25.4