diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2011-09-03 11:41:00 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2011-09-03 11:41:00 +0000 |
commit | cce0f33cda82c82c95dfc658f12d53f0fe9db6df (patch) | |
tree | 9650086a654d88a064f39a4ebec93a63964b0db3 | |
parent | 2419d7f93bbf0abcfc2a2aab17dff394bef49fce (diff) | |
download | src-cce0f33cda82c82c95dfc658f12d53f0fe9db6df.tar.gz src-cce0f33cda82c82c95dfc658f12d53f0fe9db6df.zip |
When libexec/rtld-elf/rtld.c is compiled with clang, the r_debug_state()
function (a hook necessary for gdb support), is inlined, but since the
function contains no code, no calls to it are generated. When gdb is
debugging a dynamically linked program, this causes backtraces to be
corrupted.
Fix it by marking the function __noinline, and inserting an empty asm
statement, that pretends to clobber memory. This forces the compiler to
emit calls to r_debug_state() throughout rtld.c.
Approved by: re (kib)
Notes
Notes:
svn path=/head/; revision=225366
-rw-r--r-- | libexec/rtld-elf/rtld.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 0f5aabae734a..874f4bc61ffd 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -144,7 +144,7 @@ static void ld_utrace_log(int, void *, void *, size_t, int, const char *); static void rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info); -void r_debug_state(struct r_debug *, struct link_map *); +void r_debug_state(struct r_debug *, struct link_map *) __noinline; /* * Data declarations. @@ -2782,6 +2782,14 @@ linkmap_delete(Obj_Entry *obj) void r_debug_state(struct r_debug* rd, struct link_map *m) { + /* + * The following is a hack to force the compiler to emit calls to + * this function, even when optimizing. If the function is empty, + * the compiler is not obliged to emit any code for calls to it, + * even when marked __noinline. However, gdb depends on those + * calls being made. + */ + __asm __volatile("" : : : "memory"); } /* |