From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 417E03848592; Thu, 16 Jun 2022 16:41:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 417E03848592 From: "mhov at undo dot io" To: gdb-prs@sourceware.org Subject: [Bug gdb/29257] New: Double free of demangled symbol name Date: Thu, 16 Jun 2022 16:41:58 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gdb X-Bugzilla-Component: gdb X-Bugzilla-Version: 10.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: mhov at undo dot io X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gdb-prs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-prs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jun 2022 16:41:58 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D29257 Bug ID: 29257 Summary: Double free of demangled symbol name Product: gdb Version: 10.1 Status: UNCONFIRMED Severity: normal Priority: P2 Component: gdb Assignee: unassigned at sourceware dot org Reporter: mhov at undo dot io Target Milestone: --- We've captured a GDB crash where a demangled C++ symbol name is freed twice= - double free or corruption (fasttop): #0 0x00007f270ffcdc8e in abort () from /tmp/undodb.639706.1655366126.1865206.f7b28b36e39ecdfc/debuggee-1-il8cy4y9/= symbol-files/lib64/libc.so.6 #1 0x00007f271003d057 in __libc_message () from /tmp/undodb.639706.1655366126.1865206.f7b28b36e39ecdfc/debuggee-1-il8cy4y9/= symbol-files/lib64/libc.so.6 #2 0x00007f27100441bc in malloc_printerr () from /tmp/undodb.639706.1655366126.1865206.f7b28b36e39ecdfc/debuggee-1-il8cy4y9/= symbol-files/lib64/libc.so.6 #3 0x00007f2710045c04 in _int_free () from /tmp/undodb.639706.1655366126.1865206.f7b28b36e39ecdfc/debuggee-1-il8cy4y9/= symbol-files/lib64/libc.so.6 #4 0x00000000008f8a59 in xfree (ptr=3D0x5daaff0 "\300\304\070\a") at .././gdb-10.2/gdb/../gdbsupport/common-utils.h:62 #5 gdb::xfree_deleter::operator() (this=3D, ptr=3D0x5daaff0 "\300\304\070\a") at .././gdb-10.2/gdb/../gdbsupport/gdb_unique_ptr.h:34 #6 std::unique_ptr >::~unique_ptr (this=3D, __in_chrg=3D) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/unique_ptr.h:274 #7 general_symbol_info::compute_and_set_names (this=3Dthis@entry=3D0x7f26e= bcd0808, linkage_name=3D..., copy_name=3Dcopy_name@entry=3Dfalse, per_bfd=3D0x5742db= 0, hash=3D...) at .././gdb-10.2/gdb/symtab.c:881 #8 0x000000000079ad85 in minimal_symbol_reader::::operator() (end=3D, start=3D, __closure=3D) at .././gdb-10.2/gdb/symtab.h:421 #9 gdb::parallel_for_each > (callback=3D..., last=3D, first=3D) at .././gdb-10.2/gdb/../gdbsupport/parallel-for.h:76 #10 minimal_symbol_reader::install (this=3Dthis@entry=3D0x7ffdedc85590) at .././gdb-10.2/gdb/minsyms.c:1409 #11 0x00000000006ad0a2 in elf_read_minimal_symbols (symfile_flags=3D8, ei=3D0x7ffdedc85570, objfile=3D0x82e8980) at .././gdb-10.2/gdb/elfread.c:11= 75 #12 elf_symfile_read (objfile=3D0x82e8980, symfile_flags=3D...) at .././gdb-10.2/gdb/elfread.c:1216 #13 0x00000000008f0c95 in read_symbols (objfile=3D0x82e8980, add_flags=3D..= .) at .././gdb-10.2/gdb/symfile.c:782 #14 0x00000000008f0595 in syms_from_objfile_1 (add_flags=3D..., addrs=3D0x7ffdedc856f0, objfile=3D0x82e8980) at .././gdb-10.2/gdb/symfile.c= :979 #15 syms_from_objfile (add_flags=3D..., addrs=3D, objfile=3D= 0x82e8980) at .././gdb-10.2/gdb/symfile.c:996 #16 symbol_file_add_with_addrs (abfd=3D, name=3D0x3b21d00 ..= ., add_flags=3D..., addrs=3D, flags=3D..., parent=3D) at .././gdb-10.2/gdb/symfile.c:1099 #17 0x00000000008c9aa4 in solib_read_symbols (so=3D0x3b21af0, flags=3D...) = at .././gdb-10.2/gdb/solib.c:688 #18 0x00000000008ca5d2 in solib_add (pattern=3Dpattern@entry=3D0x0, from_tty=3Dfrom_tty@entry=3D0, readsyms=3D1) at .././gdb-10.2/gdb/solib.c:9= 93 #19 0x00000000008ca769 in handle_solib_event () at .././gdb-10.2/gdb/solib.c:1266 I've been trying to understand how interning of demangled symbol names works and I'm still learning, so apologies if this report isn't very precise. During this crash, in minimal_symbol_reader::install I can see that we're finished collecting, sorting and compacting our list of existing and new minimal symbols. In my instance it looks like we have 9673 minsyms already defined for this objfile, and we're about to potentially add 8509 more. We'= re in the point where we compute and insert demangled names in parallel in gdb::parallel_for_each (though the machine has decided to use a single thre= ad in this instance, so the main thread is doing all of the work). We're crashing in the second phase of the parallel workload. general_symbol_info::compute_and_set_names has just finished and the demang= led name that is managed by the following unique_xmalloc_ptr is released: https://sourceware.org/git/?p=3Dbinutils-gdb.git;a=3Dblob;f=3Dgdb/symtab.c;= hb=3Dce35d7163e779b1321058b22f005c70ce1524b25#l880. It turns out that the same instance of this demangled name is assigned to multiple symbols. These symbols have identical mangled and demangled names,= but they come from different source files and have different addresses. At the time of crash, the first of these similar symbols I can trace back as being one of the existing symbols for this objfile. I.e we've called elf_symfile_read on this object before and we loaded a bunch of symbols the= n. At that point the demangled name got allocated from libc heap while first computing the demangled name. Then, because the demangled name hadn't been encountered yet, it was std::move'ed into the hash table that contains the demangled names. Fair enough, we allocate the name while demangling it, and the ownership of that storage is transferred to the hash table slot. Now - the second time we're doing elf_symfile_read for this object, we're a= gain considering this symbol which was already interned, and this time the symbol already has had a demangled name assigned to, so we don't allocate a new na= me for it. The demangled name is already present in the hash table, so we don'= t go through the effort of allocating a new hash table slot for the demangled na= me and we also don't end up moving the storage for the demangled name into a n= ew hash slot. Because of this, the unique_xmalloc_ptr is still the rightful owner of this demangled name, so at the end of general_symbol_info::compute_and_set_names= it decides to free that storage when it goes out of scope. But wait - since th= is is a symbol that is being re-examined this demangled name is the exact same= one that was previously inserted into the hash table! We go ahead freeing it - = and when the next pre-existing symbol that has the same demangled name is being considered we try to free the same name again - leading to our crash. general_symbol_info::compute_and_set_names seems to do exactly one of these: 1. transfer the storage of the demangled name into the hash table 2. let the unique ptr free the storage on scope exit I think the rationale behind doing this is to allow multiple identical demangled names to be allocated upfront while ensuring that only one unique name is interned into the hash table. Subsequent duplicates will find the existing hash table slot, will not have their storage transferred into the = hash table and so will be freed by the unique ptr. However, I'm not sure that this takes into account the fact that, for exist= ing symbols, the demangled name may actually already be in the hashtable instea= d of having been allocated by symbol_find_demangled_name. We're seeing this problem with our Time-Travel debugger UDB, which will move around in execution history and might make it seem like the same library is being loaded multiple times. Is it otherwise normal to have elf_symfile_read called on the same object multiple times?=20 Note that I have a recording of this failure so I can produce more details = if required. I only have this failure captured for GDB 10.2. --=20 You are receiving this mail because: You are on the CC list for the bug.=