Bug 29074 - gdb fails to find a shared library for a function
Summary: gdb fails to find a shared library for a function
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: backtrace (show other bugs)
Version: unknown
: P2 normal
Target Milestone: 14.1
Assignee: Tom Tromey
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-04-20 06:20 UTC by Rui Ueyama
Modified: 2023-08-26 16:35 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2023-08-01 00:00:00
Project(s) to access:
ssh public key:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rui Ueyama 2022-04-20 06:20:19 UTC
It looks like gdb sometimes fails to find a shared library name for a function. My shared library ends with something like this:

ruiu@blue:~/mold$ objdump -d liba.so
<<<omit>>>
0000000000001140 <_ZL5func2i>:
    1140:       55                      push   %rbp
    1141:       48 89 e5                mov    %rsp,%rbp
    1144:       48 83 ec 10             sub    $0x10,%rsp
    1148:       89 7d fc                mov    %edi,-0x4(%rbp)
    114b:       e8 c0 fe ff ff          call   1010 <abort@plt>
ruiu@blue:~/mold$

So, the DSO's text segment ends with a call to `abort`. Since GCC knows `abort` does not return, it can emit code like this.

When gdb tries to lookup a shared library using a function return address as a key, the "return address" for the above function is one byte beyond the executable segment of the DSO. Because of that, gdb fails to find a shared library for that function. An example output is shown below:

Program received signal SIGABRT, Aborted.
0x00007ffff70b0cdb in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff70b0cdb in raise () from /lib64/libc.so.6
#1 0x00007ffff70b2375 in abort () from /lib64/libc.so.6
#2 0x00007ffff7ff0140 in func2(int) ()
#3 0x00007ffff7ff0123 in func(int) () from ./liba.so
#4 0x0000000000201149 in main () at a1.cpp:2

The third line from the bottom lacks the shared library name.

I believe gdb has to subtract one byte from a return address before using it to lookup a shared library.

This is originally reported at https://github.com/rui314/mold/issues/444
Comment 1 Tom Tromey 2023-07-31 22:18:57 UTC
Another case of bug#8416.
Easy to fix but I am not sure how to write a robust test.
Comment 2 Tom Tromey 2023-08-03 17:18:53 UTC
Perhaps a non-robust test is good enough.
Comment 4 Sourceware Commits 2023-08-26 16:34:33 UTC
The master branch has been updated by Tom Tromey <tromey@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9030a82d6f700e03ab143f0d002e9f21ae2fd52f

commit 9030a82d6f700e03ab143f0d002e9f21ae2fd52f
Author: Tom Tromey <tom@tromey.com>
Date:   Tue Aug 1 15:09:49 2023 -0600

    Use get_frame_address_in_block in print_frame
    
    The author of 'mold' pointed out that with a certain shared library,
    gdb would fail to find the shared library's name in 'bt'.
    
    The function in question appeared at the end of the .so's .text
    segment and ended with a call to 'abort'.
    
    This turned out to be a classic case of calling get_frame_pc when
    get_frame_address_in_block is needed -- the former will be off-by-one
    for purposes of finding the enclosing function or shared library.
    
    The included test fails without the patch on my system.  However, I
    imagine it can't be assumed to reliably fail.  Nevertheless it seemed
    worth doing.
    
    Regression tested on x86-64 Fedora 38.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29074
    Reviewed-by: Kevin Buettner <kevinb@redhat.com>
Comment 5 Tom Tromey 2023-08-26 16:35:16 UTC
Fixed.