From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id D0D82385E036; Thu, 19 Aug 2021 12:57:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D0D82385E036 From: "mail at milianw dot de" To: glibc-bugs@sourceware.org Subject: [Bug dynamic-link/28248] New: is there a way to LD_PRELOAD library before other dynamic libraries? Date: Thu, 19 Aug 2021 12:57:15 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: dynamic-link X-Bugzilla-Version: 2.33 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: mail at milianw dot de 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: glibc-bugs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-bugs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Aug 2021 12:57:15 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D28248 Bug ID: 28248 Summary: is there a way to LD_PRELOAD library before other dynamic libraries? Product: glibc Version: 2.33 Status: UNCONFIRMED Severity: normal Priority: P2 Component: dynamic-link Assignee: unassigned at sourceware dot org Reporter: mail at milianw dot de Target Milestone: --- Hey there, I hope this is the right place to report this. I'm the author of heaptrack, which relies on LD_PRELOAD to intercept calls = to malloc and friends. Only recently, I realized my assumption about LD_PRELOAD behavior is wrong - I thought it would be loaded _before_ all other dynamic libraries, but that isn't the case. See documentation over at https://www.man7.org/linux/man-pages/man8/ld.so.8.html: > LD_PRELOAD > A list of additional, user-specified, ELF shared objects > to be loaded before all others. But as can be seen by the below, the preloaded library will be loaded after other dependencies of the binary we are executing, i.e.: ``` $ cat preload_dump.c: #include void __attribute__ ((constructor)) init(void) { fprintf(stderr, "preload init!\n");=20 } void __attribute__ ((destructor)) cleanup(void) { fprintf(stderr, "preload cleanup!\n");=20 } $ gcc -shared -fPIC -o preload_dump.so preload_dump.c ``` ``` $ readelf -d $(which bash) | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libtinfo.so.5] 0x0000000000000001 (NEEDED) Shared library: [libdl.so.2] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] ``` ``` LD_DEBUG=3Dfiles LD_PRELOAD=3D$PWD/preload_dump.so bash --version 83: 83: file=3D/opt/craft/preload_dump.so [0]; needed by bash [0] 83: file=3D/opt/craft/preload_dump.so [0]; generating link map 83: dynamic: 0x00007fb5dbbd3dd0 base: 0x00007fb5dbbd2000 s= ize: 0x0000000000002029 83: entry: 0x00007fb5dbbd2000 phdr: 0x00007fb5dbbd2040 ph= num: 8 83: 83: 83: file=3Dlibtinfo.so.5 [0]; needed by bash [0] 83: file=3Dlibtinfo.so.5 [0]; generating link map 83: dynamic: 0x00007fb5db9b3d10 base: 0x00007fb5db78b000 s= ize: 0x0000000000229f00 83: entry: 0x00007fb5db797e40 phdr: 0x00007fb5db78b040 ph= num: 7 83: 83: 83: file=3Dlibdl.so.2 [0]; needed by bash [0] 83: file=3Dlibdl.so.2 [0]; generating link map 83: dynamic: 0x00007fb5db789d68 base: 0x00007fb5db587000 s= ize: 0x0000000000203130 83: entry: 0x00007fb5db587e50 phdr: 0x00007fb5db587040 ph= num: 7 83: 83: 83: file=3Dlibc.so.6 [0]; needed by bash [0] 83: file=3Dlibc.so.6 [0]; generating link map 83: dynamic: 0x00007fb5db57fb60 base: 0x00007fb5db1b9000 s= ize: 0x00000000003cd200 83: entry: 0x00007fb5db1db660 phdr: 0x00007fb5db1b9040 ph= num: 10 83: 83: 83: calling init: /lib64/libc.so.6 83: 83: 83: calling init: /lib64/libdl.so.2 83: 83: 83: calling init: /lib64/libtinfo.so.5 83: 83: 83: calling init: /opt/craft/preload_dump.so 83: preload init! 83: 83: initialize program: bash 83: 83: 83: transferring control: bash 83: GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. 83: 83: calling fini: bash [0] 83: 83: 83: calling fini: /opt/craft/preload_dump.so [0] 83: preload cleanup! 83: 83: calling fini: /lib64/libtinfo.so.5 [0] 83: 83: 83: calling fini: /lib64/libdl.so.2 [0] 83: ``` Note how the needed libs of the binary are loaded before the LD_PRELOAD'ed library. And note how that then obviously means the fini call for preload_d= ump happens before e.g. libtinfo.so's fini call. Is there a way for me to inject a library into the dynamic loader in such a way, that it is loaded first before any other dependency of the executable? In my case, the main reason why I want the above behavior is actually to enforce proper shutdown semantics: As a memory profiler, I have an atexit handler which is calling `__libc_freeres` and `__gnu_cxx::__freeres`, simil= ar to and inspired by valgrind. But because my preloaded library is loaded *af= ter* the other libraries, its cleanup code will run *before* that of other libraries. Combined, this can lead to crashes when another fini of some other library calls code that depends on resources that get freed by the freeres calls. so, tl;dr; - is there a way to force something like LD_PRELOAD, but load the library before all others? - is there an alternative way to force an atexit handler call at the very e= nd of the shutdown semantics, after all other libraries got unloaded? Many thanks! --=20 You are receiving this mail because: You are on the CC list for the bug.=