Problem with DW_AT_abstract_origin references

Hi!

I have two class methods implemented in the same .cpp file. They inline each other after code optimization.
The problem is that each of them contains a tag DW_TAG_inlined_subroutine with attribute DW_AT_abstract_origin referring
to other one. It only happens when LTO is enabled.

When loading debug information, GDB gets into infinite loop and crashes with stack overflow.

Here is a piece of dwarf dump, search for text "HERE" to find the references. I tried to reproduce it with minimal code with no results.

< 1><0x00021c68> DW_TAG_subprogram
                      DW_AT_specification <global die offset 0x000ed3fd>
                      DW_AT_low_pc 0x00108da0
                      DW_AT_high_pc 0x00108e96
                      DW_AT_frame_base DW_OP_reg7
                      DW_AT_object_pointer <0x00021c85>
                      DW_AT_APPLE_omit_frame_ptr yes(1)
                      DW_AT_inline DW_INL_inlined
< 2><0x00021c85> DW_TAG_formal_parameter
                        DW_AT_name this
                        DW_AT_type <global die offset 0x001102e2>
                        DW_AT_artificial yes(1)
                        DW_AT_location <loclist with 3 entries follows>
            [ 0]<lowpc=0x00108da0><highpc=0x00108da8>DW_OP_reg5
            [ 1]<lowpc=0x00108da8><highpc=0x00108de5>DW_OP_reg3
            [ 2]<lowpc=0x00108deb><highpc=0x00108e83>DW_OP_reg3
< 2><0x00021c93> DW_TAG_formal_parameter
                        DW_AT_name f
                        DW_AT_decl_file 0x0000000a src/Session.cpp
                        DW_AT_decl_line 0x0000070c
                        DW_AT_type <global die offset 0x0005ee33>
                        DW_AT_location <loclist with 2 entries follows>
            [ 0]<lowpc=0x00108da0><highpc=0x00108da8>DW_OP_reg4
            [ 1]<lowpc=0x00108da8><highpc=0x00108dc3>DW_OP_reg4
< 2><0x00021ca4> DW_TAG_lexical_block
                          fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f1920
< 3><0x00021caa> DW_TAG_lexical_block
                            fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f18f0
< 4><0x00021cb0> DW_TAG_lexical_block
                              fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f18c0
< 5><0x00021cb6> DW_TAG_variable
                              DW_AT_name _layer
                              DW_AT_decl_file 0x0000000a src/Session.cpp
                              DW_AT_decl_line 0x00000714
                              DW_AT_type <global die offset 0x000f2254>
< 5><0x00021cc3> DW_TAG_lexical_block
                                fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f1890
< 6><0x00021cc9> DW_TAG_lexical_block
                                DW_AT_low_pc 0x00108df0
                                DW_AT_high_pc 0x00108e96
< 7><0x00021cdb> DW_TAG_variable
                                  DW_AT_name _log
                                  DW_AT_decl_file 0x0000000a src/Session.cpp
                                  DW_AT_decl_line 0x00000714
                                  DW_AT_type <global die offset 0x0017c8f6>
                                  DW_AT_location DW_OP_reg14
< 7><0x00021cea> DW_TAG_inlined_subroutine
                                  DW_AT_abstract_origin <0x0009ff85>
                                  DW_AT_low_pc 0x00108e19
                                  DW_AT_high_pc 0x00108e6f
                                  DW_AT_call_file 0x0000000a src/Session.cpp
                                  DW_AT_call_line 0x00000714
< 8><0x00021d03> DW_TAG_formal_parameter
                                    DW_AT_name this
                                    DW_AT_type <global die offset 0x0010867e>
                                    DW_AT_artificial yes(1)
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108df8><highpc=0x00108e83>DW_OP_reg14
< 8><0x00021d11> DW_TAG_formal_parameter
                                    DW_AT_name __out
                                    DW_AT_decl_file 0x00000039 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ostream
                                    DW_AT_decl_line 0x000001f9
                                    DW_AT_type <global die offset 0x0016764f>
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108e24><highpc=0x00108e83>DW_OP_reg15
< 8><0x00021d22> DW_TAG_formal_parameter
                                    DW_AT_name __os
                                    DW_AT_decl_file 0x00000050 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/basic_string.h
                                    DW_AT_decl_line 0x000009c2
                                    DW_AT_type <global die offset 0x0016764f>
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108e24><highpc=0x00108e47>DW_OP_reg15
< 8><0x00021d33> DW_TAG_formal_parameter
                                    DW_AT_name this
                                    DW_AT_type <global die offset 0x00117ac5>
                                    DW_AT_artificial yes(1)
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108e31><highpc=0x00108e83>DW_OP_reg3
< 8><0x00021d41> DW_TAG_inlined_subroutine
                                    DW_AT_abstract_origin <0x00084edf>
                                    DW_AT_low_pc 0x00108e31
                                    DW_AT_high_pc 0x00108e3c
                                    DW_AT_call_file 0x00000050 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/basic_string.h
                                    DW_AT_call_line 0x000009c7
< 9><0x00021d5a> DW_TAG_inlined_subroutine
                                      DW_AT_abstract_origin <0x00084ef1>
                                      DW_AT_low_pc 0x00108e31
                                      DW_AT_high_pc 0x00108e38
                                      DW_AT_call_file 0x00000050 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/basic_string.h
                                      DW_AT_call_line 0x00000657
< 4><0x00021d78> DW_TAG_inlined_subroutine
                            DW_AT_abstract_origin <0x00021db1> # <<<< HERE
                            DW_AT_low_pc 0x00108dd5
                            DW_AT_high_pc 0x00108de5
                            DW_AT_call_file 0x0000000a src/Session.cpp
                            DW_AT_call_line 0x00000715
< 5><0x00021d91> DW_TAG_formal_parameter
                              DW_AT_name this
                              DW_AT_type <global die offset 0x001102e2>
                              DW_AT_artificial yes(1)
                              DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108dd5><highpc=0x00108de5>DW_OP_reg3
< 5><0x00021d9f> DW_TAG_formal_parameter
                              DW_AT_name f
                              DW_AT_decl_file 0x0000000a src/Session.cpp
                              DW_AT_decl_line 0x00000719
                              DW_AT_type <global die offset 0x0005ee33>
                              DW_AT_const_value 0x00000000

< 1><0x00021db1> DW_TAG_subprogram
                      DW_AT_specification <global die offset 0x000ed42e>
                      DW_AT_low_pc 0x00108ea0
                      DW_AT_high_pc 0x00108f96
                      DW_AT_frame_base DW_OP_reg7
                      DW_AT_object_pointer <0x00021dce>
                      DW_AT_APPLE_omit_frame_ptr yes(1)
                      DW_AT_inline DW_INL_inlined
< 2><0x00021dce> DW_TAG_formal_parameter
                        DW_AT_name this
                        DW_AT_type <global die offset 0x001102e2>
                        DW_AT_artificial yes(1)
                        DW_AT_location <loclist with 3 entries follows>
            [ 0]<lowpc=0x00108ea0><highpc=0x00108ea8>DW_OP_reg5
            [ 1]<lowpc=0x00108ea8><highpc=0x00108ee5>DW_OP_reg3
            [ 2]<lowpc=0x00108eeb><highpc=0x00108f83>DW_OP_reg3
< 2><0x00021ddc> DW_TAG_formal_parameter
                        DW_AT_name f
                        DW_AT_decl_file 0x0000000a src/Session.cpp
                        DW_AT_decl_line 0x00000719
                        DW_AT_type <global die offset 0x0005ee33>
                        DW_AT_location <loclist with 2 entries follows>
            [ 0]<lowpc=0x00108ea0><highpc=0x00108ea8>DW_OP_reg4
            [ 1]<lowpc=0x00108ea8><highpc=0x00108ec3>DW_OP_reg4
< 2><0x00021ded> DW_TAG_lexical_block
                          fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f19e0
< 3><0x00021df3> DW_TAG_lexical_block
                            fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f19b0
< 4><0x00021df9> DW_TAG_lexical_block
                              fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f1980
< 5><0x00021dff> DW_TAG_variable
                              DW_AT_name _layer
                              DW_AT_decl_file 0x0000000a src/Session.cpp
                              DW_AT_decl_line 0x00000721
                              DW_AT_type <global die offset 0x000f2254>
< 5><0x00021e0c> DW_TAG_lexical_block
                                fails to find DW_AT_ranges offset attr 0x55 form 0x6 DW_AT_ranges 0x000f1950
< 6><0x00021e12> DW_TAG_lexical_block
                                DW_AT_low_pc 0x00108ef0
                                DW_AT_high_pc 0x00108f96
< 7><0x00021e24> DW_TAG_variable
                                  DW_AT_name _log
                                  DW_AT_decl_file 0x0000000a src/Session.cpp
                                  DW_AT_decl_line 0x00000721
                                  DW_AT_type <global die offset 0x0017c8f6>
                                  DW_AT_location DW_OP_reg14
< 7><0x00021e33> DW_TAG_inlined_subroutine
                                  DW_AT_abstract_origin <0x0009ff85>
                                  DW_AT_low_pc 0x00108f19
                                  DW_AT_high_pc 0x00108f6f
                                  DW_AT_call_file 0x0000000a src/Session.cpp
                                  DW_AT_call_line 0x00000721
< 8><0x00021e4c> DW_TAG_formal_parameter
                                    DW_AT_name this
                                    DW_AT_type <global die offset 0x0010867e>
                                    DW_AT_artificial yes(1)
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108ef8><highpc=0x00108f83>DW_OP_reg14
< 8><0x00021e5a> DW_TAG_formal_parameter
                                    DW_AT_name this
                                    DW_AT_type <global die offset 0x0010867e>
                                    DW_AT_artificial yes(1)
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108ef8><highpc=0x00108f83>DW_OP_reg14
< 8><0x00021e68> DW_TAG_formal_parameter
                                    DW_AT_name __out
                                    DW_AT_decl_file 0x00000039 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ostream
                                    DW_AT_decl_line 0x000001f9
                                    DW_AT_type <global die offset 0x0016764f>
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108f24><highpc=0x00108f83>DW_OP_reg15
< 8><0x00021e79> DW_TAG_formal_parameter
                                    DW_AT_name __os
                                    DW_AT_decl_file 0x00000050 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/basic_string.h
                                    DW_AT_decl_line 0x000009c2
                                    DW_AT_type <global die offset 0x0016764f>
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108f24><highpc=0x00108f47>DW_OP_reg15
< 8><0x00021e8a> DW_TAG_formal_parameter
                                    DW_AT_name this
                                    DW_AT_type <global die offset 0x00117ac5>
                                    DW_AT_artificial yes(1)
                                    DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108f31><highpc=0x00108f83>DW_OP_reg3
< 8><0x00021e98> DW_TAG_inlined_subroutine
                                    DW_AT_abstract_origin <0x00084edf>
                                    DW_AT_low_pc 0x00108f31
                                    DW_AT_high_pc 0x00108f3c
                                    DW_AT_call_file 0x00000050 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/basic_string.h
                                    DW_AT_call_line 0x000009c7
< 9><0x00021eb1> DW_TAG_inlined_subroutine
                                      DW_AT_abstract_origin <0x00084ef1>
                                      DW_AT_low_pc 0x00108f31
                                      DW_AT_high_pc 0x00108f38
                                      DW_AT_call_file 0x00000050 /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/basic_string.h
                                      DW_AT_call_line 0x00000657
< 4><0x00021ecf> DW_TAG_inlined_subroutine
                            DW_AT_abstract_origin <0x00021c68> # <<<< HERE
                            DW_AT_low_pc 0x00108ed5
                            DW_AT_high_pc 0x00108ee5
                            DW_AT_call_file 0x0000000a src/Session.cpp
                            DW_AT_call_line 0x00000722
< 5><0x00021ee8> DW_TAG_formal_parameter
                              DW_AT_name this
                              DW_AT_type <global die offset 0x001102e2>
                              DW_AT_artificial yes(1)
                              DW_AT_location <loclist with 1 entries follows>
            [ 0]<lowpc=0x00108ed5><highpc=0x00108ee5>DW_OP_reg3
< 5><0x00021ef6> DW_TAG_formal_parameter
                              DW_AT_name f
                              DW_AT_decl_file 0x0000000a src/Session.cpp
                              DW_AT_decl_line 0x0000070c
                              DW_AT_type <global die offset 0x0005ee33>
                              DW_AT_const_value 0x00000000

clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix

Compiler options: -m64 -flto -pipe -ffast-math -fno-finite-math-only -pthread -march=core2 -mtune=corei7 -O3 -g -fvisibility=hidden -fvisibility-inlines-hidden -fPIC
Linker options: -m64 -flto -pipe -ffast-math -fno-finite-math-only -pthread -march=core2 -mtune=corei7 -O3 -g -fvisibility=hidden -fvisibility-inlines-hidden -fuse-ld=gold -shared -Wl,-zdefs

Thanks!

Yep - that'd be a known bug in Clang 3.4 (well, known when I looked at
the code, saw that it was no good, and fixed it) that has, hopefully,
since been fixed. At least I think that's what you're seeing.

Have you tried reproducing this with Clang ToT? (or a 3.5 release candidate?)

You should be able to reproduce this by writing a small example with
__attribute__((force_inline)) (or is it always_inline, I forget...
maybe it's one word, without the underscore... ), I would imagine -
even without LTO.

Anyway, if you have some preprocessed source, I can compile it with
Clang ToT and show you the dwarfdump to see if it makes more sense
(but I can't easily verify that GDB doesn't infinitely recurse without
a fully linkable/executable example).

- David

Yes, it works fine in 3.5.

Great - thanks for letting us know/reporting this!

(even though it's already fixed - I'm gratified to know it was a real
user-impacting bug that I found/fixed by inspection ;))