Bug 1092144
| Summary: | only a single inlined_subroutine DIE is emitted during loop unrolling | ||
|---|---|---|---|
| Product: | Red Hat Developer Toolset | Reporter: | Jonathan Lebon <jlebon> |
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> |
| Status: | CLOSED WORKSFORME | QA Contact: | qe-baseos-tools-bugs |
| Severity: | unspecified | Docs Contact: | |
| Priority: | unspecified | ||
| Version: | DTS 5.0 RHEL 7 | CC: | jakub, jason, law, mcermak, mjw, mnewsome, mpolacek, sipoyare |
| Target Milestone: | rc | Keywords: | Bugfix |
| Target Release: | 6.0 | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2020-12-08 19:38:10 UTC | 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: | |||
| Bug Depends On: | |||
| Bug Blocks: | 1110700, 1191021 | ||
This request was not resolved in time for the current release. Red Hat invites you to ask your support representative to propose this request, if still desired, for consideration in the next release of Red Hat Enterprise Linux. This now works in DTS 9, even with -O3: (Actually, even DTS 3 works as expected.)
(gdb) b ibar
Breakpoint 1 at 0x401145: file tmp.c, line 12.
(gdb) r
Starting program: /root/tmp
Missing separate debuginfos, use: debuginfo-install glibc-2.17-307.el7.x86_64
Breakpoint 1, ibar () at tmp.c:12
12 j += ibar();
(gdb) c
Continuing.
printing
Breakpoint 1, ibar () at tmp.c:12
12 j += ibar();
(gdb) c
Continuing.
printing
Breakpoint 1, ibar () at tmp.c:12
12 j += ibar();
(gdb) c
Continuing.
printing
Breakpoint 1, ibar () at tmp.c:12
12 j += ibar();
However, there still is just one DW_TAG_inlined_subroutine:
<2><3c9>: Abbrev Number: 21 (DW_TAG_inlined_subroutine)
<3ca> DW_AT_abstract_origin: <0x450>
<3ce> DW_AT_entry_pc : 0x401080
<3d6> DW_AT_GNU_entry_view: 2
<3d7> DW_AT_ranges : 0x0
<3db> DW_AT_call_file : 1
<3dc> DW_AT_call_line : 12
<3dd> DW_AT_call_column : 10
So I'm not sure if we should move forward with this.
Jonathan, would you be OK with us moving forward with this bug? I.e., mark is as fixed, given Comment 11. DTS 10.0 meanwhile. Hmm, interesting that it doesn't unroll the loop anymore. It might just be that the sample I've provided no longer triggers loop unrolling, and that the underlying issue of breakpoints on unrolled loops is still present. My suggestion is to try to find another minimal scenario where loop unrolling is done and trying out the gdb steps again. |
Description of problem: When GCC does a single unrolling of a loop in which a function call has been inlined, an inlined_subroutine DIE is emitted only for the first inlining, not for the second one in the loop. As a result, DWARF consumers such as SystemTap/GDB only fire once at startup when probing the inlined function, rather than at every iteration. Version-Release number of selected component (if applicable): $ uname -r 3.10.0-121.el7.x86_64 $ rpm -q gcc gcc-4.8.2-16.el7.x86_64 How reproducible: All the time Steps to Reproduce: $ cat tmp.c #include <stdio.h> #include <unistd.h> inline int ibar (void) { usleep(250000); return printf("printing\n"); } int main (int argc, char *argv[]) { int j = 0; for (;;) { j += ibar(); if (argc > 1) return; } return j; } $ gcc tmp.c -g -O -o tmp $ Actual results: $ gdb tmp (gdb) break ibar Breakpoint 1 at 0x4005c0: ibar. (2 locations) (gdb) run Starting program: /notnfs/jlebon/codebase/systemtap/systemtap/testsuite/systemtap.unprivileged/tmp Breakpoint 1, main (argc=1, argv=0x7fffffffe298) at tmp.c:12 12 j += ibar(); (gdb) c Continuing. printing printing printing ^C Program received signal SIGINT, Interrupt. (gdb) q $ Expected results: GDB breaks at every iteration rather than only the first one. Additional info: The loop is unrolled once: $ objdump -d tmp | grep '<main>' -A 18 00000000004005e2 <main>: 4005e2: 53 push %rbx 4005e3: 89 fb mov %edi,%ebx 4005e5: bf 90 d0 03 00 mov $0x3d090,%edi 4005ea: e8 d1 fe ff ff callq 4004c0 <usleep@plt> 4005ef: bf ba 06 40 00 mov $0x4006ba,%edi 4005f4: e8 87 fe ff ff callq 400480 <puts@plt> 4005f9: 83 fb 01 cmp $0x1,%ebx 4005fc: 7f 16 jg 400614 <main+0x32> 4005fe: bf 90 d0 03 00 mov $0x3d090,%edi 400603: e8 b8 fe ff ff callq 4004c0 <usleep@plt> 400608: bf ba 06 40 00 mov $0x4006ba,%edi 40060d: e8 6e fe ff ff callq 400480 <puts@plt> 400612: eb ea jmp 4005fe <main+0x1c> 400614: b8 00 00 00 00 mov $0x0,%eax 400619: 5b pop %rbx 40061a: c3 retq 40061b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) We can see ibar is inlined once outside the loop at 4005e5, and once in the loop at 4005fe. However, the DWARF info only has a single inlined_subroutine DIE with entry_pc pointing to 4005e5: $ readelf -w tmp ... <1><29d>: Abbrev Number: 14 (DW_TAG_subprogram) <29e> DW_AT_external : 1 <29e> DW_AT_name : (indirect string, offset: 0x36): ibar <2a2> DW_AT_decl_file : 1 <2a3> DW_AT_decl_line : 4 <2a4> DW_AT_prototyped : 1 <2a4> DW_AT_type : <0x62> <2a8> DW_AT_inline : 3 (declared as inline and inlined) ... <2><343>: Abbrev Number: 22 (DW_TAG_inlined_subroutine) <344> DW_AT_abstract_origin: <0x29d> <348> DW_AT_entry_pc : 0x4005e5 <350> DW_AT_ranges : 0x0 <354> DW_AT_call_file : 1 <355> DW_AT_call_line : 12 Note however that the associated ranges do indicate the two locations: $ readelf -w tmp ... Contents of the .debug_ranges section: Offset Begin End 00000000 00000000004005e5 00000000004005f9 00000000 00000000004005fe 0000000000400614 00000000 <End of list> Shouldn't these be separate DW_TAG_inlined_subroutine DIEs instead?