GDB duplicate solib question
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Fri Jul 25 15:50:50 GMT 2025
On 25/07/25 12:11, Simon Marchi wrote:
> On 7/16/25 3:58 PM, Simon Marchi wrote:
>> Hello,
>>
>> I stumbled on some code in GDB that is somewhat getting in my way, and
>> I'm not sure it's still useful. It concerns duplicate in dynamic linker
>> link maps, so I'm including libc-alpha, in case someone there knows more
>> about this.
>>
>> The code in question implies the possibility of multiple struct solib
>> objects referring to the same struct objfile (N solib to 1 objfile
>> relationship). I previously assumed a 1:1 (at most) relationship.
>>
>> First, the solib_used function [1] is used at a few places to check if a
>> struct objfile is referred to by more than one struct solib. We use
>> this function to avoid free-ing the objfile when removing an solib, if
>> that objfile is also pointed to by another solib. That function was
>> added to fix a bug on the QNX platform [2][3]. From the original email:
>>
>> What happened is that a process loaded the same shared object more than
>> once. Then it crashed and a core was generated.
>>
>> In the core, we had a link map specifying the same shared object more
>> than once. While traversing the link map, gdb loaded shared objects
>> (symbols), thus associating each so_list object with an objfile object.
>> During the process, it detected duplicates and associated multiple
>> so_list objects with the same objfile instance.
>>
>> My understanding is that on QNX (at least at that time), dlopen-ing the
>> same library twice would result in having two entries in the link map,
>> even if the library is really mapped just once.
>>
>> I believe that the code detecting duplicates and associating multiple
>> solib objects (previously called so_list) to the same objfile is this
>> one in solib_read_symbols [4]:
>>
>> /* Have we already loaded this shared object? */
>> so.objfile = nullptr;
>> for (objfile *objfile : current_program_space->objfiles ())
>> {
>> if (filename_cmp (objfile_name (objfile), so.name.c_str ())
>> == 0
>> && objfile->addr_low == so.addr_low)
>> {
>> so.objfile = objfile;
>> break;
>> }
>> }
>>
>> This supports my understanding of there being two entries in the link
>> map with the same lib at the same address.
>>
>> This code that detects duplicate solibs was added much earlier [5][6],
>> in 2000, implying that even then, there might have been some instances
>> of this.
>>
>> As far as I know, on "modern" systems, if you dlopen a library twice and
>> the linker re-uses an existing mapping, it just increases a refcount.
>> You won't see two entries in the link map.
>>
>> If you dlopen a library twice with some options that causes the linker
>> to map the library twice at different addresses, then you get two link
>> map entries. The GDB code above would not consider them duplicates, so
>> we wouldn't end up with two solibs sharing one objfile.
>>
>> So, my question is: is anybody aware of a legitimate case for the link
>> map to contain multiple entries for the same lib at the same address?
>>
>> The "good" news is that we no longer support QNX. But since the code to
>> detect duplicates predates that, I'm wondering if there is something
>> else I'm missing.
>>
>> I'm thinking of getting rid of that code, which would simplify things a
>> little bit. And if a case like the QNX one was to come back, I think I
>> would hide the complexity behind the specific solib_ops implementation:
>> if two link map entries refer to the same mapping, then return just one
>> struct solib for those.
>
> To answer my own question: this case actually happens for the dynamic
> linker when using multiple linker namespaces. The dynamic linker will
> be visible in all namespaces, so will be listed in the link maps of all
> namespaces, but in reality it's the same instance, at the same
> addresses. In GDB, we create one struct solib for each "view" of the
> dynamic linker (so, if you have 3 namespaces, we create 3 struct solib
> for the dynamic linker), which should all point to the same objfile.
>
> I wonder, if a shared library was read-only (no .data, no .bss, etc), if
> the program loaded it in multiple linker namespaces, could the libc
> optimize it by only having one mapping reused in all namespaces?
I think that was the idea of DF_GNU_1_UNIQUE [1], but the proposal got
stalled.
[1] https://sourceware.org/pipermail/libc-alpha/2021-October/131818.html
More information about the Libc-alpha
mailing list