| Message ID | 20251222165805.88826-1-ssbssa@yahoo.de |
|---|---|
| State | New |
| Headers |
Return-Path: <gdb-patches-bounces~patchwork=sourceware.org@sourceware.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 171BA4BA2E27 for <patchwork@sourceware.org>; Mon, 22 Dec 2025 16:59:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 171BA4BA2E27 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=yahoo.de header.i=@yahoo.de header.a=rsa-sha256 header.s=s2048 header.b=N2Ao3CPI X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from sonic305-20.consmr.mail.ir2.yahoo.com (sonic305-20.consmr.mail.ir2.yahoo.com [77.238.177.82]) by sourceware.org (Postfix) with ESMTPS id 44FE84BA2E25 for <gdb-patches@sourceware.org>; Mon, 22 Dec 2025 16:58:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 44FE84BA2E25 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=yahoo.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yahoo.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 44FE84BA2E25 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=77.238.177.82 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1766422701; cv=none; b=crXRwyCTb+iIergffVMrAa67M7Zvh9wXZ2x8/XhQyDUhNhcZvN+AedG9XCpqE3PrCEzYjbECREjJXdSe4TcAAroXJ8rrA61e81hLTIJ19TMg7ZAXMr+IrUNjNTaHY3jjf1uye4foATqvnAjCTfqnS51yKz++AnzdavapH3nx8KA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1766422701; c=relaxed/simple; bh=3qDd6T8K4Fj88pfRq3T6D9Tt+GDTfneDJO7HiX/x8BI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Ot2FvZ1zmy73iRfYpmMiEhJEQ5o5/SWP1AsN+N1LUNND08bdQpwn2yGd8RcZ1jhDmyay2aG9RsjINp2REJtaAJcrJyvi19aSHyXycMIRl4pVK2Ku8Mgbu8UgMZgimsCyVmBoDu8A2yG9Ox0tNzdxCKeCjKQSURmj8BqLBFfHl9k= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 44FE84BA2E25 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1766422700; bh=9KLSGHlDt0GJEYXdqz7G0K8Lf8Tqyb8u8O2/HUu56gE=; h=From:To:Subject:Date:References:From:Subject:Reply-To; b=N2Ao3CPI9d52agI3rwSCCKoLnZ/rZPAU02dRk2I2tzyq1eST+Xm7t6kHtYn6rubwtSa8FBNNVPVmuOoXOHYY2G4RMhV/tGoYQ82KETDt+9Pv1JGmnf/zML1f1auD0+pHZhoe8rn+5OV1tT13kly182oWqoMUbkm0E2cukoaCUChTNX4XW5ST2Rb8rExcnmZY78Dovk5/ZM0auq88pzYMp8sDzYJH2dXuvHgX2xf8Fg+xC8k1N2c6UkkIlss8oanI+E4G/obDomDVtfIf/rh9NgWFhzV4qqk4AL/HWBngOwDRZT2QyVa1VdZxjtXI5ZjjvvINqZzCTKotUBJeHHEQow== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1766422700; bh=Q7nK8GUUIP0pyYjDf/NEy3OfI4yHyMZW3JVCGRVSNsI=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=eax7iFirFL5r0lsZ0kN6uZiiCFJ6KWDMfdLs2ZmqWVLylSYrY+jpZP/OC7YuLTTpY8BHbRwj89JaGlNxyJHgVdD+nTxVOwAQAYz3+IwUodtlH4BewBSsxWSNcxBkepz+6Jxg/qAPBzYvkvaGSoFLEd4uhv4lskybGaksmBcrlWxjiKg2coQEsgtUdKpcFUBbyHEySOQgyLX0R+8JCO9yyzEiB/NMLJzEYltRPaHu/LgWERs9urVDNsFR7QA+O/SjWqQGzA8sUqDdAvNifr+xsuGq4JTT5ARNvQ1K4jVjSqdYuMClihuh38aQtsnGURaT2Z6wbVVDU1B6I+om63a5Ug== X-YMail-OSG: wRy.bKcVM1m2xSUSlVm1YnHqmszEroKZwvv5gEJyfW9cdFsUXnx754IOYq6FKpz L62GImFtz9A4hroX_QDhgHzrDe54QCqBZMPlESVQROdFUH2ebw74KM7ryNlU95IHGz4wpFe3a04S cZrhyqrmgtC1Y9RJF0KVpWo.ZmgGsQKqOhrhYoc_tsK1MnYgY9wH2A30qxrc70EJnBL6ASSeVZUv oBoANrVIOXH530NZ97egT2YO.CQ5t1d.0.2Q69dEst3np67gi1VHu_QOoKYABMPteHj.O7ePckSI hZqqLT0gUB.jDgYzgMtPAHUewQ4IigHt5a50uWzbERr6Ow3Qzkj.ulfZHCNXIVYM8iRurwcxkZtu LjbGHRuXEDgvTbmH3dubehuDAAYJsx1TQDIRajzNRd8kQiIAtQijUdIx0JfbuPaQcAb64ljUU7UQ UnYIb4mbFtC6nrNngQ3XyKvkcPl98XfaLhI0OGMgC2KC_Az4dskIOtWOZrhgOeJsAbDxFwQezEzQ oWyRgA7cagjrtgg3570GH0TNKHnkkcUV_gNZN_y1DHHx_Hmur5vdjdi6c8uyRjfDjeecyodX8tYG zC44aiMNzhZUW1GLd6DJa0MNnjn5tjIr_OJ3edpC_P.9IiiK48Q1.qtXcG.FznXv98PtiDUQNliN dTZ0xyRM3WgQA6rbWt9xLYSWu.8whkc6phgWoiaEr4N4LOK8HTV3JtgNrwFQL3e0heCl29LzKp7f Qk40An3gpXyIYPimC_WSdkqDS1F_9rIIH2f0grJiwSGKxAigHvUhdQvD11dI3QSZhkvgaPnBMj5q 4Pk1lUSvs05zYpfV82wRiC_un_VcWbmQzYr_.F4mRh_sq9P2pIzktiIuUk8f86gWjA9z7ZHg8i8U t.iGkRF1GDC9ryHLy6J7a70t.X7fyeBsn41a2Us_2IOsM2PldNiYyVgmOnErQO.q43qeL78m3mWf DyamUhZO.8wLqnO9YD284NuHHKNOzEcWNI3BS0WQFaziF517HjmPptKcZ9ZQyFBPODELPzSmPMQD 5eMUa8l4R2LLdqyja.r8yN84Auis7WD.MSweBmw71v95_LAGuNXTRjN77twvYYn5Rkc3FDSa.QKm iAxYP4zRBlhlm4ykJSoBVAN8jv9cAipz4yzTw3BmYWPPRlgPghRLPakCamNm_6aHWFZ4JqZms9aJ 9U6cpzBdnA_ukgoQF1pQ7X4jG1xsMSPUit.s_V.NcIlDM1oxf4FNk1yxffSE557HvN7YWXVjCVal U5cNxnpGWD29HrBthWaNooMkq0LXRCEWgz7u6nKEW.BuUfUwWBs77YD3Bu4Jmje2voc3YpiE8vNN q0xrz9L_ldHqpmOPOg4tL_nclthhuxcG_tTnSicvCwUSXtLlor0dVh3.daOag2mHSRVCTwXBwpZ9 e2sAGToHC2J9jXH.afx97mDLfTZb1JafrDDvZoRAvJFi6tglSrDvfEvSK9X_HRJCR1wmLwv1OEr2 21xx03zSOZCcbH4njBfm1tgd5RQZvdY5EQk31e05xK3Iwq3SV4qGAIv1L8KMqlYEMSTbRQqXxAld 97jggklfy3r0I8i2La21UizSjqzCz7HKq.lPlr39IcORYBDF5ZIyW3Zqsk67nw8hPSusr15QBooe ZF1zPTnoWi1kWceQul2lwo1ogOPAMdPJgJCAp1LZyZOfrPHc8AEsey38et1CeBL0O7kuwb9g9hS9 Pzpp0azTy37XqwJ6IgmeYM_tf4qbo7cQmGRWayKLVLBWwzdIhnGZXibpSbGHq6QEi7HDrwCzqARh ee6IYBhNG4uI66KiRc5sfKYInIlD13gAhxZ62nAk8BA2_2sojqUunyghIbuTadn3ZhkfzaoWsmI6 Fn7ihS_FjjZR6AHDE_b9k_i5zufyW4mFsO55FXNQb.KxtrzQPKMh88XgCnYDsDNzAgAKpaWSAngQ JogvjgJ2MPnrk3F4FgohPdLAMBab2Fkuqmfkdtml27B1uFqtAdOjRu4D1mRQ_0PrVEHJZLDLgjQE glcQuw5htt9zFzmpEjcyf72IsHuJFLQ_YT8Xy9Bwy_8Kd9Z13eTj.uO0yOvhUZVe1bZK7Y8YPhBs u1uIPI8bpFrzgO1ptEUZoo1Hd2O.j_oj2aJjTUW8zwzn.07f_sZdureFbpRO4.aG016gu6hq_ySA xdmbRBu4H0qb4r_p4Gjaqx1FSORZNHuu2T166Rf61..ZbE_AJxAHpkGtEKaP75ygcz7t.LF8uotw rjLfafTCjxFLl4zoRcLT9aySF5GLosQ4SF.byJ8g- X-Sonic-MF: <ssbssa@yahoo.de> X-Sonic-ID: 692d8095-9bb6-4029-bc68-9cc8713188ef Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ir2.yahoo.com with HTTP; Mon, 22 Dec 2025 16:58:20 +0000 Received: by hermes--production-ir2-7679c5bc-tqh9m (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID a18ace7c8fac2f0201da418ca03dca5a; Mon, 22 Dec 2025 16:58:17 +0000 (UTC) From: Hannes Domani <ssbssa@yahoo.de> To: gdb-patches@sourceware.org Subject: [PATCH v2] Forget the last displayed sal when the referenced objfile is destroyed Date: Mon, 22 Dec 2025 17:55:47 +0100 Message-ID: <20251222165805.88826-1-ssbssa@yahoo.de> X-Mailer: git-send-email 2.52.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit References: <20251222165805.88826-1-ssbssa.ref@yahoo.de> X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED, WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list <gdb-patches.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/gdb-patches/> List-Post: <mailto:gdb-patches@sourceware.org> List-Help: <mailto:gdb-patches-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/gdb-patches>, <mailto:gdb-patches-request@sourceware.org?subject=subscribe> Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org |
| Series |
[v2] Forget the last displayed sal when the referenced objfile is destroyed
|
|
Commit Message
Hannes Domani
Dec. 22, 2025, 4:55 p.m. UTC
When creating a new line-breakpoint after rerunning with a disabled or
removed breakpoint in a solib, you currently get this use-after-free
crash:
(gdb) break solib_main
Breakpoint 1 at 0x1030
(gdb) run
Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1".
Breakpoint 1, solib_main (arg=100) at /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/solib1.c:7
7 int ans = arg*arg; /* HERE */
(gdb) disable
(gdb) set confirm off
(gdb) run
Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1".
[Inferior 1 (process 50868) exited normally]
(gdb) break 18
=================================================================
==50836==ERROR: AddressSanitizer: heap-use-after-free on address 0x7d65a543d488 at pc 0x55f022334c29 bp 0x7ffe9c7f45f0 sp 0x7ffe9c7f45e0
READ of size 8 at 0x7d65a543d488 thread T0
#0 0x55f022334c28 in symtab::filename() const ../../gdb/symtab.h:1747
#1 0x55f023a32b7d in create_sals_line_offset ../../gdb/linespec.c:2013
#2 0x55f023a37937 in convert_linespec_to_sals ../../gdb/linespec.c:2294
#3 0x55f023a3cf79 in parse_linespec ../../gdb/linespec.c:2652
#4 0x55f023a415b2 in location_spec_to_sals ../../gdb/linespec.c:3050
#5 0x55f023a423b0 in decode_line_full(location_spec*, int, program_space*, symtab*, int, linespec_result*, char const*, char const*) ../../gdb/linespec.c:3126
#6 0x55f022826e1b in parse_breakpoint_sals ../../gdb/breakpoint.c:9069
#7 0x55f0228291c2 in create_breakpoint(gdbarch*, location_spec*, char const*, int, int, char const*, bool, int, int, bptype, int, auto_boolean, breakpoint_ops const*, int, int, int, unsigned int) ../../gdb/breakpoint.c:9312
#8 0x55f02282c298 in break_command_1 ../../gdb/breakpoint.c:9471
#9 0x55f02282d0bb in break_command(char const*, int) ../../gdb/breakpoint.c:9541
#10 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94
0x7d65a543d488 is located 904 bytes inside of 4064-byte region [0x7d65a543d100,0x7d65a543e0e0)
freed by thread T0 here:
#0 0x7f55aa91f79d in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:51
#1 0x55f0221f6403 in xfree<void> ../../gdb/../gdbsupport/gdb-xfree.h:37
#2 0x55f027b64851 in call_freefun ../../libiberty/obstack.c:103
#3 0x55f027b66283 in _obstack_free ../../libiberty/obstack.c:280
#4 0x55f0221f7a07 in auto_obstack::~auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:126
#5 0x55f023f3dd83 in objfile::~objfile() ../../gdb/objfiles.c:509
#6 0x55f023f511d8 in std::default_delete<objfile>::operator()(objfile*) const /usr/include/c++/15.2.1/bits/unique_ptr.h:93
#7 0x55f023f4b8cd in std::unique_ptr<objfile, std::default_delete<objfile> >::~unique_ptr() /usr/include/c++/15.2.1/bits/unique_ptr.h:399
#8 0x55f0240b6dab in owning_intrusive_list<objfile, intrusive_base_node<objfile> >::erase(intrusive_list_iterator<objfile, intrusive_base_node<objfile> >) ../../gdb/../gdbsupport/owning_intrusive_list.h:113
#9 0x55f0240adb68 in program_space::remove_objfile(objfile*) ../../gdb/progspace.c:202
#10 0x55f023f3cfcf in objfile::unlink() ../../gdb/objfiles.c:409
#11 0x55f023f40faf in objfile_purge_solibs(program_space*) ../../gdb/objfiles.c:687
#12 0x55f02487ec19 in no_shared_libraries(program_space*) ../../gdb/solib.c:1359
#13 0x55f024b37e1e in target_pre_inferior() ../../gdb/target.c:2474
#14 0x55f0238ac7cd in run_command_1 ../../gdb/infcmd.c:381
#15 0x55f0238ae438 in run_command ../../gdb/infcmd.c:510
#16 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94
previously allocated by thread T0 here:
#0 0x7f55aa920cb5 in malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:67
#1 0x55f02241d780 in xmalloc ../../gdb/alloc.c:52
#2 0x55f027b6461f in call_chunkfun ../../libiberty/obstack.c:94
#3 0x55f027b649d1 in _obstack_begin_worker ../../libiberty/obstack.c:141
#4 0x55f027b650c5 in _obstack_begin ../../libiberty/obstack.c:164
#5 0x55f0221f775a in auto_obstack::auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:123
#6 0x55f023f39c91 in objfile::objfile(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>) ../../gdb/objfiles.c:257
#7 0x55f023f3ccaa in objfile::make(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>, objfile*) ../../gdb/objfiles.c:392
#8 0x55f02498b1d2 in symbol_file_add_with_addrs ../../gdb/symfile.c:1069
#9 0x55f02498c099 in symbol_file_add_from_bfd(gdb::ref_ptr<bfd, gdb_bfd_ref_policy> const&, char const*, enum_flags<symfile_add_flag>, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) ../../gdb/symfile.c:1156
#10 0x55f02487255b in solib_read_symbols(solib&, enum_flags<symfile_add_flag>) ../../gdb/solib.c:660
#11 0x55f024876c0c in solib_add(char const*, int, int) ../../gdb/solib.c:993
#12 0x55f02487f1f8 in handle_solib_event() ../../gdb/solib.c:1399
#13 0x55f0227df91f in bpstat_stop_status(address_space const*, unsigned long, thread_info*, target_waitstatus const&, bpstat*) ../../gdb/breakpoint.c:5962
#14 0x55f023944fa8 in handle_signal_stop ../../gdb/infrun.c:7130
#15 0x55f02393e2a1 in handle_inferior_event ../../gdb/infrun.c:6574
#16 0x55f0239279f2 in fetch_inferior_event() ../../gdb/infrun.c:4713
#17 0x55f023885fe3 in inferior_event_handler(inferior_event_type) ../../gdb/inf-loop.c:42
#18 0x55f023af706e in handle_target_event ../../gdb/linux-nat.c:4449
#19 0x55f027c2d2f0 in handle_file_event ../../gdbsupport/event-loop.cc:551
#20 0x55f027c2e4ff in gdb_wait_for_event ../../gdbsupport/event-loop.cc:672
It happened because last_displayed_symtab_info of stack.c still contained
a reference to a symtab that was already freed in the 2nd run.
This fixes it by clearing last_displayed_symtab_info in the objfile
destructor, if it is pointing to that objfile.
Now setting of the 2nd breakpoint works:
(gdb) break 18
Breakpoint 2 at 0x555555555141: file /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/so-impl-ld.c, line 18.
(gdb)
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32668
---
Changes since v1:
- Clear last_displayed_symtab_info in the objfile destructor.
- Some test improvements.
---
gdb/objfiles.c | 8 +++
.../gdb.base/solib-breakpoints-rerun.exp | 49 +++++++++++++++++++
2 files changed, 57 insertions(+)
create mode 100644 gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp
Comments
On 12/22/25 1:55 PM, Hannes Domani wrote: > When creating a new line-breakpoint after rerunning with a disabled or > removed breakpoint in a solib, you currently get this use-after-free > crash: > > (gdb) break solib_main > Breakpoint 1 at 0x1030 > (gdb) run > Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun > [Thread debugging using libthread_db enabled] > Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". > > Breakpoint 1, solib_main (arg=100) at /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/solib1.c:7 > 7 int ans = arg*arg; /* HERE */ > (gdb) disable > (gdb) set confirm off > (gdb) run > Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun > [Thread debugging using libthread_db enabled] > Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". > [Inferior 1 (process 50868) exited normally] > (gdb) break 18 > ================================================================= > ==50836==ERROR: AddressSanitizer: heap-use-after-free on address 0x7d65a543d488 at pc 0x55f022334c29 bp 0x7ffe9c7f45f0 sp 0x7ffe9c7f45e0 > READ of size 8 at 0x7d65a543d488 thread T0 > #0 0x55f022334c28 in symtab::filename() const ../../gdb/symtab.h:1747 > #1 0x55f023a32b7d in create_sals_line_offset ../../gdb/linespec.c:2013 > #2 0x55f023a37937 in convert_linespec_to_sals ../../gdb/linespec.c:2294 > #3 0x55f023a3cf79 in parse_linespec ../../gdb/linespec.c:2652 > #4 0x55f023a415b2 in location_spec_to_sals ../../gdb/linespec.c:3050 > #5 0x55f023a423b0 in decode_line_full(location_spec*, int, program_space*, symtab*, int, linespec_result*, char const*, char const*) ../../gdb/linespec.c:3126 > #6 0x55f022826e1b in parse_breakpoint_sals ../../gdb/breakpoint.c:9069 > #7 0x55f0228291c2 in create_breakpoint(gdbarch*, location_spec*, char const*, int, int, char const*, bool, int, int, bptype, int, auto_boolean, breakpoint_ops const*, int, int, int, unsigned int) ../../gdb/breakpoint.c:9312 > #8 0x55f02282c298 in break_command_1 ../../gdb/breakpoint.c:9471 > #9 0x55f02282d0bb in break_command(char const*, int) ../../gdb/breakpoint.c:9541 > #10 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94 > > 0x7d65a543d488 is located 904 bytes inside of 4064-byte region [0x7d65a543d100,0x7d65a543e0e0) > freed by thread T0 here: > #0 0x7f55aa91f79d in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:51 > #1 0x55f0221f6403 in xfree<void> ../../gdb/../gdbsupport/gdb-xfree.h:37 > #2 0x55f027b64851 in call_freefun ../../libiberty/obstack.c:103 > #3 0x55f027b66283 in _obstack_free ../../libiberty/obstack.c:280 > #4 0x55f0221f7a07 in auto_obstack::~auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:126 > #5 0x55f023f3dd83 in objfile::~objfile() ../../gdb/objfiles.c:509 > #6 0x55f023f511d8 in std::default_delete<objfile>::operator()(objfile*) const /usr/include/c++/15.2.1/bits/unique_ptr.h:93 > #7 0x55f023f4b8cd in std::unique_ptr<objfile, std::default_delete<objfile> >::~unique_ptr() /usr/include/c++/15.2.1/bits/unique_ptr.h:399 > #8 0x55f0240b6dab in owning_intrusive_list<objfile, intrusive_base_node<objfile> >::erase(intrusive_list_iterator<objfile, intrusive_base_node<objfile> >) ../../gdb/../gdbsupport/owning_intrusive_list.h:113 > #9 0x55f0240adb68 in program_space::remove_objfile(objfile*) ../../gdb/progspace.c:202 > #10 0x55f023f3cfcf in objfile::unlink() ../../gdb/objfiles.c:409 > #11 0x55f023f40faf in objfile_purge_solibs(program_space*) ../../gdb/objfiles.c:687 > #12 0x55f02487ec19 in no_shared_libraries(program_space*) ../../gdb/solib.c:1359 > #13 0x55f024b37e1e in target_pre_inferior() ../../gdb/target.c:2474 > #14 0x55f0238ac7cd in run_command_1 ../../gdb/infcmd.c:381 > #15 0x55f0238ae438 in run_command ../../gdb/infcmd.c:510 > #16 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94 > > previously allocated by thread T0 here: > #0 0x7f55aa920cb5 in malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:67 > #1 0x55f02241d780 in xmalloc ../../gdb/alloc.c:52 > #2 0x55f027b6461f in call_chunkfun ../../libiberty/obstack.c:94 > #3 0x55f027b649d1 in _obstack_begin_worker ../../libiberty/obstack.c:141 > #4 0x55f027b650c5 in _obstack_begin ../../libiberty/obstack.c:164 > #5 0x55f0221f775a in auto_obstack::auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:123 > #6 0x55f023f39c91 in objfile::objfile(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>) ../../gdb/objfiles.c:257 > #7 0x55f023f3ccaa in objfile::make(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>, objfile*) ../../gdb/objfiles.c:392 > #8 0x55f02498b1d2 in symbol_file_add_with_addrs ../../gdb/symfile.c:1069 > #9 0x55f02498c099 in symbol_file_add_from_bfd(gdb::ref_ptr<bfd, gdb_bfd_ref_policy> const&, char const*, enum_flags<symfile_add_flag>, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) ../../gdb/symfile.c:1156 > #10 0x55f02487255b in solib_read_symbols(solib&, enum_flags<symfile_add_flag>) ../../gdb/solib.c:660 > #11 0x55f024876c0c in solib_add(char const*, int, int) ../../gdb/solib.c:993 > #12 0x55f02487f1f8 in handle_solib_event() ../../gdb/solib.c:1399 > #13 0x55f0227df91f in bpstat_stop_status(address_space const*, unsigned long, thread_info*, target_waitstatus const&, bpstat*) ../../gdb/breakpoint.c:5962 > #14 0x55f023944fa8 in handle_signal_stop ../../gdb/infrun.c:7130 > #15 0x55f02393e2a1 in handle_inferior_event ../../gdb/infrun.c:6574 > #16 0x55f0239279f2 in fetch_inferior_event() ../../gdb/infrun.c:4713 > #17 0x55f023885fe3 in inferior_event_handler(inferior_event_type) ../../gdb/inf-loop.c:42 > #18 0x55f023af706e in handle_target_event ../../gdb/linux-nat.c:4449 > #19 0x55f027c2d2f0 in handle_file_event ../../gdbsupport/event-loop.cc:551 > #20 0x55f027c2e4ff in gdb_wait_for_event ../../gdbsupport/event-loop.cc:672 > > It happened because last_displayed_symtab_info of stack.c still contained > a reference to a symtab that was already freed in the 2nd run. > This fixes it by clearing last_displayed_symtab_info in the objfile > destructor, if it is pointing to that objfile. > Now setting of the 2nd breakpoint works: > > (gdb) break 18 > Breakpoint 2 at 0x555555555141: file /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/so-impl-ld.c, line 18. > (gdb) > > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32668 > --- > Changes since v1: > - Clear last_displayed_symtab_info in the objfile destructor. > - Some test improvements. > --- Hi! Thanks for working on this! I took a look over this patch and everything makes sense, and I confirmed that this does fix the issue, so it looks reasonable, Reviewed-By: Guinevere Larsen <guinevere@redhat.com> Hopefully this gets approved soon.
On 12/22/25 11:55 AM, Hannes Domani wrote: > When creating a new line-breakpoint after rerunning with a disabled or > removed breakpoint in a solib, you currently get this use-after-free > crash: > > (gdb) break solib_main > Breakpoint 1 at 0x1030 > (gdb) run > Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun > [Thread debugging using libthread_db enabled] > Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". > > Breakpoint 1, solib_main (arg=100) at /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/solib1.c:7 > 7 int ans = arg*arg; /* HERE */ > (gdb) disable > (gdb) set confirm off > (gdb) run > Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun > [Thread debugging using libthread_db enabled] > Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". > [Inferior 1 (process 50868) exited normally] > (gdb) break 18 > ================================================================= > ==50836==ERROR: AddressSanitizer: heap-use-after-free on address 0x7d65a543d488 at pc 0x55f022334c29 bp 0x7ffe9c7f45f0 sp 0x7ffe9c7f45e0 > READ of size 8 at 0x7d65a543d488 thread T0 > #0 0x55f022334c28 in symtab::filename() const ../../gdb/symtab.h:1747 > #1 0x55f023a32b7d in create_sals_line_offset ../../gdb/linespec.c:2013 > #2 0x55f023a37937 in convert_linespec_to_sals ../../gdb/linespec.c:2294 > #3 0x55f023a3cf79 in parse_linespec ../../gdb/linespec.c:2652 > #4 0x55f023a415b2 in location_spec_to_sals ../../gdb/linespec.c:3050 > #5 0x55f023a423b0 in decode_line_full(location_spec*, int, program_space*, symtab*, int, linespec_result*, char const*, char const*) ../../gdb/linespec.c:3126 > #6 0x55f022826e1b in parse_breakpoint_sals ../../gdb/breakpoint.c:9069 > #7 0x55f0228291c2 in create_breakpoint(gdbarch*, location_spec*, char const*, int, int, char const*, bool, int, int, bptype, int, auto_boolean, breakpoint_ops const*, int, int, int, unsigned int) ../../gdb/breakpoint.c:9312 > #8 0x55f02282c298 in break_command_1 ../../gdb/breakpoint.c:9471 > #9 0x55f02282d0bb in break_command(char const*, int) ../../gdb/breakpoint.c:9541 > #10 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94 > > 0x7d65a543d488 is located 904 bytes inside of 4064-byte region [0x7d65a543d100,0x7d65a543e0e0) > freed by thread T0 here: > #0 0x7f55aa91f79d in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:51 > #1 0x55f0221f6403 in xfree<void> ../../gdb/../gdbsupport/gdb-xfree.h:37 > #2 0x55f027b64851 in call_freefun ../../libiberty/obstack.c:103 > #3 0x55f027b66283 in _obstack_free ../../libiberty/obstack.c:280 > #4 0x55f0221f7a07 in auto_obstack::~auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:126 > #5 0x55f023f3dd83 in objfile::~objfile() ../../gdb/objfiles.c:509 > #6 0x55f023f511d8 in std::default_delete<objfile>::operator()(objfile*) const /usr/include/c++/15.2.1/bits/unique_ptr.h:93 > #7 0x55f023f4b8cd in std::unique_ptr<objfile, std::default_delete<objfile> >::~unique_ptr() /usr/include/c++/15.2.1/bits/unique_ptr.h:399 > #8 0x55f0240b6dab in owning_intrusive_list<objfile, intrusive_base_node<objfile> >::erase(intrusive_list_iterator<objfile, intrusive_base_node<objfile> >) ../../gdb/../gdbsupport/owning_intrusive_list.h:113 > #9 0x55f0240adb68 in program_space::remove_objfile(objfile*) ../../gdb/progspace.c:202 > #10 0x55f023f3cfcf in objfile::unlink() ../../gdb/objfiles.c:409 > #11 0x55f023f40faf in objfile_purge_solibs(program_space*) ../../gdb/objfiles.c:687 > #12 0x55f02487ec19 in no_shared_libraries(program_space*) ../../gdb/solib.c:1359 > #13 0x55f024b37e1e in target_pre_inferior() ../../gdb/target.c:2474 > #14 0x55f0238ac7cd in run_command_1 ../../gdb/infcmd.c:381 > #15 0x55f0238ae438 in run_command ../../gdb/infcmd.c:510 > #16 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94 > > previously allocated by thread T0 here: > #0 0x7f55aa920cb5 in malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:67 > #1 0x55f02241d780 in xmalloc ../../gdb/alloc.c:52 > #2 0x55f027b6461f in call_chunkfun ../../libiberty/obstack.c:94 > #3 0x55f027b649d1 in _obstack_begin_worker ../../libiberty/obstack.c:141 > #4 0x55f027b650c5 in _obstack_begin ../../libiberty/obstack.c:164 > #5 0x55f0221f775a in auto_obstack::auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:123 > #6 0x55f023f39c91 in objfile::objfile(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>) ../../gdb/objfiles.c:257 > #7 0x55f023f3ccaa in objfile::make(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>, objfile*) ../../gdb/objfiles.c:392 > #8 0x55f02498b1d2 in symbol_file_add_with_addrs ../../gdb/symfile.c:1069 > #9 0x55f02498c099 in symbol_file_add_from_bfd(gdb::ref_ptr<bfd, gdb_bfd_ref_policy> const&, char const*, enum_flags<symfile_add_flag>, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) ../../gdb/symfile.c:1156 > #10 0x55f02487255b in solib_read_symbols(solib&, enum_flags<symfile_add_flag>) ../../gdb/solib.c:660 > #11 0x55f024876c0c in solib_add(char const*, int, int) ../../gdb/solib.c:993 > #12 0x55f02487f1f8 in handle_solib_event() ../../gdb/solib.c:1399 > #13 0x55f0227df91f in bpstat_stop_status(address_space const*, unsigned long, thread_info*, target_waitstatus const&, bpstat*) ../../gdb/breakpoint.c:5962 > #14 0x55f023944fa8 in handle_signal_stop ../../gdb/infrun.c:7130 > #15 0x55f02393e2a1 in handle_inferior_event ../../gdb/infrun.c:6574 > #16 0x55f0239279f2 in fetch_inferior_event() ../../gdb/infrun.c:4713 > #17 0x55f023885fe3 in inferior_event_handler(inferior_event_type) ../../gdb/inf-loop.c:42 > #18 0x55f023af706e in handle_target_event ../../gdb/linux-nat.c:4449 > #19 0x55f027c2d2f0 in handle_file_event ../../gdbsupport/event-loop.cc:551 > #20 0x55f027c2e4ff in gdb_wait_for_event ../../gdbsupport/event-loop.cc:672 > > It happened because last_displayed_symtab_info of stack.c still contained > a reference to a symtab that was already freed in the 2nd run. > This fixes it by clearing last_displayed_symtab_info in the objfile > destructor, if it is pointing to that objfile. > Now setting of the 2nd breakpoint works: > > (gdb) break 18 > Breakpoint 2 at 0x555555555141: file /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/so-impl-ld.c, line 18. > (gdb) > > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32668 > --- > Changes since v1: > - Clear last_displayed_symtab_info in the objfile destructor. > - Some test improvements. > --- > gdb/objfiles.c | 8 +++ > .../gdb.base/solib-breakpoints-rerun.exp | 49 +++++++++++++++++++ > 2 files changed, 57 insertions(+) > create mode 100644 gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp > > diff --git a/gdb/objfiles.c b/gdb/objfiles.c > index 5c5b04c6458..0f9c9a046a2 100644 > --- a/gdb/objfiles.c > +++ b/gdb/objfiles.c > @@ -47,6 +47,7 @@ > #include "gdb_bfd.h" > #include "btrace.h" > #include "gdbsupport/pathstuff.h" > +#include "stack.h" > > #include <algorithm> > > @@ -501,6 +502,13 @@ objfile::~objfile () > and if so, call clear_current_source_symtab_and_line. */ > clear_current_source_symtab_and_line (this); > > + /* Check if last_displayed_symtab_info belongs to this objfile, > + and if so, call clear_last_displayed_sal. */ > + struct symtab *last_displayed_symtab = get_last_displayed_symtab (); > + if (last_displayed_symtab != nullptr > + && last_displayed_symtab->compunit ()->objfile () == this) > + clear_last_displayed_sal (); Modern C++ nit: /* Check if last_displayed_symtab_info belongs to this objfile, and if so, call clear_last_displayed_sal. */ if (symtab *last_displayed_symtab = get_last_displayed_symtab (); last_displayed_symtab != nullptr && last_displayed_symtab->compunit ()->objfile () == this) clear_last_displayed_sal (); > + > /* Rebuild section map next time we need it. */ > auto info = objfiles_pspace_data.get (pspace ()); > if (info != nullptr) > diff --git a/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp b/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp > new file mode 100644 > index 00000000000..d6089ca5dfb > --- /dev/null > +++ b/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp > @@ -0,0 +1,49 @@ > +# Copyright 2025 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program. If not, see <http://www.gnu.org/licenses/>. > + > +# Test setting new line-breakpoint after re-running with removed > +# breakpoint inside solib. > + > +require !use_gdb_stub > +require allow_shlib_tests > + > +standard_testfile so-impl-ld.c > +set libfile "solib1" > +set libsrc $srcdir/$subdir/$libfile.c > +set lib_sl [standard_output_file $libfile.sl] > + > +set lib_opts {debug shlib} > +set exec_opts [list debug shlib=$lib_sl] > + > +if { [build_executable "build shlib" $lib_sl $libsrc $lib_opts] != 0 } { > + return > +} > + > +if { [prepare_for_testing "prepare" $testfile $srcfile $exec_opts] != 0 } { > + return > +} > + > +gdb_breakpoint solib_main > + > +gdb_test "run" "Breakpoint $decimal, solib_main.*" "run with breakpoint" > + > +delete_breakpoints > + > +gdb_test "set confirm off" "" > +gdb_test "run" "\[Inferior $decimal \\(\[^\r\n\]*\\) exited normally\]" \ > + "run without breakpoint" You can probably use "with confirm off -- run". > + > +set bp_location [gdb_get_line_number "result = solib_main"] > +gdb_test "break $bp_location" "Breakpoint $decimal at .*" Please add a comment stating that GDB would crash (use-after-free, with ASan) during that break command, and why (high level, the one sentence version). LGTM with those fixed. Approved-By: Simon Marchi <simon.marchi@efficios.com> Simon
Am Donnerstag, 8. Januar 2026 um 21:05:00 MEZ hat Simon Marchi <simark@simark.ca> Folgendes geschrieben: > On 12/22/25 11:55 AM, Hannes Domani wrote: > > When creating a new line-breakpoint after rerunning with a disabled or > > removed breakpoint in a solib, you currently get this use-after-free > > crash: > > > > (gdb) break solib_main > > Breakpoint 1 at 0x1030 > > (gdb) run > > Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun > > [Thread debugging using libthread_db enabled] > > Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". > > > > Breakpoint 1, solib_main (arg=100) at /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/solib1.c:7 > > 7 int ans = arg*arg; /* HERE */ > > (gdb) disable > > (gdb) set confirm off > > (gdb) run > > Starting program: /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/outputs/gdb.base/solib-breakpoints-rerun/solib-breakpoints-rerun > > [Thread debugging using libthread_db enabled] > > Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". > > [Inferior 1 (process 50868) exited normally] > > (gdb) break 18 > > ================================================================= > > ==50836==ERROR: AddressSanitizer: heap-use-after-free on address 0x7d65a543d488 at pc 0x55f022334c29 bp 0x7ffe9c7f45f0 sp 0x7ffe9c7f45e0 > > READ of size 8 at 0x7d65a543d488 thread T0 > > #0 0x55f022334c28 in symtab::filename() const ../../gdb/symtab.h:1747 > > #1 0x55f023a32b7d in create_sals_line_offset ../../gdb/linespec.c:2013 > > #2 0x55f023a37937 in convert_linespec_to_sals ../../gdb/linespec.c:2294 > > #3 0x55f023a3cf79 in parse_linespec ../../gdb/linespec.c:2652 > > #4 0x55f023a415b2 in location_spec_to_sals ../../gdb/linespec.c:3050 > > #5 0x55f023a423b0 in decode_line_full(location_spec*, int, program_space*, symtab*, int, linespec_result*, char const*, char const*) ../../gdb/linespec.c:3126 > > #6 0x55f022826e1b in parse_breakpoint_sals ../../gdb/breakpoint.c:9069 > > #7 0x55f0228291c2 in create_breakpoint(gdbarch*, location_spec*, char const*, int, int, char const*, bool, int, int, bptype, int, auto_boolean, breakpoint_ops const*, int, int, int, unsigned int) ../../gdb/breakpoint.c:9312 > > #8 0x55f02282c298 in break_command_1 ../../gdb/breakpoint.c:9471 > > #9 0x55f02282d0bb in break_command(char const*, int) ../../gdb/breakpoint.c:9541 > > #10 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94 > > > > 0x7d65a543d488 is located 904 bytes inside of 4064-byte region [0x7d65a543d100,0x7d65a543e0e0) > > freed by thread T0 here: > > #0 0x7f55aa91f79d in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:51 > > #1 0x55f0221f6403 in xfree<void> ../../gdb/../gdbsupport/gdb-xfree.h:37 > > #2 0x55f027b64851 in call_freefun ../../libiberty/obstack.c:103 > > #3 0x55f027b66283 in _obstack_free ../../libiberty/obstack.c:280 > > #4 0x55f0221f7a07 in auto_obstack::~auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:126 > > #5 0x55f023f3dd83 in objfile::~objfile() ../../gdb/objfiles.c:509 > > #6 0x55f023f511d8 in std::default_delete<objfile>::operator()(objfile*) const /usr/include/c++/15.2.1/bits/unique_ptr.h:93 > > #7 0x55f023f4b8cd in std::unique_ptr<objfile, std::default_delete<objfile> >::~unique_ptr() /usr/include/c++/15.2.1/bits/unique_ptr.h:399 > > #8 0x55f0240b6dab in owning_intrusive_list<objfile, intrusive_base_node<objfile> >::erase(intrusive_list_iterator<objfile, intrusive_base_node<objfile> >) ../../gdb/../gdbsupport/owning_intrusive_list.h:113 > > #9 0x55f0240adb68 in program_space::remove_objfile(objfile*) ../../gdb/progspace.c:202 > > #10 0x55f023f3cfcf in objfile::unlink() ../../gdb/objfiles.c:409 > > #11 0x55f023f40faf in objfile_purge_solibs(program_space*) ../../gdb/objfiles.c:687 > > #12 0x55f02487ec19 in no_shared_libraries(program_space*) ../../gdb/solib.c:1359 > > #13 0x55f024b37e1e in target_pre_inferior() ../../gdb/target.c:2474 > > #14 0x55f0238ac7cd in run_command_1 ../../gdb/infcmd.c:381 > > #15 0x55f0238ae438 in run_command ../../gdb/infcmd.c:510 > > #16 0x55f022b05f56 in do_simple_func ../../gdb/cli/cli-decode.c:94 > > > > previously allocated by thread T0 here: > > #0 0x7f55aa920cb5 in malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:67 > > #1 0x55f02241d780 in xmalloc ../../gdb/alloc.c:52 > > #2 0x55f027b6461f in call_chunkfun ../../libiberty/obstack.c:94 > > #3 0x55f027b649d1 in _obstack_begin_worker ../../libiberty/obstack.c:141 > > #4 0x55f027b650c5 in _obstack_begin ../../libiberty/obstack.c:164 > > #5 0x55f0221f775a in auto_obstack::auto_obstack() ../../gdb/../gdbsupport/gdb_obstack.h:123 > > #6 0x55f023f39c91 in objfile::objfile(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>) ../../gdb/objfiles.c:257 > > #7 0x55f023f3ccaa in objfile::make(gdb::ref_ptr<bfd, gdb_bfd_ref_policy>, program_space*, char const*, enum_flags<objfile_flag>, objfile*) ../../gdb/objfiles.c:392 > > #8 0x55f02498b1d2 in symbol_file_add_with_addrs ../../gdb/symfile.c:1069 > > #9 0x55f02498c099 in symbol_file_add_from_bfd(gdb::ref_ptr<bfd, gdb_bfd_ref_policy> const&, char const*, enum_flags<symfile_add_flag>, std::vector<other_sections, std::allocator<other_sections> >*, enum_flags<objfile_flag>, objfile*) ../../gdb/symfile.c:1156 > > #10 0x55f02487255b in solib_read_symbols(solib&, enum_flags<symfile_add_flag>) ../../gdb/solib.c:660 > > #11 0x55f024876c0c in solib_add(char const*, int, int) ../../gdb/solib.c:993 > > #12 0x55f02487f1f8 in handle_solib_event() ../../gdb/solib.c:1399 > > #13 0x55f0227df91f in bpstat_stop_status(address_space const*, unsigned long, thread_info*, target_waitstatus const&, bpstat*) ../../gdb/breakpoint.c:5962 > > #14 0x55f023944fa8 in handle_signal_stop ../../gdb/infrun.c:7130 > > #15 0x55f02393e2a1 in handle_inferior_event ../../gdb/infrun.c:6574 > > #16 0x55f0239279f2 in fetch_inferior_event() ../../gdb/infrun.c:4713 > > #17 0x55f023885fe3 in inferior_event_handler(inferior_event_type) ../../gdb/inf-loop.c:42 > > #18 0x55f023af706e in handle_target_event ../../gdb/linux-nat.c:4449 > > #19 0x55f027c2d2f0 in handle_file_event ../../gdbsupport/event-loop.cc:551 > > #20 0x55f027c2e4ff in gdb_wait_for_event ../../gdbsupport/event-loop.cc:672 > > > > It happened because last_displayed_symtab_info of stack.c still contained > > a reference to a symtab that was already freed in the 2nd run. > > This fixes it by clearing last_displayed_symtab_info in the objfile > > destructor, if it is pointing to that objfile. > > Now setting of the 2nd breakpoint works: > > > > (gdb) break 18 > > Breakpoint 2 at 0x555555555141: file /home/src/lappy/binutils-gdb.git/build/gdb/testsuite/../../../gdb/testsuite/gdb.base/so-impl-ld.c, line 18. > > (gdb) > > > > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32668 > > --- > > Changes since v1: > > - Clear last_displayed_symtab_info in the objfile destructor. > > - Some test improvements. > > --- > > gdb/objfiles.c | 8 +++ > > .../gdb.base/solib-breakpoints-rerun.exp | 49 +++++++++++++++++++ > > 2 files changed, 57 insertions(+) > > create mode 100644 gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp > > > > diff --git a/gdb/objfiles.c b/gdb/objfiles.c > > index 5c5b04c6458..0f9c9a046a2 100644 > > --- a/gdb/objfiles.c > > +++ b/gdb/objfiles.c > > @@ -47,6 +47,7 @@ > > #include "gdb_bfd.h" > > #include "btrace.h" > > #include "gdbsupport/pathstuff.h" > > +#include "stack.h" > > > > #include <algorithm> > > > > @@ -501,6 +502,13 @@ objfile::~objfile () > > and if so, call clear_current_source_symtab_and_line. */ > > clear_current_source_symtab_and_line (this); > > > > + /* Check if last_displayed_symtab_info belongs to this objfile, > > + and if so, call clear_last_displayed_sal. */ > > + struct symtab *last_displayed_symtab = get_last_displayed_symtab (); > > + if (last_displayed_symtab != nullptr > > + && last_displayed_symtab->compunit ()->objfile () == this) > > + clear_last_displayed_sal (); > > Modern C++ nit: > > /* Check if last_displayed_symtab_info belongs to this objfile, > and if so, call clear_last_displayed_sal. */ > if (symtab *last_displayed_symtab = get_last_displayed_symtab (); > last_displayed_symtab != nullptr > && last_displayed_symtab->compunit ()->objfile () == this) > clear_last_displayed_sal (); > > > + > > /* Rebuild section map next time we need it. */ > > auto info = objfiles_pspace_data.get (pspace ()); > > if (info != nullptr) > > diff --git a/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp b/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp > > new file mode 100644 > > index 00000000000..d6089ca5dfb > > --- /dev/null > > +++ b/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp > > @@ -0,0 +1,49 @@ > > +# Copyright 2025 Free Software Foundation, Inc. > > + > > +# This program is free software; you can redistribute it and/or modify > > +# it under the terms of the GNU General Public License as published by > > +# the Free Software Foundation; either version 3 of the License, or > > +# (at your option) any later version. > > +# > > +# This program is distributed in the hope that it will be useful, > > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +# GNU General Public License for more details. > > +# > > +# You should have received a copy of the GNU General Public License > > +# along with this program. If not, see <http://www.gnu.org/licenses/>. > > + > > +# Test setting new line-breakpoint after re-running with removed > > +# breakpoint inside solib. > > + > > +require !use_gdb_stub > > +require allow_shlib_tests > > + > > +standard_testfile so-impl-ld.c > > +set libfile "solib1" > > +set libsrc $srcdir/$subdir/$libfile.c > > +set lib_sl [standard_output_file $libfile.sl] > > + > > +set lib_opts {debug shlib} > > +set exec_opts [list debug shlib=$lib_sl] > > + > > +if { [build_executable "build shlib" $lib_sl $libsrc $lib_opts] != 0 } { > > + return > > +} > > + > > +if { [prepare_for_testing "prepare" $testfile $srcfile $exec_opts] != 0 } { > > + return > > +} > > + > > +gdb_breakpoint solib_main > > + > > +gdb_test "run" "Breakpoint $decimal, solib_main.*" "run with breakpoint" > > + > > +delete_breakpoints > > + > > +gdb_test "set confirm off" "" > > +gdb_test "run" "\[Inferior $decimal \\(\[^\r\n\]*\\) exited normally\]" \ > > + "run without breakpoint" > > You can probably use "with confirm off -- run". > > > > + > > +set bp_location [gdb_get_line_number "result = solib_main"] > > +gdb_test "break $bp_location" "Breakpoint $decimal at .*" > > Please add a comment stating that GDB would crash (use-after-free, with > ASan) during that break command, and why (high level, the one sentence > > version). > > > LGTM with those fixed. > > Approved-By: Simon Marchi <simon.marchi@efficios.com> Pushed with these changes, thanks. Hannes
diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 5c5b04c6458..0f9c9a046a2 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -47,6 +47,7 @@ #include "gdb_bfd.h" #include "btrace.h" #include "gdbsupport/pathstuff.h" +#include "stack.h" #include <algorithm> @@ -501,6 +502,13 @@ objfile::~objfile () and if so, call clear_current_source_symtab_and_line. */ clear_current_source_symtab_and_line (this); + /* Check if last_displayed_symtab_info belongs to this objfile, + and if so, call clear_last_displayed_sal. */ + struct symtab *last_displayed_symtab = get_last_displayed_symtab (); + if (last_displayed_symtab != nullptr + && last_displayed_symtab->compunit ()->objfile () == this) + clear_last_displayed_sal (); + /* Rebuild section map next time we need it. */ auto info = objfiles_pspace_data.get (pspace ()); if (info != nullptr) diff --git a/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp b/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp new file mode 100644 index 00000000000..d6089ca5dfb --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-breakpoints-rerun.exp @@ -0,0 +1,49 @@ +# Copyright 2025 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Test setting new line-breakpoint after re-running with removed +# breakpoint inside solib. + +require !use_gdb_stub +require allow_shlib_tests + +standard_testfile so-impl-ld.c +set libfile "solib1" +set libsrc $srcdir/$subdir/$libfile.c +set lib_sl [standard_output_file $libfile.sl] + +set lib_opts {debug shlib} +set exec_opts [list debug shlib=$lib_sl] + +if { [build_executable "build shlib" $lib_sl $libsrc $lib_opts] != 0 } { + return +} + +if { [prepare_for_testing "prepare" $testfile $srcfile $exec_opts] != 0 } { + return +} + +gdb_breakpoint solib_main + +gdb_test "run" "Breakpoint $decimal, solib_main.*" "run with breakpoint" + +delete_breakpoints + +gdb_test "set confirm off" "" +gdb_test "run" "\[Inferior $decimal \\(\[^\r\n\]*\\) exited normally\]" \ + "run without breakpoint" + +set bp_location [gdb_get_line_number "result = solib_main"] +gdb_test "break $bp_location" "Breakpoint $decimal at .*"