Re: gdb does not stop at printf for ppc
Peter Bergner via Libc-help <libc-help-9JcytcrH/[email protected]> Tue, 30 Sep 2025 23:03:51 -0500
| Newsgroups | gmane.comp.lib.glibc.user,gmane.comp.lib.glibc.alpha,gmane.comp.gdb.devel |
|---|---|
| Message-ID | <[email protected]> |
Adding Carl, Mike, Segher and Surya to the CC for their input, so I'm
leaving Sachin's entire question for them to see.
I'm also CCing the libc-alpha and GDB lists for wider exposure, since
this is an actual BUG. My reply is at the end of Sachin's questions.
On 9/25/25 2:47 AM, Sachin Monga wrote:
> Hi Stewards
>
>
> Summary:
>
> There is a test case in GDB where printf is getting converted into
> __printfieee128 when program is compiled with "--no-builtin" flag.
> The program is working fine on a machine with glibc 2.34, but not on
> another machine where glibc 2.40 is installed.
>
>
> Test program:
> $ cat test.c
> #include <stdio.h>
>
> int
> main ()
> {
> printf ("Hello World!\n");
> return 0;
> }
>
> GDB operation:
> 1. Load the binary
> 2. Break main
> 3. Run
> 4. Once program stops at main, then Break printf
> 5. Continue
>
> Expected ouput: GDB should stop at printf function
>
> Actual Output on Machine1(with glibc 2.34) : GDB stop at printf symbol
>
> Actual Output on Machine2(with glibc 2.40) : GDB does NOT stop at printf
> symbol
>
>
> Analysis:
> Glibc debug package with source is required. Once it is installed.
> Then program is working fine with glibc 2.34, but not where glibc 2.40
> is installed.
>
>
> 1. Install debug info package for glibc
> sudo dnf debuginfo-install glibc
>
> Machine1: glibc packages
> $ rpm -q glibc glibc-debuginfo glibc-debugsource
> glibc-2.34-168.el9_6.23.ppc64le
> glibc-debuginfo-2.34-168.el9_6.23.ppc64le
> glibc-debugsource-2.34-168.el9_6.23.ppc64le
>
>
>
> Machine2: glibc 2.40 packages
> $ rpm -q glibc glibc-debuginfo glibc-debugsource
> glibc-2.40-28.fc41.ppc64le
> glibc-debuginfo-2.40-28.fc41.ppc64le
> glibc-debugsource-2.40-28.fc41.ppc64le
> ~/GDB/latest_gdb/print$
>
>
> I execute additional program to check behaviour in both the machine
>
> $] cat test_print_map.c
> #include <stdio.h>
>
> int main(void) {
> printf("Hello World!\n");
>
> // Print address of printf and its ieee128 variant
> printf("Address of printf: %p\n", (void*)printf);
> #ifdef __GLIBC__
> extern int __printfieee128(const char *, ...);
> printf("Address of __printfieee128: %p\n", (void*)__printfieee128);
> #endif
>
> return 0;
> }
>
> Compilation
> gcc -O0 -g -o test_print_map test_print_map.c --no-builtin
>
>
> Machine 2 (with glibc 2.40)
> $ ./test_printf_map
> Hello World!
> Address of printf: 0x7fff806870c0 <---- Same address
> Address of __printfieee128: 0x7fff806870c0 <------ Same address
> Abhay@ltcd97-lp3:~/GDB/latest_gdb/print$
>
>
> Machine1 (with glibc 2.34)
> $ ./test_printf_map
> Hello World!
> Address of printf: 0x20002a066980 <-------- Different address
> Address of __printfieee128: 0x20002a082e80 <-------- Different address
> [abhay@kubota print]$
>
>
> Based on above output, my assumption are (may be it is not 100% true):
> Here, the compiler + linker decide how to bind the symbol:
>
> In glibc 2.40 :
> printf is just a strong alias to __printfieee128, so both resolve to the
> same address at link time.
>
> In glibc 2.34 :
> printf lives at a different symbol table entry than __printfieee128.
> May be two different definitions or pointing to IO_printf(). I am not sure.
>
>
> So the query is why gdb is not able to stop at printf symbol where glibc
> 2.40 is installed ? Is this a bug in glibc or I am missing something ?
>
>
> Regards:
> Sachin.
There is actually a GLIBC bugzilla about this and it's not just printf,
but all IEEE 128-bit floating point functions. I've assigned it to you now! :-)
I don't remember if the solution in Carl's last comment was actually decided
to be the correct way to "fix" this though:
https://sourceware.org/bugzilla/show_bug.cgi?id=29989
My guess is the difference between your two systems, is that the newer
system's gcc was built with --with-long-double-format=ieee which causes
gcc to enable -mabi=ieeelongdouble by default, meaning "long double"
is equal to IEEE128 instead of the older -mabi=ibmlongdouble usage,
where "long double" is equal to the IBM128/IBM double-double format.
With -mabi=ibmlongdouble, calls to printf() are directed at the printf
symbol in glibc. With -mabi=ieeelongdouble, gcc remaps printf() calls
to the __printfieee128 symbol in glibc. I don't think symbol versioning
would have helped here, since we have to handle calls to both the old
and new printf symbols. I'll let Mike correct me if I'm wrong. :-)
Obviously, we don't want to make users have to say "break __printfieee128"
in gdb, but rather "break printf" should set breakpoints on both printf and
__printfieee128. The best way to accomplish that though...I'm not sure
we decided that. Ie, can we fix this in GLIBC or add a workaround in GDB?
Mike, Segher, Carl, Surya or anyone else, anything else to add?
Peter