This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: NPTL libthread_db changes for static debugging


currently GDB debugging fails for threaded binaries linked as `-static':
	echo -e '#include <pthread.h>\nint main (void) { long p = pthread_create ((void *) 1, NULL, (void *) 1, NULL); return p; }' >nptl_s.c; gcc -o nptl_s nptl_s.c -Wall -ggdb2 -static -pthread -lpthread; gdb -ex start ./nptl_s
	Starting program: .../nptl_s
	[Thread debugging using libthread_db enabled]
	find_new_threads_callback: cannot get thread info: generic error

GDB (nptl_db) has feeling the threading is turned on as `nptl_version' symbol
already exists (as if `' would get loaded) due to `-static'.
That time still the %fs/%gs (or ia64 %r13) register has value 0.
Therefore nptl_db tries to read `struct pthread' from address 0 and fails.

Daniel Jacobowitz proposed (unaccepted) patches for it before:

I can confirm the Roland McGrath's patch is incompatible (at least) with ia64.

Daniel Jacobowitz's patch depends on that the arbitrary (inherited across
exec(2)) values of the TLS register points to unreadable memory or to a memory
containing non-matching data.

Wouldn't it be most clean to set the TLS (all?) register(s) by the Linux kernel
on exec(2) to zero even on the non-x86 platforms?


On Fri, 03 Mar 2006 15:42:39 +0100, Daniel Jacobowitz wrote:
> On Fri, Mar 03, 2006 at 03:43:47AM -0800, Roland McGrath wrote:
> > I don't really like that fake creation event.  It's not really right.
> > 
> > I have had this patch sitting in my tree for, well, I guess about a year
> > and half.  I don't recall whether static pthreads was what this was about,
> > but I can't off hand see what else it would have been.  This makes
> > td_ta_map_lwp2thr, and thereby td_ta_thr_iter, fail with TD_NOTHR before
> > the thread register is set up.  That should prevent the confused results
> > you mentioned.  
> > 
> > This doesn't stop for the debugger as soon as things are initialized.  But
> > I don't really see the need for that.  You can try map_lwp2thr again the
> > next time the process stops for whatever reason.  You don't really need to
> > know it until first real thread creation event.
> > 
> > What do you think?
> It assumes the uninitialized value is zero.  Is that really going to
> cut it?  It works for i686 and x86_64, but most other platforms don't
> flush TLS state on exec - no point in wasting the kernel cycles
> when they don't affect something as touchy as segment registers.
> I had a previous draft of the GDB changes where I simply ignored errors
> from td_ta_thr_iter and td_thr_get_info.  It works well enough on i686
> and x86_64, but while I haven't tested it anywhere else, I'm pretty
> sure it won't work on MIPS, SH, ARM, or IA-64.  After that I stopped
> looking.
> I just verified IA-64: immediately after exec r13 contains the previous
> executable's TLS value.
> So, it's nicer, but it doesn't work.
> Another potential problem is that there's a window between the
> initialization of TLS and the initialization of the first struct
> pthread; at that point libthread_db will try to read things like the
> LWP ID from the struct pthread even though they aren't initialized
> until later in __pthread_initialize_minimal.  I can probably get
> that to be a problem even in dynamic executables.  Not sure.
> -- 
> Daniel Jacobowitz
> CodeSourcery

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]