initialization problem w/ thread-specific .tbss data on i386
Konstantin Belousov
kostikbel at gmail.com
Tue May 8 08:14:30 UTC 2018
On Mon, May 07, 2018 at 05:27:03PM -0400, Phil Shafer wrote:
> I have a problem reported with libxo-based applications running
> under FreeBSD-11-stable on i386 boxes that I think is related
> to rtld:
>
> When I breakpoint on main() and dump the contents of my uninitialized
> thread-specific variable, it has not been initialized to zeroes.
>
> I don't see this problem on 64-bit systems, only on i386 ones.
>
> When I look at the rtld code, it appears to memset the .tbss to
> zero (/usr/src/libexec/rtld-elf/rtld.c:allocate_tls) in the
> non-arch-specific code so the arch shouldn't matter, but something
> is not working right.
>
> So I'm looking for a helpful clue, such as how to debug rtld to see
> why this isn't being zeroed. I thought I'd use:
>
> gdb /libexec/ld-elf.so.1
> run /usr/bin/uptime
>
> for this doesn't work for me (SEGV with a callstack that doesn't
> make sense).
You need to supply argv[0]. Read ld-elf.so.1(1), it has the whole
section about direct execution mode.
>
> For this instance, the work around is to initialize the contents
> of xo_default_handle to zero so it's not in the .tbss, but I'd like
> to understand what's failing. In truth, I just have a hard time
> blaming rtld, even though this is issue is an obscure intersection
> of weird things (.tbbs on i386). Perhaps it's something wrong with
> how the library is built or similar. But given that it's not zeroed
> when main() get control, something's clearly broken.
>
> Details follow:
>
> I declare my variable as:
>
> #define THREAD_LOCAL(_x) __thread _x
> ...
> static THREAD_LOCAL(xo_handle_t) xo_default_handle;
>
> To help debug this issue, I made the following change to the sources
> to help with gdb's inability to show thread-local variables ("Cannot
> find thread-local variables on this target"):
>
> --- contrib/libxo/libxo/libxo.c.save 2018-05-04 17:26:29.079500000 -0400
> +++ contrib/libxo/libxo/libxo.c 2018-05-04 17:28:06.570875000 -0400
> @@ -8349,3 +8349,11 @@
> xop->xo_style = XO_STYLE_ENCODER;
> xop->xo_encoder = encoder;
> }
> +
> +void xo_print_handle (void);
> +void
> +xo_print_handle (void)
> +{
> + fprintf(stderr, "xo_default_handle: %p %d\n",
> + &xo_default_handle, sizeof(xo_handle_t));
> +}
>
> When I run the failing command (uptime) under gdb and breakpoint
> on main, my thread-local variable is not set to zeroes:
>
> % gdb uptime
> GNU gdb 6.1.1 [FreeBSD]
> ...
> This GDB was configured as "i386-marcel-freebsd"...
> (gdb) b main
> Breakpoint 1 at 0x8049be5: file /usr/src/usr.bin/w/w.c, line 145.
> (gdb) run
> Starting program: /usr/home/phil/work/lib/uptime
>
> Breakpoint 1, main (argc=1, argv=0xbfbfe60c) at /usr/src/usr.bin/w/w.c:145
> 145 (void)setlocale(LC_ALL, "");
> Current language: auto; currently minimal
> (gdb) call xo_print_handle()
> xo_default_handle: 0x2806aff0 328
> $1 = 34
> (gdb) x/82x 0x2806aff0
> 0x2806aff0: 0x00000000 0x00000000 0x00000000 0x280601ef
> 0x2806b000: 0x2806b010 0x2806a200 0x00000001 0x280601ef
> 0x2806b010: 0x2806b020 0x2806a400 0x0000005d 0x280601ef
> 0x2806b020: 0x2806b030 0x2806a600 0x000000a1 0x280601ef
> 0x2806b030: 0x2806b040 0x2806a800 0x00000147 0x280601ef
> 0x2806b040: 0x00000000 0x2806aa00 0x00000164 0x280601ef
> 0x2806b050: 0x2806c000 0x00000000 0x28065e70 0x280601ef
> 0x2806b060: 0x2806b070 0x2806ac00 0x00000421 0x280601ef
> 0x2806b070: 0x00000000 0x2806aa00 0x0000042d 0x280601ef
> 0x2806b080: 0x00000000 0x2806aa00 0x000001ff 0x280601ef
> 0x2806b090: 0x2806b0a0 0x2806a800 0x00000976 0x280601ef
> 0x2806b0a0: 0x00000000 0x2806aa00 0x00000983 0x280601ef
> 0x2806b0b0: 0x00000000 0x2806aa00 0x00000a18 0x280601ef
> 0x2806b0c0: 0x00000000 0x2806aa00 0x00000571 0x280601ef
> 0x2806b0d0: 0x2806b0e0 0x2806a000 0x00000000 0x280601ef
> 0x2806b0e0: 0x2806b0f0 0x2806a200 0x00000000 0x280601ef
> 0x2806b0f0: 0x2806b100 0x2806a400 0x00000000 0x280601ef
> 0x2806b100: 0x2806b110 0x2806a600 0x00000000 0x280601ef
> 0x2806b110: 0x2806b120 0x2806a800 0x00000000 0x280601ef
> 0x2806b120: 0x2806b130 0x2806aa00 0x00000000 0x280601ef
> 0x2806b130: 0x00000000 0x2806ac00
> (gdb)
>
> objdump shows the lib does have a .tbbs:
>
> 14 .tbss 00000658 000181f8 000181f8 000171f8 2**3
> ALLOC, THREAD_LOCAL
Can you build the library and binary with clang 5 or even gcc, and
see how is it end up ?
Also, try to link in libpthread.
More information about the freebsd-arch
mailing list