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

Pedro Alves
2017-06-30T18:11:57Z

On 06/30/2017 06:27 PM, Zack Weinberg wrote:

> Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols
> from /usr/lib/debug/.build-id/cc/80584889db7a969292959a46c718a2b1500702.debug...done.
> done.
> (gdb) ptype __errno_location
> type = int ()
> (gdb) p __errno_location
> $1 = {<text variable, no debug info>} 0x20590 <__GI___errno_location>
>
> ... a suspicion occurs...
>
> (gdb) ptype __GI___errno_location
> type = int *(void)
> (gdb) p __GI___errno_location
> $2 = {int *(void)} 0x20590 <__GI___errno_location>
>
> ... so I guess this is a problem with the __GI_ indirection, which
> *may* be a thing we can resolve on our end. I don't fully understand
> that stuff.

OK, thanks, that's clear. I don't know much about __GI_ indirection
either. Redefining errno to call the __GI_ version would probably
be too easy. :-)

> Still, It Would Be Niceâ„¢ if you _didn't_ have to have the debug
> symbols for libc.so installed for this to work. Probably a lot of
> people think you only need those if you are debugging libc itself.

I guess that that could also be seen as a packaging issue. May
be it'd be possible to (always) have some kind of minimal debug
info available for libc, with only the definitions of public API
functions, describing their prototypes, but not their internals?
See:

https://fedoraproject.org/wiki/Features/MiniDebugInfo

>
>> The next problem is that without debug info for __errno_location,
>> gdb has no clue of its prototype, only that its a function, and so
>> it assumes that it has type "int()", i.e., that it returns int,
>> while in reality it returns int * / __error_t *. (Falling back
>> to assuming "int" is IMO not the best idea, but I don't know
>> the history behind it.)
>
> Probably because that's the pre-C89 legacy default function signature?

Yes, most likely.

>> One dirty way around it would be for the printer to
>> re-define the errno macro (using to cast __errno_location to
>> the correct type before calling it, I guess:
>>
>> (gdb) macro define errno *(*(__error_t *(*) (void)) __errno_location) ()
>>
>> That's make "errno" available when you compile with levels
>> lower than -g3, too.
>
> Hmm. How would one do that from inside Python?

There's no direct Python API, I believe. You'd just call the CLI
command directly, with gdb.execute.

xmethods sounds like something that maybe might be useful here:
https://sourceware.org/gdb/onlinedocs/gdb/Xmethods-In-Python.html
though from the docs it sounds like you can only replace class
methods, not free functions, currently. Not sure, have never written any.

Thanks,
Pedro Alves