Bug 134391 - [libc] dladdr(3) does effectively not work on main program.
Summary: [libc] dladdr(3) does effectively not work on main program.
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 8.0-CURRENT
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-09 16:20 UTC by Poul-Henning Kamp
Modified: 2018-01-03 05:13 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Poul-Henning Kamp 2009-05-09 16:20:01 UTC
	The dladdr(3) function does not return anything remotely
	useful for the main program, because it only examines the
	dynamic symbol table.

	The most common use for this function, is to construct a
	backtrace.

	ports/devel/libexecinfo is an example of this use.

Fix: 

Linking the program with `-Wl,--export-dynamic fills the
	dynamic symbol table with all non-static symbols, which is
	a bit better, but still useless because all static functions
	are invisible.

	A simple correct solution escapes me, since we might not
	even be able to open the original binary again to read the
	DWARF symbol table.

	One, quasi-hackish way to solve this, is to notice that the
	program references dladdr(3) in the first place, and have rtld(1)
	load the DWARF-symbol table(s) also.
How-To-Repeat: 	#include <stdio.h>
	#include <dlfcn.h>

	extern void foo(const void *a);
	static void bar(void *a);

	int
	main(int argc, char **argv)
	{

		(void)argc;
		(void)argv;

		foo((const char *)bar + 4);
		return (0);
	}

	void foo(const void *a)
	{
		Dl_info info;
		int i;

		i = dladdr(a, &info);

		printf("i = %d (%p)\n", i, a);
		printf("fn = %s\n", info.dli_fname);
		printf("fb = %p\n", info.dli_fbase);
		printf("sn = %s\n", info.dli_sname);
		printf("sb = %p\n", info.dli_saddr);
	}

	static void bar(void *b)
	{
		printf("%p\n", b);
	}
Comment 1 csdavec 2009-09-14 02:06:51 UTC
I tried to submit something related to this bug a while ago, but send- 
pr ate it...

dlsym() on FreeBSD is similarly broken.  It's worth noting that nm is  
capable of listing all of the symbols in an executable or shared  
object, even when compiled without debug info, and so they must exist  
in the binary, they are just not being added to the symbol table that  
is exposed via these functions.  The behaviour of dladdr() is  
particularly bad because, unlike dlsym() it doesn't return failure, it  
simply returns the name of a different symbol from the same library.

David
Comment 2 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:00:02 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped