[patch] Improve ELF symbols preference (global > weak)
Jan Kratochvil
jan.kratochvil at redhat.com
Mon Oct 8 18:53:57 UTC 2012
Hi,
debuggers like GDB display symbol name 'raise' but elfutils have been
displaying 'gsignal' instead.
$ mv core.`ulimit -c unlimited;./backtrace-child --gencore --run` ./backtrace-child.core
$ ./backtrace ./backtrace-child{,.core}
[...]
TID 9971:
FAIL: # 0 0x7fe4ec6bd285 gsignal
->
PASS: # 0 0x7fe4ec6bd285 raise
# 1 0x7fe4ec6beb9b - 1 abort
# 2 0x7fe4ece7fa75 - 1 sigusr2
# 3 0x7fe4ece7fbd0 - 1 stdarg
# 4 0x7fe4ece7fbee - 1 backtracegen
# 5 0x7fe4ece7fc05 - 1 start
# 6 0x7fe4eca46d90 - 1 start_thread
# 7 0x7fe4ec77819d - 1 clone
This is because:
readelf -Ws /lib64/libc.so.6
Symbol table '.symtab' contains 7720 entries:
6650: 000000326ca36250 100 FUNC WEAK DEFAULT 12 gsignal
6675: 000000326ca36250 100 FUNC GLOBAL DEFAULT 12 raise
I believe when there are both such symbols STB_GLOBAL should be preferred over
STB_WEAK (which should be preferred over STB_LOCAL).
Testcase for this patch is the whole testsuite of:
[API RFC] unwinder
https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/002618.html
There is check_gsignal for it in tests/run-backtrace.sh. As there are shipped
non-x86* core files and self-contained -static files with ELF symbols the test
does not depend on host system. Still maybe some more thorough testcase for
symbols priorities could be there, currently there is not.
Thanks,
Jan
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index 4e0646e..7ea6289 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -133,13 +143,13 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
}
}
/* When the beginning of its range is no closer,
- the end of its range might be. But do not
- replace a global symbol with a local! */
+ the end of its range might be. Prefer STB_GLOBAL over
+ STB_WEAK and STB_WEAK over STB_LOCAL. */
else if (sym.st_size != 0
&& closest_sym->st_value == sym.st_value
- && closest_sym->st_size > sym.st_size
- && (GELF_ST_BIND (closest_sym->st_info)
- <= GELF_ST_BIND (sym.st_info)))
+ && closest_sym->st_size >= sym.st_size
+ && (GELF_ST_BIND (sym.st_info) == STB_GLOBAL
+ || GELF_ST_BIND (closest_sym->st_info) == STB_LOCAL))
{
*closest_sym = sym;
closest_shndx = shndx;
More information about the elfutils-devel
mailing list