Summary: | Debugger hangs on a shared library in memory-mapped file. | ||
---|---|---|---|
Product: | gdb | Reporter: | Marcin Copik <mcopik> |
Component: | shlibs | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | NEW --- | ||
Severity: | normal | CC: | asaffisher.dev, ppluzhnikov |
Priority: | P2 | ||
Version: | 12.1 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: | 2024-08-27 00:00:00 |
Description
Marcin Copik
2022-09-19 13:03:04 UTC
The reason this happens is because /proc/self is different between inferior and GDB. I proposed a patch to fix it today. I just hit this as well. Trivial repro with current trunk: --- foo.c --- #include <assert.h> int fn (int x) { assert (x > 0); return x + 1; } --- main1.c --- #include <dlfcn.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> int main() { int fd = open("./foo.so", O_RDONLY); char path[1024]; sprintf(path, "/proc/self/fd/%d", fd); fprintf (stderr, "Before dlopen %s\n", path); void *h = dlopen(path, RTLD_LOCAL|RTLD_LAZY); int (*fn)(int) = dlsym(h, "fn"); fprintf (stderr, "Before call to fn\n"); return fn(0); } gcc -g -fPIC -shared -o foo.so foo.c && gcc -g main1.c -ldl && ./a.out Before dlopen /proc/self/fd/3 Before call to fn a.out: foo.c:5: fn: Assertion `x > 0' failed. Aborted --- Everything is as expected up to this point gdb/gdb -q -ex run ./a.out Reading symbols from ./a.out... Starting program: /tmp/memfd/a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Before dlopen /proc/self/fd/3 ... GDB hangs forever trying to read from some pipe, and is blocking all signals requiring that I pkill -9 from another terminal. strace -p $(pgrep gdb) strace: Process 3885955 attached read(16, ^Cstrace: Process 3885955 detached <detached ...> ls -l /proc/3885955/fd/16 lr-x------ 1 ppluzhnikov primarygroup 64 Aug 27 03:43 /proc/3885955/fd/16 -> 'pipe:[95221642]' --- It's also easy to make GDB not hang, but simply fail to load symbols: --- main.c --- #include <assert.h> #include <dlfcn.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> int main() { int fd = open("./foo.so", O_RDONLY); char path[1024]; assert(dup2(fd, 133) != -1); sprintf(path, "/proc/self/fd/%d", 133); void *h = dlopen(path, RTLD_LOCAL|RTLD_LAZY); int (*fn)(int) = dlsym(h, "fn"); return fn(0); } gcc -g main.c -ldl && gdb/gdb -q -ex run ./a.out Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". warning: Could not load shared library symbols for /proc/self/fd/133. Do you need "set solib-search-path" or "set sysroot"? a.out: foo.c:5: fn: Assertion `x > 0' failed. Program received signal SIGABRT, Aborted. 0x00007ffff7e520ec in ?? () from /lib/x86_64-linux-gnu/libc.so.6 (gdb) bt #0 0x00007ffff7e520ec in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007ffff7e04102 in raise () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00007ffff7ded4f2 in abort () from /lib/x86_64-linux-gnu/libc.so.6 #3 0x00007ffff7ded415 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #4 0x00007ffff7dfcd32 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6 #5 0x00007ffff7fbf142 in ?? () #6 0x00007fffffffd868 in ?? () #7 0x00000000ffffd868 in ?? () #8 0x00007fffffffd750 in ?? () #9 0x000055555555524c in main () at main.c:18 Backtrace stopped: frame did not save the PC |