Bug 1845696

Summary: Wrong line for code containing inlined functions
Product: Red Hat Developer Toolset Reporter: Joe Wright <jwright>
Component: gdbAssignee: Keith Seitz <keiths>
Status: ASSIGNED --- QA Contact: Martin Cermak <mcermak>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: DTS 10.0 RHEL 7CC: alanm, amike, blarsen, casantos, dsmith, gdb-bugs, jan, keiths, mcermak, mkolbas, ohudlick
Target Milestone: ---Keywords: Triaged
Target Release: 10.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
customer reproducer information none

Description Joe Wright 2020-06-09 20:25:15 UTC
Created attachment 1696382 [details]
customer reproducer information

Description of problem:
GDB is showing the wrong line information for a function call in a line with inlined functions.

Version-Release number of selected component (if applicable):


How reproducible:
For the following code:

```

struct MyClass;
struct ptr {
    MyClass* get() { return t; }
    MyClass* t;
};
struct MyClass { void call(); };
void MyClass::call() {
    *(char*)(nullptr) = 1;
}
static void intermediate(ptr p) {
    p.get()->call();
}
int main() {
    intermediate(ptr{new MyClass});
}

```

Compiled with GCC 8 or above with these flags:

```
g++ -Og -g -o main main.cpp
```

The function "call" will crash and the backtrace using GDB HEAD looks like this:

```
#0  MyClass::call (this=0x416c20) at main.cpp:8
#1  0x0000000000401140 in intermediate (p=...) at main.cpp:3
#2  0x0000000000401157 in main () at main.cpp:14
```

Notice that the "intermediate" frame is pointing to main.cpp:3 which is the call to "get". I would expect it to show main.cpp:11

I tested GDB 8 and it shows the correct information but that seems by chance. If I move the "ptr" definition to a header, then it also fails with GDB 8 (but works with GDB head).

Looking at the decoded line information, it seems that there is no way for GDB to tell which is the correct call:

```
$ objdump -D main | grep callq.*intermediate
  401152:       e8 e4 ff ff ff          callq  40113b <_ZL12intermediate3ptr


$ objdump --dwarf=decodedline main | grep 40113b
main.cpp 10 0x40113b               x
main.cpp 11 0x40113b       1       x
main.cpp  3 0x40113b       2       x
main.cpp  3 0x40113b       3       x
main.cpp  3 0x40113b       4
main.cpp 11 0x40113b       5

```

There seems to be multiple line information for the same "callq" instruction. So I'm not sure how GDB would tell the difference. Maybe from the dwarf information it should be able to figure out which of those lines refer to inlined functions ?

Steps to Reproduce:
see above

Actual results:


Expected results:


Additional info:

Comment 2 Joe Wright 2020-06-09 21:24:07 UTC
Reproduced on the following gdb versions (DTS)

-bash-4.2$ scl enable devtoolset-9 bash
bash-4.2$ gdb --version
GNU gdb (GDB) Red Hat Enterprise Linux 8.3-3.el7

and

-bash-4.2$ scl enable devtoolset-6 bash
bash-4.2$ gdb --version
GNU gdb (GDB) Red Hat Enterprise Linux 7.12.1-48.el7

Comment 3 Keith Seitz 2020-06-17 17:42:52 UTC
Thank you for the report. Since RHEL7 development is over, I'm moving this to DTS to make
sure it is addressed for that release.

Comment 5 Keith Seitz 2021-01-14 19:40:08 UTC
This appears to be working correctly now with DTS 10 (compiled with devtoolset-10-gcc):

$ gdb main -ex r -ex bt
GNU gdb (GDB) Red Hat Enterprise Linux 9.2-9.el7
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from main...
Starting program: /home/rhel7/main 

Program received signal SIGSEGV, Segmentation fault.
MyClass::call (this=0x405010) at main.cc:8
8	    *(char*)(nullptr) = 1;
#0  MyClass::call (this=0x405010) at main.cc:8
#1  0x0000000000401140 in intermediate (p=...) at main.cc:11
#2  0x0000000000401157 in main () at main.cc:14
(gdb) 

Can anyone confirm?

Comment 6 Joe Wright 2021-02-24 15:26:45 UTC
Customer tested with DTS10, but reports behavior is inconsistent:

$ scl enable devtoolset-10 tcsh
$ gdb --version
GNU gdb (GDB) Red Hat Enterprise Linux 9.2-9.el7
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ gdb -batch -x gdb_cmds ./bin/main_with_header_gcc6 | grep intermediate
#1  0x0000000000400588 in intermediate (p=...) at main.cpp:15

$ gdb -batch -x gdb_cmds ./bin/main_with_header_gcc9 | grep intermediate
#1  0x0000000000401144 in intermediate (p=...) at header.h:6  <<<============================ INCONSISTENT

$ gdb -batch -x gdb_cmds ./bin/main_without_header_gcc6 | grep intermediate
#1  0x0000000000400588 in intermediate (p=...) at main.cpp:15

$ gdb -batch -x gdb_cmds ./bin/main_without_header_gcc9 | grep intermediate
#1  0x0000000000401144 in intermediate (p=...) at main.cpp:15

Comment 12 Guinevere Larsen 2021-09-03 20:55:21 UTC
We have started to re-investigate this issue. Initial testing revealed that there was no change on DTS-11, upstream master or gdb 11. 

We did, however, noticed that the compilation uses -Og (which still uses some optimizations), so decided to test with -O0, as we tend to have greater luck debugging with -O0 than when using -Og. The latter is supposed to not interfere, or even improve, debugging experience, but the optimizations often do interfere with debugging due to bugs or missing features. As we thought, disabling all optimizations stopped reproducing the bug, so this could be used as a work around while there isn't a proper fix.

We also found an (as of yet) unapproved patch in development that may fix this issue.