public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "mail at milianw dot de" <sourceware-bugzilla@sourceware.org>
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 [thread overview]
Message-ID: <bug-28248-131@http.sourceware.org/bugzilla/> (raw)
https://sourceware.org/bugzilla/show_bug.cgi?id=28248
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 <stdio.h>
void __attribute__ ((constructor)) init(void)
{
fprintf(stderr, "preload init!\n");
}
void __attribute__ ((destructor)) cleanup(void)
{
fprintf(stderr, "preload cleanup!\n");
}
$ 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=files LD_PRELOAD=$PWD/preload_dump.so bash --version
83:
83: file=/opt/craft/preload_dump.so [0]; needed by bash [0]
83: file=/opt/craft/preload_dump.so [0]; generating link map
83: dynamic: 0x00007fb5dbbd3dd0 base: 0x00007fb5dbbd2000 size:
0x0000000000002029
83: entry: 0x00007fb5dbbd2000 phdr: 0x00007fb5dbbd2040 phnum:
8
83:
83:
83: file=libtinfo.so.5 [0]; needed by bash [0]
83: file=libtinfo.so.5 [0]; generating link map
83: dynamic: 0x00007fb5db9b3d10 base: 0x00007fb5db78b000 size:
0x0000000000229f00
83: entry: 0x00007fb5db797e40 phdr: 0x00007fb5db78b040 phnum:
7
83:
83:
83: file=libdl.so.2 [0]; needed by bash [0]
83: file=libdl.so.2 [0]; generating link map
83: dynamic: 0x00007fb5db789d68 base: 0x00007fb5db587000 size:
0x0000000000203130
83: entry: 0x00007fb5db587e50 phdr: 0x00007fb5db587040 phnum:
7
83:
83:
83: file=libc.so.6 [0]; needed by bash [0]
83: file=libc.so.6 [0]; generating link map
83: dynamic: 0x00007fb5db57fb60 base: 0x00007fb5db1b9000 size:
0x00000000003cd200
83: entry: 0x00007fb5db1db660 phdr: 0x00007fb5db1b9040 phnum:
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 <http://gnu.org/licenses/gpl.html>
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_dump
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`, similar
to and inspired by valgrind. But because my preloaded library is loaded *after*
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 end
of the shutdown semantics, after all other libraries got unloaded?
Many thanks!
--
You are receiving this mail because:
You are on the CC list for the bug.
next reply other threads:[~2021-08-19 12:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-19 12:57 mail at milianw dot de [this message]
2021-08-31 17:41 ` [Bug dynamic-link/28248] " amonakov at gmail dot com
2021-09-06 8:19 ` mail at milianw dot de
2021-09-06 8:32 ` fweimer at redhat dot com
2021-09-09 8:35 ` mail at milianw dot de
2021-09-09 8:54 ` mail at milianw dot de
2022-08-29 9:53 ` fweimer at redhat dot com
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bug-28248-131@http.sourceware.org/bugzilla/ \
--to=sourceware-bugzilla@sourceware.org \
--cc=glibc-bugs@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).