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

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

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.

These are really LLVM questions. Basically:

- if you can see the variable with dwarfdump and it doesn't show up in LLDB, you should ask on lldb-dev
- if you can't see the variable with dwarfdump, you should ask on llvm-dev

A golden rule of thumb is to look at what clang is doing and copy that.

The location of a dbg.declare is mostly irrelevant, since there can only be one dbg.declare per variable and it is valid throughout the entire scope.

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 don't understand the question here. It would be helpful to post a minimal example, and look at the output of -print-after-all to see how it is transformed by the various passes, so you can ask a more directed question.

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?

If your variables "live" on the stack, such as in clang -O0 code, you should use one dbg.declare per variable. Otherwise you'll need at least one dbg.value per SSA value that carries a variable value.

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.

Yes, dbg.value(undef, ...) followed by another dbg.value will do that explicitly.

You can not achieve this with dbg.declare because it is global.

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?

Depends on the kind of code you generate.

Thanks this has been very helpful