This log is from a Debian 11 machine with GNU ld 2.31 (according to ld --version command):
gdb ./main
Reading symbols from ./main...
(No debugging symbols found in ./main)
(gdb) run
Starting program: /home/user/Documents/dlopen-lock/main
Library 1 loaded successfully!
Program received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff7fc8126 in func () from /home/user/Documents/dlopen-lock/lib1.so
(gdb) gef
GEF for linux ready, type `gef' to start, `gef config' to configure
91 commands loaded for GDB 10.1.90.20210103-git using Python engine 3.9
[*] 5 commands could not be loaded, run `gef missing` to know why.
[+] Configuration from '/home/user/.gef.rc' restored
[+] 35 extra commands added from '/home/user/Documents/gef-extras/scripts'
gef➤ code 3 1
─────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x7ffff7fc8125 <func+16> int3
→ 0x7ffff7fc8126 <func+17> mov esi, 0x1
0x7ffff7fc812b <func+22> lea rdi, [rip+0xeed] # 0x7ffff7fc901f
0x7ffff7fc8132 <func+29> call 0x7ffff7fc8030 <dlopen@plt>
────────────────────────────────────────────────────────────────────────────────────────
gef➤ # ^ We break from constructor of lib1 before doing dlopen on lib2 (using an int3 trap)
gef➤ break rtld_lock_default_lock_recursive
Breakpoint 1 at 0x7ffff7fd30e0: file rtld.c, line 841.
gef➤ break rtld_lock_default_unlock_recursive
Breakpoint 2 at 0x7ffff7fd30f0: file rtld.c, line 847.
gef➤ continue
Continuing.
Breakpoint 1, rtld_lock_default_lock_recursive (lock=0x7ffff7ffd968 <_rtld_global+2312>) at rtld.c:841
841 rtld.c: No such file or directory.
gef➤ print _rtld_global._dl_load_lock
$1 = {
mutex = {
__data = {
__lock = 0x0,
__count = 0x1,
__owner = 0x0,
__nusers = 0x0,
__kind = 0x1,
__spins = 0x0,
__elision = 0x0,
__list = {
__prev = 0x0,
__next = 0x0
}
},
__size = "\000\000\000\000\001", '\000' <repeats 11 times>, "\001", '\000' <repeats 22 times>,
__align = 0x100000000
}
}
gef➤ print _rtld_global._dl_load_lock.mutex.__data.__count
$2 = 0x1
gef➤ # ^ This count increments/decrements with every loader lock/unlock
gef➤ x/5i rtld_lock_default_lock_recursive
=> 0x7ffff7fd30e0 <rtld_lock_default_lock_recursive>: add DWORD PTR [rdi+0x4],0x1
0x7ffff7fd30e4 <rtld_lock_default_lock_recursive+4>: ret
0x7ffff7fd30e5: data16 nop WORD PTR cs:[rax+rax*1+0x0]
0x7ffff7fd30f0 <rtld_lock_default_unlock_recursive>: sub DWORD PTR [rdi+0x4],0x1
0x7ffff7fd30f4 <rtld_lock_default_unlock_recursive+4>: ret
gef➤ print lock
$3 = (void *) 0x7ffff7ffd968 <_rtld_global+2312>
gef➤ x/1wx lock+0x4
0x7ffff7ffd96c <_rtld_global+2316>: 0x00000001
gef➤ x/1wx $rdi+0x4
0x7ffff7ffd96c <_rtld_global+2316>: 0x00000001
gef➤ nexti
841 in rtld.c
gef➤ print _rtld_global._dl_load_lock.mutex.__data.__count
$4 = 0x2
gef➤ x/1wx lock+0x4
0x7ffff7ffd96c <_rtld_global+2316>: 0x00000002
gef➤ x/1wx $rdi+0x4
0x7ffff7ffd96c <_rtld_global+2316>: 0x00000002
gef➤ backtrace
#0 rtld_lock_default_lock_recursive (lock=0x7ffff7ffd968 <_rtld_global+2312>) at rtld.c:841
#1 0x00007ffff7fe5896 in _dl_open (file=0x7ffff7fc901f "lib2.so", mode=0x80000001, caller_dlopen=0x7ffff7fc8137 <func+34>, nsid=0xfffffffffffffffe, argc=0x1, argv=0x7fffffffe828, env=0x7fffffffe838) at dl-open.c:786
#2 0x00007ffff7fa0258 in dlopen_doit (a=a@entry=0x7fffffffe110) at dlopen.c:66
#3 0x00007ffff7f00a90 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffe0b0, operate=0x7ffff7fa0200 <dlopen_doit>, args=0x7fffffffe110) at dl-error-skeleton.c:208
#4 0x00007ffff7f00b4f in __GI__dl_catch_error (objname=0x7ffff7fa40f0 <last_result+16>, errstring=0x7ffff7fa40f8 <last_result+24>, mallocedp=0x7ffff7fa40e8 <last_result+8>, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:227
#5 0x00007ffff7fa0a65 in _dlerror_run (operate=operate@entry=0x7ffff7fa0200 <dlopen_doit>, args=args@entry=0x7fffffffe110) at dlerror.c:170
#6 0x00007ffff7fa02e4 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#7 0x00007ffff7fc8137 in func () from /home/user/Documents/dlopen-lock/lib1.so
#8 0x00007ffff7fe1fe2 in call_init (l=<optimized out>, argc=argc@entry=0x1, argv=argv@entry=0x7fffffffe828, env=env@entry=0x7fffffffe838) at dl-init.c:72
#9 0x00007ffff7fe20e9 in call_init (env=0x7fffffffe838, argv=0x7fffffffe828, argc=0x1, l=<optimized out>) at dl-init.c:30
#10 _dl_init (main_map=0x5555555592e0, argc=0x1, argv=0x7fffffffe828, env=0x7fffffffe838) at dl-init.c:119
#11 0x00007ffff7f00aed in __GI__dl_catch_exception (exception=<optimized out>, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:182
#12 0x00007ffff7fe6058 in dl_open_worker (a=a@entry=0x7fffffffe4d0) at dl-open.c:758
#13 0x00007ffff7f00a90 in __GI__dl_catch_exception (exception=0x7fffffffe4b0, operate=0x7ffff7fe5ca0 <dl_open_worker>, args=0x7fffffffe4d0) at dl-error-skeleton.c:208
#14 0x00007ffff7fe58fa in _dl_open (file=0x555555556014 "lib1.so", mode=0x80000001, caller_dlopen=0x55555555516d <main+21>, nsid=0xfffffffffffffffe, argc=0x1, argv=0x7fffffffe4b0, env=0x7fffffffe838) at dl-open.c:837
#15 0x00007ffff7fa0258 in dlopen_doit (a=a@entry=0x7fffffffe6f0) at dlopen.c:66
#16 0x00007ffff7f00a90 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffe690, operate=0x7ffff7fa0200 <dlopen_doit>, args=0x7fffffffe6f0) at dl-error-skeleton.c:208
#17 0x00007ffff7f00b4f in __GI__dl_catch_error (objname=0x7ffff7fa40f0 <last_result+16>, errstring=0x7ffff7fa40f8 <last_result+24>, mallocedp=0x7ffff7fa40e8 <last_result+8>, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:227
#18 0x00007ffff7fa0a65 in _dlerror_run (operate=operate@entry=0x7ffff7fa0200 <dlopen_doit>, args=args@entry=0x7fffffffe6f0) at dlerror.c:170
#19 0x00007ffff7fa02e4 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#20 0x000055555555516d in main ()
gef➤ delete breakpoints 1 2
gef➤ continue
Continuing.
Library 2 loaded successfully from constructor of Library 1!
[Inferior 1 (process 12003) exited normally]
gef➤ exit