This log is taken starting from the main function. We set a watchpoint to on dl_load_lock and dl_write_lock to monitor where locks and unlocks occur. This is a Fedora 38 machine with GNU ld 2.39 (according to ld --version command):
NOTE: There are a few places where the Glibc calls __rtld_lock_unlock_recursive but you don't see it in the call stack upon doing "up" (in the call stack) and "list" (show source code) because it was optimized out with a tail call. Unlocks are usually done at the end of a funciton so they may be optimized out like this. Glibc still runs __rtld_lock_unlock_recursive but it's jumped (jmp instruction) to instead of called (call instruction) thus improving performance.
I've confirmed the tail call by looking at the end of _dl_add_to_namespace_list where it jumps to ___rtld_mutex_unlock then lets that function return (ret instruction) instead of _dl_add_to_namespace_list returning itself:
=> 0x7ffff7fd556f <_dl_add_to_namespace_list+143>: add $0x8,%rsp 0x7ffff7fd5573 <_dl_add_to_namespace_list+147>: pop %rbx 0x7ffff7fd5574 <_dl_add_to_namespace_list+148>: pop %r12 0x7ffff7fd5576 <_dl_add_to_namespace_list+150>: pop %r13 0x7ffff7fd5578 <_dl_add_to_namespace_list+152>: pop %rbp 0x7ffff7fd5579 <_dl_add_to_namespace_list+153>: jmp *0x274d1(%rip) # 0x7ffff7ffca50 <___rtld_mutex_unlock>
gdb ./main Reading symbols from ./main... (gdb) break main Breakpoint 1 at 0x40112a: file main.c, line 4. (gdb) run Starting program: /home/user/QubesIncoming/lab-bin/load-library/main [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, main () at main.c:4 4 dlopen("lib1.so", RTLD_LAZY); (gdb) list 1 #include <dlfcn.h> 2 3 int main() { 4 dlopen("lib1.so", RTLD_LAZY); 5 dlopen("lib2.so", RTLD_LAZY); 6 } (gdb) set print pretty (gdb) print _rtld_global $1 = { _dl_ns = {{ _ns_loaded = 0x7ffff7ffe2d0, _ns_nloaded = 4, _ns_main_searchlist = 0x7ffff7ffe5a8, _ns_global_scope_alloc = 0, _ns_global_scope_pending_adds = 0, libc_map = 0x7ffff7fc2090, _ns_unique_sym_table = { lock = { mutex = { __data = { __lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 1, __spins = 0, __elision = 0, __list = { __prev = 0x0, __next = 0x0 } }, __size = '\000' <repeats 16 times>, "\001", '\000' <repeats 22 times>, __align = 0 } }, entries = 0x0, size = 0, n_elements = 0, free = 0x0 }, _ns_debug = { base = { r_version = 0, r_map = 0x0, r_brk = 0, r_state = RT_CONSISTENT, r_ldbase = 0 }, r_next = 0x0 } }, { _ns_loaded = 0x0, _ns_nloaded = 0, _ns_main_searchlist = 0x0, _ns_global_scope_alloc = 0, _ns_global_scope_pending_adds = 0, libc_map = 0x0, _ns_unique_sym_table = { lock = { mutex = { __data = { __lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 0, __spins = 0, __elision = 0, __list = { __prev = 0x0, __next = 0x0 } }, __size = '\000' <repeats 39 times>, __align = 0 } }, entries = 0x0, size = 0, n_elements = 0, free = 0x0 }, _ns_debug = { base = { r_version = 0, r_map = 0x0, r_brk = 0, r_state = RT_CONSISTENT, r_ldbase = 0 }, r_next = 0x0 } } <repeats 15 times>}, _dl_nns = 1, _dl_load_lock = { mutex = { __data = { __lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 1, __spins = 0, __elision = 0, __list = { __prev = 0x0, __next = 0x0 } }, __size = '\000' <repeats 16 times>, "\001", '\000' <repeats 22 times>, __align = 0 } }, _dl_load_write_lock = { mutex = { __data = { __lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 1, __spins = 0, __elision = 0, __list = { __prev = 0x0, __next = 0x0 } }, __size = '\000' <repeats 16 times>, "\001", '\000' <repeats 22 times>, __align = 0 } }, _dl_load_tls_lock = { mutex = { __data = { __lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 1, __spins = 0, __elision = 0, __list = { __prev = 0x0, __next = 0x0 } }, __size = '\000' <repeats 16 times>, "\001", '\000' <repeats 22 times>, __align = 0 } }, _dl_load_adds = 4, _dl_initfirst = 0x0, _dl_profile_map = 0x0, _dl_num_relocations = 93, _dl_num_cache_relocations = 7, _dl_all_dirs = 0x7ffff7fc2000, _dl_rtld_map = { l_addr = 140737353916416, l_name = 0x400318 "/lib64/ld-linux-x86-64.so.2", l_ld = 0x7ffff7ffce40, l_next = 0x0, l_prev = 0x7ffff7fc2090, l_real = 0x7ffff7ffdab0 <_rtld_local+2736>, l_ns = 0, l_libname = 0x7ffff7ffe270 <_dl_rtld_libname>, l_info = {0x0, 0x0, 0x0, 0x0, 0x7ffff7ffce50, 0x7ffff7ffce70, 0x7ffff7ffce80, 0x7ffff7ffceb0, 0x7ffff7ffcec0, 0x7ffff7ffced0, 0x7ffff7ffce90, 0x7ffff7ffcea0, 0x0, 0x0, 0x7ffff7ffce40, 0x0 <repeats 15 times>, 0x7ffff7ffcf00, 0x0, 0x0, 0x0, 0x0, 0x7ffff7ffcf40, 0x7ffff7ffcf30, 0x7ffff7ffcf50, 0x0, 0x0, 0x7ffff7ffcef0, 0x7ffff7ffcee0, 0x7ffff7ffcf10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7ffff7ffcf20, 0x0 <repeats 25 times>, 0x7ffff7ffce60}, l_phdr = 0x7ffff7fca040, l_entry = 0, l_phnum = 11, l_ldnum = 0, l_searchlist = { r_list = 0x0, r_nlist = 0 }, l_symbolic_searchlist = { r_list = 0x0, r_nlist = 0 }, l_loader = 0x0, l_versions = 0x7ffff7fc2aa0, l_nversions = 8, l_nbuckets = 37, l_gnu_bitmask_idxbits = 3, l_gnu_shift = 8, l_gnu_bitmask = 0x7ffff7fca458, { l_gnu_buckets = 0x7ffff7fca478, l_chain = 0x7ffff7fca478 }, { l_gnu_chain_zero = 0x7ffff7fca508, l_buckets = 0x7ffff7fca508 }, l_direct_opencount = 0, l_type = lt_library, l_dt_relr_ref = 0, l_relocated = 1, l_init_called = 1, l_global = 1, l_reserved = 0, l_main_map = 0, l_visited = 1, l_map_used = 1, l_map_done = 0, l_phdr_allocated = 0, l_soname_added = 0, l_faked = 0, l_need_tls_init = 0, l_auditing = 0, l_audit_any_plt = 0, l_removed = 0, l_contiguous = 0, l_free_initfini = 0, l_ld_readonly = 0, l_find_object_processed = 0, l_nodelete_active = false, l_nodelete_pending = false, l_property = lc_property_unknown, l_x86_feature_1_and = 0, l_x86_isa_1_needed = 0, l_1_needed = 0, l_rpath_dirs = { dirs = 0x0, malloced = 0 }, l_reloc_result = 0x0, l_versyms = 0x7ffff7fcac02, l_origin = 0x0, l_map_start = 140737353916416, l_map_end = 140737354130120, l_init_called_next = 0x0, l_scope_mem = {0x0, 0x0, 0x0, 0x0}, l_scope_max = 0, l_scope = 0x0, l_local_scope = {0x0, 0x0}, l_file_id = { dev = 0, ino = 0 }, l_runpath_dirs = { dirs = 0x0, malloced = 0 }, l_initfini = 0x0, l_reldeps = 0x0, l_reldepsmax = 0, l_used = 1, l_feature_1 = 0, l_flags_1 = 0, l_flags = 0, l_idx = 0, l_mach = { plt = 0, gotplt = 0, tlsdesc_table = 0x0 }, l_lookup_cache = { sym = 0x7ffff7fca860, type_class = 0, value = 0x7ffff7ffdab0 <_rtld_local+2736>, ret = 0x7ffff7fca860 }, l_tls_initimage = 0x0, l_tls_initimage_size = 0, l_tls_blocksize = 0, l_tls_align = 0, l_tls_firstbyte_offset = 0, l_tls_offset = 0, l_tls_modid = 0, l_tls_dtor_count = 0, l_relro_addr = 203040, l_relro_size = 5856, l_serial = 0 }, _dl_rtld_auditstate = {{ cookie = 0, bindflags = 0 } <repeats 16 times>}, _dl_x86_feature_1 = 0, _dl_x86_feature_control = { ibt = cet_elf_property, shstk = cet_elf_property }, _dl_stack_flags = 6, _dl_tls_dtv_gaps = false, _dl_tls_max_dtv_idx = 1, _dl_tls_dtv_slotinfo_list = 0x7ffff7fc2b60, _dl_tls_static_nelem = 1, _dl_tls_static_used = 136, _dl_tls_static_optional = 512, _dl_initial_dtv = 0x7ffff7dce0e0, _dl_tls_generation = 1, _dl_scope_free_list = 0x0, _dl_stack_used = { next = 0x7ffff7ffe0a0 <_rtld_local+4256>, prev = 0x7ffff7ffe0a0 <_rtld_local+4256> }, _dl_stack_user = { next = 0x7ffff7dcda00, prev = 0x7ffff7dcda00 }, _dl_stack_cache = { next = 0x7ffff7ffe0c0 <_rtld_local+4288>, prev = 0x7ffff7ffe0c0 <_rtld_local+4288> }, _dl_stack_cache_actsize = 0, _dl_in_flight_stack = 0, _dl_stack_cache_lock = 0 } (gdb) print &_rtld_global._dl_load_lock $2 = (__rtld_lock_recursive_t *) 0x7ffff7ffda08 <_rtld_local+2568> (gdb) print &_rtld_global._dl_load_write_lock $3 = (__rtld_lock_recursive_t *) 0x7ffff7ffda30 <_rtld_local+2608> (gdb) watch *0x7ffff7ffda08 Hardware watchpoint 2: *0x7ffff7ffda08 (gdb) watch *0x7ffff7ffda30 Hardware watchpoint 3: *0x7ffff7ffda30 (gdb) info watchpoints Num Type Disp Enb Address What 2 hw watchpoint keep y *0x7ffff7ffda08 3 hw watchpoint keep y *0x7ffff7ffda30 (gdb) continue Continuing. Hardware watchpoint 2: *0x7ffff7ffda08 Old value = 0 New value = 1 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 130 assert (mutex->__data.__owner == 0); (gdb) backtrace #0 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 #1 0x00007ffff7fd5edb in _dl_open (file=0x402010 "lib1.so", mode=-2147483647, caller_dlopen=0x40113e <main+24>, nsid=-2, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:830 #2 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #3 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #4 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #5 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #6 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #7 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #8 0x000000000040113e in main () at main.c:4 (gdb) up #1 0x00007ffff7fd5edb in _dl_open (file=0x402010 "lib1.so", mode=-2147483647, caller_dlopen=0x40113e <main+24>, nsid=-2, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:830 830 __rtld_lock_lock_recursive (GL(dl_load_lock)); (gdb) list 825 if ((mode & RTLD_BINDING_MASK) == 0) 826 /* One of the flags must be set. */ 827 _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()")); 828 829 /* Make sure we are alone. */ 830 __rtld_lock_lock_recursive (GL(dl_load_lock)); 831 832 if (__glibc_unlikely (nsid == LM_ID_NEWLM)) 833 { 834 /* Find a new namespace. */ (gdb) continue Continuing. Hardware watchpoint 3: *0x7ffff7ffda30 Old value = 0 New value = 1 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 130 assert (mutex->__data.__owner == 0); (gdb) backtrace #0 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 #1 0x00007ffff7fd5507 in _dl_add_to_namespace_list (new=0x4052e0, nsid=0) at dl-object.c:33 #2 0x00007ffff7fd1c76 in _dl_map_object_from_fd (name=name@entry=0x402010 "lib1.so", origname=origname@entry=0x0, fd=-1, fbp=<optimized out>, realname=<optimized out>, loader=loader@entry=0x0, l_type=<optimized out>, mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>) at dl-load.c:1494 #3 0x00007ffff7fd2839 in _dl_map_object (loader=<optimized out>, loader@entry=0x7ffff7ffe2d0, name=name@entry=0x402010 "lib1.so", type=type@entry=2, trace_mode=trace_mode@entry=0, mode=mode@entry=-1879048191, nsid=<optimized out>) at dl-load.c:2253 #4 0x00007ffff7fd63bc in dl_open_worker_begin (a=a@entry=0x7fffffffdcf0) at dl-open.c:534 #5 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdb40, operate=operate@entry=0x7ffff7fd6310 <dl_open_worker_begin>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #6 0x00007ffff7fd5b70 in dl_open_worker (a=a@entry=0x7fffffffdcf0) at dl-open.c:782 #7 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdcd0, operate=operate@entry=0x7ffff7fd5b30 <dl_open_worker>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #8 0x00007ffff7fd5f44 in _dl_open (file=0x402010 "lib1.so", mode=<optimized out>, caller_dlopen=0x40113e <main+24>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:884 #9 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #10 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #11 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #12 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #13 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #14 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #15 0x000000000040113e in main () at main.c:4 (gdb) up #1 0x00007ffff7fd5507 in _dl_add_to_namespace_list (new=0x4052e0, nsid=0) at dl-object.c:33 33 __rtld_lock_lock_recursive (GL(dl_load_write_lock)); (gdb) list 28 /* Add the new link_map NEW to the end of the namespace list. */ 29 void 30 _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) 31 { 32 /* We modify the list of loaded objects. */ 33 __rtld_lock_lock_recursive (GL(dl_load_write_lock)); 34 35 if (GL(dl_ns)[nsid]._ns_loaded != NULL) 36 { 37 struct link_map *l = GL(dl_ns)[nsid]._ns_loaded; (gdb) continue Continuing. Hardware watchpoint 3: *0x7ffff7ffda30 Old value = 1 New value = 0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 70 LIBC_PROBE (mutex_release, 1, mutex); (gdb) backtrace #0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 #1 0x00007ffff7fd1c76 in _dl_map_object_from_fd (name=name@entry=0x402010 "lib1.so", origname=origname@entry=0x0, fd=-1, fbp=<optimized out>, realname=<optimized out>, loader=loader@entry=0x0, l_type=<optimized out>, mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>) at dl-load.c:1494 #2 0x00007ffff7fd2839 in _dl_map_object (loader=<optimized out>, loader@entry=0x7ffff7ffe2d0, name=name@entry=0x402010 "lib1.so", type=type@entry=2, trace_mode=trace_mode@entry=0, mode=mode@entry=-1879048191, nsid=<optimized out>) at dl-load.c:2253 #3 0x00007ffff7fd63bc in dl_open_worker_begin (a=a@entry=0x7fffffffdcf0) at dl-open.c:534 #4 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdb40, operate=operate@entry=0x7ffff7fd6310 <dl_open_worker_begin>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #5 0x00007ffff7fd5b70 in dl_open_worker (a=a@entry=0x7fffffffdcf0) at dl-open.c:782 #6 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdcd0, operate=operate@entry=0x7ffff7fd5b30 <dl_open_worker>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #7 0x00007ffff7fd5f44 in _dl_open (file=0x402010 "lib1.so", mode=<optimized out>, caller_dlopen=0x40113e <main+24>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:884 #8 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #9 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #10 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #11 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #12 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #13 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #14 0x000000000040113e in main () at main.c:4 (gdb) up #1 0x00007ffff7fd1c76 in _dl_map_object_from_fd (name=name@entry=0x402010 "lib1.so", origname=origname@entry=0x0, fd=-1, fbp=<optimized out>, realname=<optimized out>, loader=loader@entry=0x0, l_type=<optimized out>, mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>) at dl-load.c:1494 1494 _dl_add_to_namespace_list (l, nsid); (gdb) list 1489 #ifdef DL_AFTER_LOAD 1490 DL_AFTER_LOAD (l); 1491 #endif 1492 1493 /* Now that the object is fully initialized add it to the object list. */ 1494 _dl_add_to_namespace_list (l, nsid); 1495 1496 /* Signal that we are going to add new objects. */ 1497 if (r->r_state == RT_CONSISTENT) 1498 { (gdb) continue Continuing. Library 1 loaded successfully! Hardware watchpoint 2: *0x7ffff7ffda08 Old value = 1 New value = 0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 70 LIBC_PROBE (mutex_release, 1, mutex); (gdb) backtrace #0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 #1 0x00007ffff7fd5f91 in _dl_open (file=<optimized out>, mode=<optimized out>, caller_dlopen=0x40113e <main+24>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:933 #2 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #3 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #4 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #5 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #6 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #7 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #8 0x000000000040113e in main () at main.c:4 (gdb) up #1 0x00007ffff7fd5f91 in _dl_open (file=<optimized out>, mode=<optimized out>, caller_dlopen=0x40113e <main+24>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:933 933 __rtld_lock_unlock_recursive (GL(dl_load_lock)); (gdb) list 928 } 929 930 assert (_dl_debug_update (args.nsid)->r_state == RT_CONSISTENT); 931 932 /* Release the lock. */ 933 __rtld_lock_unlock_recursive (GL(dl_load_lock)); 934 935 return args.map; 936 } 937 (gdb) continue Continuing. Hardware watchpoint 2: *0x7ffff7ffda08 Old value = 0 New value = 1 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 130 assert (mutex->__data.__owner == 0); (gdb) backtrace #0 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 #1 0x00007ffff7fd5edb in _dl_open (file=0x402018 "lib2.so", mode=-2147483647, caller_dlopen=0x401152 <main+44>, nsid=-2, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:830 #2 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #3 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #4 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #5 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #6 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #7 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #8 0x0000000000401152 in main () at main.c:5 (gdb) up #1 0x00007ffff7fd5edb in _dl_open (file=0x402018 "lib2.so", mode=-2147483647, caller_dlopen=0x401152 <main+44>, nsid=-2, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:830 830 __rtld_lock_lock_recursive (GL(dl_load_lock)); (gdb) list 825 if ((mode & RTLD_BINDING_MASK) == 0) 826 /* One of the flags must be set. */ 827 _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()")); 828 829 /* Make sure we are alone. */ 830 __rtld_lock_lock_recursive (GL(dl_load_lock)); 831 832 if (__glibc_unlikely (nsid == LM_ID_NEWLM)) 833 { 834 /* Find a new namespace. */ (gdb) continue Continuing. Hardware watchpoint 3: *0x7ffff7ffda30 Old value = 0 New value = 1 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 130 assert (mutex->__data.__owner == 0); (gdb) backtrace #0 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 #1 0x00007ffff7fd5507 in _dl_add_to_namespace_list (new=0x406600, nsid=0) at dl-object.c:33 #2 0x00007ffff7fd1c76 in _dl_map_object_from_fd (name=name@entry=0x402018 "lib2.so", origname=origname@entry=0x0, fd=-1, fbp=<optimized out>, realname=<optimized out>, loader=loader@entry=0x0, l_type=<optimized out>, mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>) at dl-load.c:1494 #3 0x00007ffff7fd2839 in _dl_map_object (loader=<optimized out>, loader@entry=0x7ffff7ffe2d0, name=name@entry=0x402018 "lib2.so", type=type@entry=2, trace_mode=trace_mode@entry=0, mode=mode@entry=-1879048191, nsid=<optimized out>) at dl-load.c:2253 #4 0x00007ffff7fd63bc in dl_open_worker_begin (a=a@entry=0x7fffffffdcf0) at dl-open.c:534 #5 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdb40, operate=operate@entry=0x7ffff7fd6310 <dl_open_worker_begin>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #6 0x00007ffff7fd5b70 in dl_open_worker (a=a@entry=0x7fffffffdcf0) at dl-open.c:782 #7 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdcd0, operate=operate@entry=0x7ffff7fd5b30 <dl_open_worker>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #8 0x00007ffff7fd5f44 in _dl_open (file=0x402018 "lib2.so", mode=<optimized out>, caller_dlopen=0x401152 <main+44>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:884 #9 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #10 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #11 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #12 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #13 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #14 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #15 0x0000000000401152 in main () at main.c:5 (gdb) up #1 0x00007ffff7fd5507 in _dl_add_to_namespace_list (new=0x406600, nsid=0) at dl-object.c:33 33 __rtld_lock_lock_recursive (GL(dl_load_write_lock)); (gdb) list 28 /* Add the new link_map NEW to the end of the namespace list. */ 29 void 30 _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid) 31 { 32 /* We modify the list of loaded objects. */ 33 __rtld_lock_lock_recursive (GL(dl_load_write_lock)); 34 35 if (GL(dl_ns)[nsid]._ns_loaded != NULL) 36 { 37 struct link_map *l = GL(dl_ns)[nsid]._ns_loaded; (gdb) continue Continuing. Hardware watchpoint 3: *0x7ffff7ffda30 Old value = 1 New value = 0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 70 LIBC_PROBE (mutex_release, 1, mutex); (gdb) backtrace #0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 #1 0x00007ffff7fd1c76 in _dl_map_object_from_fd (name=name@entry=0x402018 "lib2.so", origname=origname@entry=0x0, fd=-1, fbp=<optimized out>, realname=<optimized out>, loader=loader@entry=0x0, l_type=<optimized out>, mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>) at dl-load.c:1494 #2 0x00007ffff7fd2839 in _dl_map_object (loader=<optimized out>, loader@entry=0x7ffff7ffe2d0, name=name@entry=0x402018 "lib2.so", type=type@entry=2, trace_mode=trace_mode@entry=0, mode=mode@entry=-1879048191, nsid=<optimized out>) at dl-load.c:2253 #3 0x00007ffff7fd63bc in dl_open_worker_begin (a=a@entry=0x7fffffffdcf0) at dl-open.c:534 #4 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdb40, operate=operate@entry=0x7ffff7fd6310 <dl_open_worker_begin>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #5 0x00007ffff7fd5b70 in dl_open_worker (a=a@entry=0x7fffffffdcf0) at dl-open.c:782 #6 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdcd0, operate=operate@entry=0x7ffff7fd5b30 <dl_open_worker>, args=args@entry=0x7fffffffdcf0) at dl-catch.c:237 #7 0x00007ffff7fd5f44 in _dl_open (file=0x402018 "lib2.so", mode=<optimized out>, caller_dlopen=0x401152 <main+44>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:884 #8 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #9 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #10 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #11 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #12 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #13 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #14 0x0000000000401152 in main () at main.c:5 (gdb) up #1 0x00007ffff7fd1c76 in _dl_map_object_from_fd (name=name@entry=0x402018 "lib2.so", origname=origname@entry=0x0, fd=-1, fbp=<optimized out>, realname=<optimized out>, loader=loader@entry=0x0, l_type=<optimized out>, mode=<optimized out>, stack_endp=<optimized out>, nsid=<optimized out>) at dl-load.c:1494 1494 _dl_add_to_namespace_list (l, nsid); (gdb) list 1489 #ifdef DL_AFTER_LOAD 1490 DL_AFTER_LOAD (l); 1491 #endif 1492 1493 /* Now that the object is fully initialized add it to the object list. */ 1494 _dl_add_to_namespace_list (l, nsid); 1495 1496 /* Signal that we are going to add new objects. */ 1497 if (r->r_state == RT_CONSISTENT) 1498 { (gdb) continue Continuing. Library 2 loaded successfully! Hardware watchpoint 2: *0x7ffff7ffda08 Old value = 1 New value = 0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 70 LIBC_PROBE (mutex_release, 1, mutex); (gdb) backtrace #0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 #1 0x00007ffff7fd5f91 in _dl_open (file=<optimized out>, mode=<optimized out>, caller_dlopen=0x401152 <main+44>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:933 #2 0x00007ffff7e58714 in dlopen_doit (a=a@entry=0x7fffffffdfa0) at dlopen.c:56 #3 0x00007ffff7fcb523 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdee0, operate=0x7ffff7e586b0 <dlopen_doit>, args=0x7fffffffdfa0) at dl-catch.c:237 #4 0x00007ffff7fcb679 in _dl_catch_error (objname=0x7fffffffdf48, errstring=0x7fffffffdf50, mallocedp=0x7fffffffdf47, operate=<optimized out>, args=<optimized out>) at dl-catch.c:256 #5 0x00007ffff7e581f3 in _dlerror_run (operate=operate@entry=0x7ffff7e586b0 <dlopen_doit>, args=args@entry=0x7fffffffdfa0) at dlerror.c:138 #6 0x00007ffff7e587cf in dlopen_implementation (dl_caller=<optimized out>, mode=<optimized out>, file=<optimized out>) at dlopen.c:71 #7 ___dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:81 #8 0x0000000000401152 in main () at main.c:5 (gdb) up #1 0x00007ffff7fd5f91 in _dl_open (file=<optimized out>, mode=<optimized out>, caller_dlopen=0x401152 <main+44>, nsid=<optimized out>, argc=1, argv=0x7fffffffe118, env=0x7fffffffe128) at dl-open.c:933 933 __rtld_lock_unlock_recursive (GL(dl_load_lock)); (gdb) list 928 } 929 930 assert (_dl_debug_update (args.nsid)->r_state == RT_CONSISTENT); 931 932 /* Release the lock. */ 933 __rtld_lock_unlock_recursive (GL(dl_load_lock)); 934 935 return args.map; 936 } 937 (gdb) continue Continuing. Hardware watchpoint 2: *0x7ffff7ffda08 Old value = 0 New value = 1 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 130 assert (mutex->__data.__owner == 0); (gdb) backtrace #0 ___pthread_mutex_lock (mutex=<optimized out>) at pthread_mutex_lock.c:130 #1 0x00007ffff7fced65 in _dl_fini () at dl-fini.c:34 #2 0x00007ffff7e101e6 in __run_exit_handlers (status=0, listp=<optimized out>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at exit.c:111 #3 0x00007ffff7e1032e in __GI_exit (status=<optimized out>) at exit.c:141 #4 0x00007ffff7df7b91 in __libc_start_call_main (main=main@entry=0x401126 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffe118) at ../sysdeps/nptl/libc_start_call_main.h:74 #5 0x00007ffff7df7c4b in __libc_start_main_impl (main=0x401126 <main>, argc=1, argv=0x7fffffffe118, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe108) at ../csu/libc-start.c:360 #6 0x0000000000401065 in _start () (gdb) up #1 0x00007ffff7fced65 in _dl_fini () at dl-fini.c:34 34 __rtld_lock_lock_recursive (GL(dl_load_lock)); (gdb) list 29 on new (relocation) dependencies. None of the objects are 30 unmapped, so applications can deal with this if their DSOs remain 31 in a consistent state after destructors have run. */ 32 33 /* Protect against concurrent loads and unloads. */ 34 __rtld_lock_lock_recursive (GL(dl_load_lock)); 35 36 /* Ignore objects which are opened during shutdown. */ 37 struct link_map *local_init_called_list = _dl_init_called_list; 38 (gdb) continue Continuing. Hardware watchpoint 2: *0x7ffff7ffda08 Old value = 1 New value = 0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 70 LIBC_PROBE (mutex_release, 1, mutex); (gdb) backtrace #0 __GI___pthread_mutex_unlock_usercnt (mutex=<optimized out>, decr=<optimized out>) at pthread_mutex_unlock.c:70 #1 0x00007ffff7fced9b in _dl_fini () at dl-fini.c:47 #2 0x00007ffff7e101e6 in __run_exit_handlers (status=0, listp=<optimized out>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at exit.c:111 #3 0x00007ffff7e1032e in __GI_exit (status=<optimized out>) at exit.c:141 #4 0x00007ffff7df7b91 in __libc_start_call_main (main=main@entry=0x401126 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffe118) at ../sysdeps/nptl/libc_start_call_main.h:74 #5 0x00007ffff7df7c4b in __libc_start_main_impl (main=0x401126 <main>, argc=1, argv=0x7fffffffe118, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe108) at ../csu/libc-start.c:360 #6 0x0000000000401065 in _start () (gdb) up #1 0x00007ffff7fced9b in _dl_fini () at dl-fini.c:47 47 __rtld_lock_unlock_recursive (GL(dl_load_lock)); (gdb) list 42 are not dlclose()ed from underneath us. */ 43 ++l->l_direct_opencount; 44 45 /* After this point, everything linked from local_init_called_list 46 cannot be unloaded because of the reference counter update. */ 47 __rtld_lock_unlock_recursive (GL(dl_load_lock)); 48 49 /* Perform two passes: One for non-audit modules, one for audit 50 modules. This way, audit modules receive unload notifications 51 for non-audit objects, and the destructors for audit modules (gdb) continue Continuing. [Inferior 1 (process 20248) exited normally] (gdb) exit