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