Instead of LD_PRELOAD, you can use GDB and thread-specific breakpoints with conditions: $ gdb /usr/bin/python2 gdb$ r Starting program: /usr/bin/python2 [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Python 2.7.18rc1 (default, Apr 7 2020, 12:05:55) [GCC 9.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> Program received signal SIGINT, Interrupt. gdb$ break open64 thread 1 if $_memeq($rdi, "/tmp", 4) Breakpoint 1 at 0x7ffff7db3a00: open64. (2 locations) gdb$ c Continuing. >>> f = open('/etc/something') Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno 2] No such file or directory: '/etc/something' >>> f = open('/tmp/test') Breakpoint 1, __libc_open64 (file=0x5555559c0a00 "/tmp/test", oflag=0x0) at ../sysdeps/unix/sysv/linux/open64.c:37 37 ../sysdeps/unix/sysv/linux/open64.c: No such file or directory. gdb$
Thanks for the tip, though it's not quite what I need. Normally when GDB takes control all threads are stopped, but I only want to stop the thread calling open(). Fortunately GDB supports "non-stop mode" that only pauses the trapped thread. Unfortunately it appears to be broken in my version of GDB (8.2.1). I used the non-thread-specific version of your breakpoint, enabled non-stop mode, then ran my aopen.py. GDB aborted as soon as the second thread hit the breakpoint, with, "A problem internal to GDB has been detected, further debugging may prove unreliable." gdb$ break open64 if $_memeq($rdi, "/tmp", 4) gdb$ set non-stop on gdb$ r (GDB abort) Cutting down to a single open() thread didn't help. The heartbeat kept going while the open() thread was trapped, but I couldn't interact with it. GDB would only complain, "Cannot execute this command while the selected thread is running." As far as I can tell this is another GDB bug. In theory this means there *is* a solution using ptrace, though I'd have to do more research. In any case, it's going to be more complicated and less convenient than LD_PRELOAD.