Re: [lldb-dev] [llvm-dev] Why is lldb telling me "variable not available"?

2020-02-25 Thread Brian Gesiak via lldb-dev
Thanks all, especially Jeremy, for your help.

> On Thu, Feb 6, 2020 at 11:04 AM Jeremy Morse  
> wrote:
>> Everything in the IR appears correct to my eyes, although I know next
>> to nothing about coroutines and might have missed something.

Yes, good point. I think a better explanation of the coroutine passes
is in order. The coro-split pass first uses 'llvm::LowerDbgDeclare' to
replace all llvm.dbg.declare for %i with llvm.dbg.value, and then
replaces all uses of the '%i = alloca i32' instruction with a
getelementptr instruction like this one:

%i.reload.addr63 = getelementptr inbounds %_Z3foov.Frame,
%_Z3foov.Frame* %FramePtr, i32 0, i32 7, !dbg !651

In other words, the value of %i is stored on the frame object, on the
heap, at an offset of 7 into the frame. I'm beginning to think a
fundamental fix for this issue would be to stop replacing
llvm.dbg.declare with llvm.dbg.value, and instead replace the
llvm.dbg.declare with llvm.dbg.addr that points the debugger to the %i
variable's new permanent location as an offset into the coroutine
frame object. Does this approach make sense to people on this mailing
list, who probably know more about how these intrinsics work than I
do?

>> If whatever's producing the coroutine IR has guarantees about where
>> and when variables are loaded/stored from/to memory, it should be
>> possible to put more information into the IR, so that the rest of LLVM
>> doesn't have to guess. For example, this portion of IR:
>>
>>   %15 = load i32, i32* %i.reload.addr62, align 4, !dbg !670
>>   call void @llvm.dbg.value(metadata i32 %15, metadata !659, metadata
>> !DIExpression()), !dbg !661
>>   %inc19 = add nsw i32 %15, 1, !dbg !670
>>   call void @llvm.dbg.value(metadata i32 %inc19, metadata !659,
>> metadata !DIExpression()), !dbg !661
>>   store i32 %inc19, i32* %i.reload.addr62, align 4, !dbg !670
>>
>> Could have a call to llvm.dbg.addr(metadata i32 *%i.reload.addr66,
>> ...) inserted after the store, indicating that the variable is located
>> in memory.

I tried multiple approaches to manually inserting an llvm.dbg.addr
after the store instruction, as per your suggestion, Jeremy. I used
llc to compile the IR into an object file that I then linked, and
inspected the DWARF generated for the file. Unfortunately, inserting
dbg.addr that operated on the reloaded values didn't lead to any
change in the DWARF that was produced --  specifically, this didn't
make a difference:

call void @llvm.dbg.addr(metadata i32* %i.reload.addr62, metadata
!873, metadata !DIExpression()), !dbg !884

I also tried adding a dbg.addr that attempted to point the debugger to
the %i variable's location at its offset on the coroutine frame:

call void @llvm.dbg.addr(metadata %_Z3foov.Frame* %FramePtr, metadata
!873, metadata !DIExpression(DW_OP_plus, 28)), !dbg !884

This changed the live ranges for %i in the DWARF that was output, but
not in a way that made the %i variable visible to the debugger. Again,
I wonder if maybe the correct path forward here is to, instead of
attempting to expand the live ranges in the DWARF for %i, to instead
signal in the debug info that the value of %i is always available to
read from the 7 offset into the coroutine frame. If this makes sense,
then I need to learn how to convey that via the llvm.dbg intrinsics --
llvm.dbg.addr sounds like what I want, doesn't it?

Again, thanks for all the help on this list. (PS: I've also been
enjoying reading the proposals you sent, Jeremy, for post-ISel debug
info salvaging!) Please let me know if my thinking above sounds right
or misguided in any way -- thanks!

- Brian Gesiak
___
lldb-dev mailing list
lldb-dev@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev


[lldb-dev] What are the 'rules' to play nice with lldb-9?

2020-02-25 Thread Levo DeLellis via lldb-dev
I'm thoroughly confused so I may say incorrect thing. I don't expect any
replies to this entire post but bits would be helpful. I'll double check if
you need me to be specific since it's likely I remember or ran something
wrong. For my language I output llvm-ir directly so I may generate llvm-ir
that the llvm api does not and I may create very specific ir if I need to.

I noticed a number of things. When I declare something with
llvm.dbg.declare it doesn't happen where I declare it but at the start of
the function? I put my alloca's at the start of the function like llvm
recommends so I have invalid pointers and invalid array sizes which causes
vscode to crash. Which is fine I'm sure I can write null and say the size
is 0 before the first line of the function.
I thought maybe I can use llvm.dbg.addr to work around the problem but I
never got it working in the way I hoped (Does it execute at the start of
the function? which explains why my unexpected results). I manage to have
some good results with llvm.dbg.value. I noticed if I put a value in a
local variable and use `llvm.dbg.value(i64 %abc` there's a high likelihood
it will have an incorrect value or will be wrong once I step through more
code. However i64 1234 always seem to work.

How should I tell the debugger about my variables? This page says you are
"transitioning away from" llvm.dbg.declare
https://llvm.org/docs/SourceLevelDebugging.html I see llvm.dbg.addr says to
only use it once and I had some luck with llvm.dbg.value. How do I decide
when to use llvm.dbg.value vs llvm.dbg.addr? May I use llvm.dbg.value on a
variable that I didn't specific with llvm.dbg.addr? (for example a const
value in a variable that has no address)? What about an array passed in
from a function? Do I need to store the pointer and or length to a variable
to give it an address before the debugger can understand it?

Is it possible to say ignore my variable until I hit this specific? My
language uses constructors so I often have to execute code before pointers
become valid. The language also cleans up so on a return statement as a
'hack' I execute `br false, label %dummy123, label %dummy123, !dbg
!123\ndummy123:\n` so the user can see the variables before the cleanup
happens/pointers get freed. I mentioned earlier when using vscode having
invalid array pointer and invalid size (very large number) made vscode
crash. I'm not sure what happened but I had lldb-mi-9 take up many gb
(30gb+) in some situations so it may not be a literal crash in the process
but locks up and do undesirable behavior

I don't expect to get all the answers but maybe a piece here and there will
help. Should I continue to use llvm.dbg.declare for now with lldb 9? or
should I use llvm.dbg.addr and llvm.dbg.value? Should I always initialize
my variables to 0? (so I don't crash vscode when it uses lldb-mi-9) Is
there a way I can say ignore this variable until I hit line X where I know
the memory will be initialized fully? Do I need to worry about the order I
initialize variables or the order I call llvm.dbg.addr? (I remember, call
llvm.dbg.addr once per variable)

Thank you for reading and thank you for any help
___
lldb-dev mailing list
lldb-dev@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev