Re: [RFC PATCH 0/3] Pretty-printing for errno

Pedro Alves
2017-09-05T22:32:25Z

On 09/05/2017 10:15 PM, Zack Weinberg wrote:
> On Mon, Sep 4, 2017 at 5:25 PM, Pedro Alves <palves@redhat.com> wrote:
>>
>> FYI, this is now all in gdb master. I believe all the gdb issues
>> uncovered by the errno printer have been addressed. Let me know
>> if you're aware of something still not working properly.
>
> I'm sorry I never got around to experimenting with your patches before now.

Really no worries.

> With gdb master as of earlier today, and my patched glibc that tries
> to pretty-print errno, I can confirm that nearly everything works as
> desired. `p (error_t) 0` invokes the pretty-printer, and when
> preprocessor macro bodies are available to the debugger (-ggdb3) so
> does `p errno`. Unfortunately I am still getting this error message
> when I try to print the underlying thread-local errno variable (which
> is what `p errno` does if macro bodies are not available):
>
> Cannot find thread-local storage for process 4367, executable file
> /home/zack/projects/glibc/glibc-build/stdlib/test-errno-printer:
> Cannot find thread-local variables on this target
>
> I don't understand why thread-local variables are inaccessible on my
> perfectly ordinary x86_64-unknown-linux-gnu workstation (the base OS
> is Debian 'stretch'). Do you have any idea what might be wrong?

I assume your test program isn't actually linked with -pthread?

When you do "print errno" in this situation, because there's no
"#define errno ..." in sight, gdb ends up finding the real "errno" symbol,
which, even though the program isn't threaded, is a TLS symbol, and as such has
a DWARF location expression describing its location as an offset into the
thread-local block for the current thread. GDB needs to resolve that address, and
for threaded programs that is normally done with assistance from libthread_db.so.
The problem is then that libthread_db.so only works with programs that
link with libpthread.so, and if your test program is actually non-threaded,
it doesn't link with libpthread.so, So without libthread_db.so's assistance,
gdb cannot "find [the address of] thread-local variables on this target". The
error message is coming from generic GDB "get address of tls var" code several
layers above GNU/Linux-specific libthread_db.so-interaction code, but still
it could probably be made clearer, maybe by adding "the address of".

A workaround specifically for errno, and only for live-process debugging [*]
is the "macro define" trick I had suggested before:

(gdb) macro define errno (*__errno_location ())

After that, "p errno" ends up calling __errno_location just
like when you compile the test program with -g3.

[*] doesn't work with core file / postmortem debugging.

I don't know whether GDB could be able to resolve the location
of the errno variable for the main thread (for single-threaded
programs):

- without libthread_db.so assistance and
- without baking in awareness of glibc internal data structures

If there is I'd absolutely love to learn about it.

Thanks,
Pedro Alves