From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 4WLGI3fYy2mX0AAAWB0awg (envelope-from ) for ; Tue, 31 Mar 2026 10:21:43 -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=RSWOCAVO; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 8CC6B1E0BC; Tue, 31 Mar 2026 10:21:43 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.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,RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.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 B13DD1E04F for ; Tue, 31 Mar 2026 10:21:42 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 7DBA44B7A1F1 for ; Tue, 31 Mar 2026 14:21:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7DBA44B7A1F1 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=RSWOCAVO 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 731264BA23E1 for ; Tue, 31 Mar 2026 14:20:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 731264BA23E1 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 731264BA23E1 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774966829; cv=none; b=NixrVlqbBrgqybC3G62eAD6M5MMG+fYznaMhepUC3gAPJaBwxeSsQaXOofkewYV+v9KnwWqdmuKy1tEaPLQVrOP7EeW88gajm/J7TpUXis6OO6up6ey/WR0QUP9+BMqdVStbY+aVN5j5kQJFnMHtytHjan51J0lcrb42306JY2g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774966829; c=relaxed/simple; bh=QsYEr2z/UfHtGO5tWZ+25yT1fBQoRQEt6fjIt1s73CI=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=IWJLe7ecf3aPe7A98FlfR7U7WuB687/Z6GttF/3HGGWofZ3Tj8w8SeSrsksG0VpU9KuekHptf9BIIeUT0wapVCSGK8/yYUXRgL6HaQKMENkXutilNsX/ziWF0B+VW5ZIMdTtPfD1GZvmg5RhjC1+X+qDb0D/b7l9RWcFESRoPnM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 731264BA23E1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1774966829; 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=kjZLGqIkNtiTHZ+6HSayl4fx6J50PuyTgk20wsW95+k=; b=RSWOCAVOk9+dYrQSqAKe9jeoTwxu1yNnIZ56poH363sTecv5EmqitGEjKX3PCHSgIw9OQO 80AYXwjDA2YGos6czoHOFeWx3NzqHR2Whdm8LeQvuh8vxSL5fuzsKRnjJDYePOY+uBE9XU vCRMm+8qWAq3jTwDM27xAgjkqVBrcCg= 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-397-KxDU8LUnOACqfrk8ja4u8A-1; Tue, 31 Mar 2026 10:20:25 -0400 X-MC-Unique: KxDU8LUnOACqfrk8ja4u8A-1 X-Mimecast-MFC-AGG-ID: KxDU8LUnOACqfrk8ja4u8A_1774966825 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-43d0de4bfb7so573799f8f.3 for ; Tue, 31 Mar 2026 07:20:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774966824; x=1775571624; 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; bh=kjZLGqIkNtiTHZ+6HSayl4fx6J50PuyTgk20wsW95+k=; b=CJhQ88AGzHP5Rt8j8SPGkZfv4mggcvIz4QShnbJ/t2fifi1sEDLlmsjOOgvd58BmD6 XFYsE1QnHH68uJ5JgeryA5V/uSW/h2LEvGzrhf543fN6QT0BX/cyqA1JrpWHi80WfNcv E+npK6Rr9A7TLHtfk2laXqxuTLxDzrLwLYok5C3wrA9ZszSNidHddbuPoWupZYEeetTb qufe18YWmPI3NNM2QPcgguOQJHtFHUEk0hh2AJDc750rMGhZt0j8OPg95qFZEH8Zbot9 gGS1W5Q1Q+ZYizrARgaWXeH6eorbpLf4m0RmwPhNAqOVfvhQRlq1EdNZpadfPb10KT4C o4zQ== X-Gm-Message-State: AOJu0Yysamwn5SgzeCLTlGGeMtBSh/tfbls/YOArwArf5BDeckQr01r9 2lKRCtV6bTxFGF5/R7mH1thtTNsemxNvHBjYaVvQAteyvKKq53WoYD/xgQ6DCfMyI/6cDOH4P2F HbISefpQFt3wPqIjIxrFxQB7LjJQxhtBSCRio76OMKJNKJBp2zbOMqMkAwa1UlYMl4IpxhlASm1 MxRHf+zRBW33U+WmB2S7bSeKRA23M7NO0PAIOpX0+dm47TmMM= X-Gm-Gg: ATEYQzziruhCz1/+vYpQ5rXYKninyZRrDAxT5wPjmP6Gf+JRtvQfxnxV1DM7BZ3sJ1x UTCw3Zrd7y4siil9ZbE4UubeGqjxr5QNw0T5oEC+zl9iIN3nr4n+zhK/FGgWrJ5eRwIGD2cVOCa wa00UmorvNCcrTMJm/Bzl35mOxI998fRbzR4Bv940yoDWW4wNrc++grYQjADuGs0xBWE3GFEqx2 C7paGyqbf/yZMK4QFdmSBFhwaZjK1cpjLAwt+ojek4Rl4d09giu6C6GOlude3pvdQpesh38DE2k 7uI9e+5Yri90M/PB3ag72iMfnBTMnT4p8SLV4ptuOUwgNRByhii4Zaf6+fAk06YUaOf9LCciApJ T4rcJEl/4weKjcaec X-Received: by 2002:a05:6000:430d:b0:43d:7ef:552f with SMTP id ffacd0b85a97d-43d07ef55c1mr7100576f8f.25.1774966823626; Tue, 31 Mar 2026 07:20:23 -0700 (PDT) X-Received: by 2002:a05:6000:430d:b0:43d:7ef:552f with SMTP id ffacd0b85a97d-43d07ef55c1mr7100495f8f.25.1774966822900; Tue, 31 Mar 2026 07:20:22 -0700 (PDT) Received: from localhost ([31.111.84.232]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43cf21e2a7asm30477407f8f.7.2026.03.31.07.20.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Mar 2026 07:20:22 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 2/2] gdb: move call to clear_symtab_users out from finish_new_objfile Date: Tue, 31 Mar 2026 15:20:18 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: nH4qH5lcDLHFdW9-GRsoOlvmJAXEYmomEp3doicN23w_1774966825 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 Move the call to clear_symtab_users from within finish_new_objfile to instead reside within symbol_file_add_with_addrs. This resolves an issue where clear_symtab_users can be called multiple times during the loading of the main executable, which causes important information to be discarded. To understand the problem we must understand two things. First, how does clear_symtab_users discard critical information? This is the easy part of the problem, clear_symtab_users notifies the all_objfiles_removed observer, in auto-load.c there is a listener for this observer, clear_section_scripts, which discards information about any auto-loaded scripts. If we call clear_symtab_users after auto-loading a script within a program space, then information about that script having been loaded will be discarded. The second thing we must consider is the order in which functions are called when loading a main executable with separate debug information. I'm only listing some of the most important functions in the process here, the ones relevant to the issue being fixed. In the following text I'll use "main objfile" to refer to the actual executable, and "debug info objfile" to refer to the split debug info corresponding to the "main objfile". 1. Call symbol_file_add_with_addrs for the main objfile. 2. Call syms_from_objfile passing in the main objfile. 3. Call objfile::find_and_add_separate_symbol_file on the main objfile. 4. Call symbol_file_add_separate for the debug info objfile. 5. Call symbol_file_add_with_addrs for the debug info objfile. 6. Call syms_from_objfile for the debug info objfile. The debug symbols are contained in this objfile so they are read and added to GDB. 7. Call finish_new_objfile for the debug info objfile, followed by triggering the new objfile observer for the debug info objfile. 8. We are now done in symbol_file_add_with_addrs for the debug info objfile. We now unwind the stack back to (1). 9. Back in symbol_file_add_with_addrs for the main objfile, the debug symbols have now been added (from the separate debug info objfile), so we can now call finish_new_objfile for the main objfile, followed by triggering the new objfile observer for the main objfile. 10. Success! The main objfile, and the associated debug info objfile have now been added to GDB. Notice that we end up with a recursive call back into symbol_file_add_with_addrs, which results in two calls to finish_new_objfile, the debug info objfile is processed first, and the main objfile is processed second. The main objfile will have SYMFILE_MAINLINE in its symfile_add_flags, and this will end up being passed to symbol_file_add_separate. This means that in finish_new_objfile we currently call clear_symtab_users after finishing both the debug info objfile, and after the main objfile, in that order. Auto-loaded scripts are loaded by load_auto_scripts_for_objfile (in auto-load.c) which is called by the new_objfile observer. If the debug info objfile contains any scripts within the .debug_gdb_scripts section, then these will be loaded (7) in the above list, after the debug info objfile has been added, but before the main objfile is added. Now, this shouldn't be a problem, except that currently, when finishing the main objfile, we call clear_symtab_users, which triggers the all_objfiles_removed observer, which calls clear_section_scripts (in auto-load.c), which discards all records of auto-loaded scripts. This issue is exposed by the test extension added in this commit. An executable is compiled with debug information, the executable includes a .debug_gdb_scripts section. We then use objcopy to split the debug information into a separate objfile. This takes the .debug_gdb_scripts section with it. We then ask GDB to load the executable, which triggers loading of the separate debug information file. Loading the separate debug information file loads the .debug_gdb_scripts section, then GDB finishes loading the main executable and discards the record of loading the .debug_gdb_scripts. This is exposed by using 'info auto-load'. The solution I propose is to move the call to clear_symtab_users earlier within symbol_file_add_with_addrs, and to guard the call so that it is only called for the main objfile, and not for the debug info objfile. The new location for the clear_symtab_users call is before the syms_from_objfile call. This means that it will be called for the main objfile before GDB starts loading the debug info objfile. There are two additional, related changes in this commit. The new location for the clear_symtab_users call is before program_space::symfile_object_file is removed by unlinking the referenced objfile, so we don't want the breakpoint_re_set call in clear_symtab_users to resolve breakpoints against the old objfiles. To avoid this, at the new call to clear_symtab_users, we force the SYMFILE_DEFER_BP_RESET. Then we restructure finish_new_objfile so that breakpoint_re_set can always be called if appropriate. This replaces the old breakpoint_re_set call which was reached via the old call to clear_symtab_users. Additionally, in finish_new_objfile, we only set program_space::symfile_object_file for the main objfile. Previously we would set this field first to the debug info objfile, and then reset this field to the main objfile. This set then overwrite sequence was harmless, but also pointless. I think by restricting this code so we only set it to the main objfile better reflects the state we want GDB to be in. --- gdb/symfile.c | 33 ++++++++------- .../gdb.python/py-section-script.exp | 41 +++++++++++++++++++ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/gdb/symfile.c b/gdb/symfile.c index c2844eb88a5..e3aa81fbc0c 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -969,20 +969,15 @@ syms_from_objfile (struct objfile *objfile, static void finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags) { - /* If this is the main symbol file we have to clean up all users of the - old main symbol file. Otherwise it is sufficient to fixup all the - breakpoints that may have been redefined by this symbol file. */ - if (add_flags & SYMFILE_MAINLINE) - { - /* OK, make it the "real" symbol file. */ - current_program_space->symfile_object_file = objfile; + /* If this is the main symbol file then record it as such in the program + space. Don't record any separate debug files loaded as a consequence + of loading the main symbol file though. */ + if (add_flags & SYMFILE_MAINLINE + && objfile->separate_debug_objfile_backlink == nullptr) + current_program_space->symfile_object_file = objfile; - clear_symtab_users (add_flags); - } - else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0) - { - breakpoint_re_set (); - } + if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0) + breakpoint_re_set (); /* We're done reading the symbol file; finish off complaints. */ clear_complaints (); @@ -1047,7 +1042,17 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name, error (_("Not confirmed.")); if (mainline) - flags |= OBJF_MAINLINE; + { + flags |= OBJF_MAINLINE; + + /* Before we create the new objfile, or load any debug symbols, + discard any existing cached symbols. Don't reset breakpoints at + this point as we haven't discarded the previous main objfile yet, + and we'd only end up resolving the breakpoints against the old + symbols. The breakpoints will be reset in finish_new_objfile. */ + if (parent == nullptr) + clear_symtab_users (add_flags | SYMFILE_DEFER_BP_RESET); + } objfile *objfile = objfile::make (abfd, current_program_space, name, flags, parent); diff --git a/gdb/testsuite/gdb.python/py-section-script.exp b/gdb/testsuite/gdb.python/py-section-script.exp index a3b9631ade7..d1a5a901570 100644 --- a/gdb/testsuite/gdb.python/py-section-script.exp +++ b/gdb/testsuite/gdb.python/py-section-script.exp @@ -183,4 +183,45 @@ foreach_with_prefix variant {plain compressed} { gdb_test "info auto-load python-scripts no-script-matches-this" \ "No auto-load scripts matching no-script-matches-this." } + + # Unlike eu-strip, objcopy moves the .debug_gdb_scripts into the .debug + # file, removing it from the executable. GDB should still load the + # script though, just when it loads the symbol file, not the main + # executable. + with_test_prefix "sepdebug from objcopy" { + clean_restart + + set objcopy_testfile ${the_testfile}-objcopy + set objcopy_binfile [standard_output_file $objcopy_testfile] + file copy -force $the_binfile $objcopy_binfile + + if { [gdb_gnu_strip_debug $objcopy_binfile] != 0 } { + fail "strip $objcopy_testfile debuginfo" + return + } + + set_auto_load_safe_path $remote_python_file \ + [file dirname ${objcopy_binfile}] + gdb_load $objcopy_binfile + + # Verify gdb loaded each script and they appear once in the list. + gdb_test_multiple "info auto-load python-scripts" "verify scripts loaded" { + -re -wrap "Yes.*${testfile}.py.*Yes.*inlined-script.*" { + pass $gdb_test_name + } + -re -wrap "${testfile}.py.*${testfile}.py.*" { + fail $gdb_test_name + } + -re -wrap "inlined-script.*inlined-script.*" { + fail $gdb_test_name + } + } + + # Again, with a regexp this time. + gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*" + + # Again, with a regexp that matches no scripts. + gdb_test "info auto-load python-scripts no-script-matches-this" \ + "No auto-load scripts matching no-script-matches-this." + } } -- 2.25.4