Advice for setting debug locations

Hello,

I'm trying to fix a long standing issue we are having in Julia where
when the file information switched, we weren't recording that
correctly, so line information showed up in the wrong file. Basically
we would always create a scope with the DISubprogram and the given
line number. What I tried was to change the scope to be a DIFile
instead so we'd get the correct file information. Unfortunately I had
to revert this [1], because it crashes llvm's dwarf reader (which we
use to get line information for backtraces when exceptions are thrown)
with the following backtrace:

isNULL at /Users/kfischer/Documents/julia-debug/deps/llvm-svn/lib/DebugInfo/DWARFDebugInfoEntry.h:52
getAddressRanges at
/Users/kfischer/Documents/julia-debug/deps/llvm-svn/lib/DebugInfo/DWARFDebugInfoEntry.cpp:242
collectAddressRanges at
/Users/kfischer/Documents/julia-debug/deps/llvm-svn/lib/DebugInfo/DWARFUnit.cpp:302
generate at /Users/kfischer/Documents/julia-debug/deps/llvm-svn/lib/DebugInfo/DWARFDebugAranges.cpp:54
getDebugAranges at
/Users/kfischer/Documents/julia-debug/deps/llvm-svn/lib/DebugInfo/DWARFContext.cpp:270
getCompileUnitForAddress at
/Users/kfischer/Documents/julia-debug/deps/llvm-svn/lib/DebugInfo/DWARFContext.cpp:423

Can somebody tell me what the correct way to achieve this is?

[1] Revert kf/filediinfo · JuliaLang/julia@e494cb6 · GitHub

Use the second form of DW_TAG_lexical_block metadata (the one with 3
fields - http://llvm.org/docs/SourceLevelDebugging.html#block-descriptors
) to describe file changes within a sequence of LLVM IR functions.

A small example of IR would be easier to follow if you want help
debugging why your IR is causing problems.

Sorry, I didn't have a small IR example and I was sure I was just
doing something stupid. Thanks for the help, I'll try it out and
report back. Maybe it would be good to add an assertion or something
that tells people what's wrong in this case, since the generated DWARF
seems to be invalid?

Sorry, I didn't have a small IR example and I was sure I was just
doing something stupid. Thanks for the help, I'll try it out and
report back. Maybe it would be good to add an assertion or something
that tells people what's wrong in this case, since the generated DWARF
seems to be invalid?

I'm still not sure exactly where things went wrong for you, so unsure
as to where to add the assertion - a small IR example would be helpful
for that. The suggestion to use the DW_TAG_lexical_block 3-field-form
was just based on your description of your goals, it sounded like that
was the tool you needed & weren't using yet.

Oh, I see. Sorry I misunderstood. I'll try to come up with some
minimal IR. The assertion stems from the fact that getCompileUnitDIE()
returns null and then crashes at DWARFUnit.cpp:301. I admit I don't
know if this problem is on the parsing or the generation side.

While I come up with the IR, basically what I was doing was using a
DebugLoc with scope being a DIFile rather than a DISubprogram as
before.

Oh, I see. Sorry I misunderstood. I'll try to come up with some
minimal IR. The assertion stems from the fact that getCompileUnitDIE()
returns null and then crashes at DWARFUnit.cpp:301. I admit I don't
know if this problem is on the parsing or the generation side.

While I come up with the IR, basically what I was doing was using a
DebugLoc with scope being a DIFile rather than a DISubprogram as
before.

Yes, I imagine that would end poorly. Wouldn't be hard to construct
such an example and demonstrate the failure.

Instead, using the DW_TAG_lexical_block (the one with 3 fields) you
nest that inside - so your DebugLoc references the lexical block and
the lexical block references the subprogram.

All the DebugLocs should reference scopes that eventually reference
the (non-inlined) subprogram that contains the instruction.

Using the 3 field DW_TAG_lexical_block worked just fine. Thanks!