Summary: | PowerPC, gdb fails to stop at printf call | ||
---|---|---|---|
Product: | gdb | Reporter: | Carl E Love <cel> |
Component: | gdb | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | UNCONFIRMED --- | ||
Severity: | normal | CC: | sam, will_schmidt |
Priority: | P2 | ||
Version: | 12.1 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
Carl E Love
2023-01-12 01:05:45 UTC
I was given a suggestion of trying rbreak printf. When I run this command I get asked Make breakpoint pending on future shared library load? (y or [n]) after answering the question a buzillion times you eventually get back to the gdb prompt. <function, no debug info> 00000020.plt_call._dl_fatal_printf@@GLIBC_PRIVATE; Breakpoint 1062 at 0x7ffff7bdb9b4 <function, no debug info> _dl_fatal_printf@plt; (gdb) (gdb) (gdb) c Continuing. Breakpoint 157, 0x00000000100005a0 in 0000001b.plt_call.__printfieee128@@GLIBC_2.32 () not sure exactly where we are but if we do a few step commands we then see (gdb) s Single stepping until exit from function __printfieee128@plt, which has no line number information. (gdb) s Single stepping until exit from function __glink_PLTresolve, which has no line number information. ___ieee128_printf (format=0x10000920 "value is %d\n") at ../sysdeps/ieee754/ldbl-128ibm-compat/ieee128-printf.c:24 24 { (gdb) list 19 #include <stdarg.h> 20 #include <libio/libioP.h> 21 22 extern int 23 ___ieee128_printf (const char *format, ...) 24 { 25 va_list ap; 26 int done; 27 28 va_start (ap, format); not sure what all this means yet but thought is was interesting. The issue occurs with the Fedora 38 release. The issue does not occur with Ubuntu 22.04. This issue occurs with Fedora 38. The issue does not occur with Ubuntu 22.04. Digging into the issue further, the issue is not limited to the printf function but all of the symbols for the IEEE 128-bit floating point functions that are redirected in glibc. PowerPC supports the IBM 128-bit floating point format and the IEEE 128-bit floating point format. The IEEE 128 bit support redirects the various function calls to the ieee128 versions of the functions. For example, the printf function gets linked to the __printfieee128 function at linking time. Gdb is not aware of the __printfieee128 symbol was redirected from the original printf symbol so it only sets a breakpoint in the standard printf function. GDB fails to break in the redirected printf function. The printf function is just one of about 200 IEEE128 bit functions that get remapped for PowerPC. Ulrich and I have looked at fixing this in gdb by creating hidden symbols for printf that points to the __printfieee128 function. Although it is possible to do, in general it is really messy/hard to do because because of the naming scheme that was used. The original function was mapped to an ieee128 bit function with one of the following mappings: foo -> __fooieee128 fool -> __fooieee128 foo -> __newnameieee128 foo_r -> __fooieee128_r In GDB, you have to do the reverse mapping from to determine what the original function name "foo" so you can create a hidden symbol for "foo" that points to the IEEE 128 bit symbol "__fooiiieee128". We have tried to come up with a simple reverse mapping algorithm, but since __fooieee128 can map back to either foo or fool you have to search the entire list of mappings to determine what the original name was. Note, there are also some existing symbol names with ieee128 in them that are not the result of redirecting function foo to its IEEE 128 equivalent function. These also cannot be eliminated without going thru the list of known symbol names that have been redirected. A proof of concept patch in gdb which takes the symbol and searches the list of 200+ redirected function names to determine the original symbol name was done and works. The issue is maintaining the list of 200+ function mappings in gdb is fragile and not considered an acceptable solution. The feeling is the right thing to do is to have glibc emit a local symbol in the library binary, i.e. printf that points to the redirected symbol, i.e. __printfieee128. When the user types "break printf" GDB will set a breakpoint in the original printf function and in the __printfieee128 function via the local printf symbol in the glibc library. Basically, have glibc create the hidden symbol for each of the 200 or so redirected functions rather than having gdb create the hidden symbol as was done in the proof of concept patch. The advantage of having glibc add the local symbol to the library binary is it already knows what symbols are being redirected and gdb doesn't have to maintain a list of mappings. The new redirected symbols need to be dynamic symbols in case only the stripped binary is available. |