We set write watchpoints on the dl_load_lock
and dl_load_write_lock
data, then load two libraries to check how often and where in the code these locks are acquired.
Ensure you have glibc debug symbols and source code downloaded. Fedora's GDB automatically downloads symbols and source code. On Debian, you must install the libc6-dbg
(you may need to enable the debug source in your /etc/apt/sources.list
) and glibc-source
packages.
When printing a backtrace
in GDB (or generally printing a variable name), you may see <optimized out>
in the output for some function parameter values. Consistently seeing the values of these variables requires compiling glibc with no optimizations enabled (i.e. setting the -O0
or -Og
GCC option). You could also set a breakpoint where the variable is initially set or passed into a function to see its value before optimizations remove it. Typically, you don't need to know the value of these <optimized out>
variables, though, so you can ignore them.
In the backtrace of the GDB log file, you can see entries to functions like dlerror_run
, _dl_catch_error
and __GI__dl_catch_exception
(_dl_catch_exception
in the code). These aren't indicative of an error occurring. Rather, these functions merely set up an error handler and perform handling to catch exceptions if an error/exception occurs in the dynamic linker. The error codes are conformant to errno. Error codes returned by the dynamic linker includes ENOMEM
(out of memory) or file access error codes (like ENOENT
or EACCES
). Dynamic linker functions may also pass 0
as the errno
to indicate an error specific to the dynamic linker's functionality. In either case, an exception occurs, thus stopping the dynamic linker from proceeding and continuing execution in _dl_catch_exception
(called by _dl_catch_error
). A programmer can determine if dlopen
failed by checking for a NULL
return value and then get an error message with dlerror
.