Breakpoints on inlined functions described by DW_AT_ranges

I’m trying to set a breakpoint (using b jl_apply) on a function (jl_apply) that is inlined in a number of places. This generally works fine, but I have noticed that in certain cases LLDB fails to set a breakpoint even though when I step through manually, it does know which function the code belongs to. Investigating further, I have found that the difference comes from whether the inlined subroutine is described via DW_AT_low_pc or via DW_AT_ranges, so e.g.

0x0000f6c8: DW_TAG_inlined_subroutine [42] *
DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x22e7 => {0x0000d394} “jl_apply”)
DW_AT_low_pc [DW_FORM_addr] (0x000000000000f768)
DW_AT_high_pc [DW_FORM_addr] (0x000000000000f776)
DW_AT_call_file [DW_FORM_data1] (“/Users/kfischer/Projects/julia-testpatch/src/gf.c”)
DW_AT_call_line [DW_FORM_data1] (34)

will get a breakpoint while

0x0000f6ee: DW_TAG_inlined_subroutine [53] *
DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x22e7 => {0x0000d394} “jl_apply”)
DW_AT_ranges [DW_FORM_data4] (0x0000b790
[0x000000000000f785 - 0x000000000000f788)
[0x000000000000f79c - 0x000000000000f7b8))
DW_AT_call_file [DW_FORM_data1] (“/Users/kfischer/Projects/julia-testpatch/src/gf.c”)
DW_AT_call_line [DW_FORM_data2] (1668)

will not. Is this the intended behavior or a bug? If it’s a bug, any ideas where to look to try to fix it?

Thanks,
Keno

Certainly a bug. This bit:

        if (inlined_die)
        {
            Block &function_block = sc.function->GetBlock (true);
            sc.block = function_block.FindBlockByID (inlined_die.GetID());
            if (sc.block == NULL)
                sc.block = function_block.FindBlockByID (inlined_die.GetOffset());
            if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
                addr.Clear();
        }

from SymbolFileDwarf::ResolveFunction is most likely responsible. I don't remember offhand how the blocks deal with the fact that this one die actually represents multiple blocks, but it's going to be something related to that.

If you want to have a look, that would be great, otherwise file a bug and we can take a look when we get some free time.

Jim

Hi Jim,

I tried to work on this, but everything there actually seemed correct. It now seems to me like those functions are simply missing from .apple_names (compiled with latest Clang trunk), so this might not be an LLDB bug after all.

Keno

Actually, it’s not a clang bug either. The info is there in the .o file. This only happens if lldb is looking in the .dSYM. If I delete that and let lldb look in the .o files, it sets the breakpoint just fine, so I’ll chalk this up as a dsymutil bug. llvm-dsymutil works fine.

Ah, okay. For a while the llvm-dsymutil folks were trying to make the output of dsymutil & llvm-dsymutil identical so that they could be sure llvm-dsymutil was doing the right thing, so I'm a little surprised the two differ in this regard. But if it works with .o files & llvm-dsymutil I think that's all we really care about at this point.

Jim

If llvm-dsymutil is dropping the name, then send me your example and I will file a bug on them to get this fixed.

Greg Clayton