Is 'frame diagnose' used/maintained?

In D143463 I’m changing the DWARF frame base expression to be based on the Canonical Frame Address, to fix cases where the variable locations emitted by LLVM are currently incorrect when the stack pointer changes inside a function body. This is blocked from landing because it makes the frame diagnose tests fail, since the frame diagnose command isn’t capable of handling a CFA-based DW_AT_frame_base expression.

Is frame diagnose actually being used by anyone? Is anyone maintaining it? The code doesn’t seem to have been meaningfully modified since the feature was first landed in 2016. Searching the internet for anyone talking about this command only turns up a few results on LLVM mailing lists. And gcc has been producing code that uses the CFA as the frame base since 2009, so this feature is definitely not portable.

I’m not aware of anyone using frame diagnose nor have I seen any bug reports in recent years. Removing it has come up a few times but we didn’t really have a motivation to do so and didn’t want to break anyone that might be using it.

I wouldn’t go out of my way to support it and I’m fine with removing it, unless someone steps up and says otherwise.

It’s a tricky one, for sure. It was a prototype that Sean did in 2006 in this commit,

commit 4740a734bb4a4f20ae4895ded32585e54bb87afb
Author: Sean Callanan <>
Date:   Tue Sep 6 04:48:36 2016 +0000

    Added the "frame diagnose" command and use its output to make crash info better.

there are some hints for making it work with aarch64 disassembler, but Sean was mostly building the prototype on x86_64.

It’s a pretty great idea: if you crash with an access to unmapped memory, looking at the faulting instruction’s operands to find the register being used to access that memory, and tracing it back through earlier instructions in this basic block to eventually find a user-visible variable via the debug info. They might have a variable that points to an object F and one of the members in F is a pointer p to a memory address. If that address is invalid, the instruction that we faulted at has a register that doesn’t correspond to any debug information, but if we look at earlier instructions we’ll see a register with the value of F, that register has an offset added to it to get the ivar p and that’s the register accessed. When the debugger describes the faulting access to the user, it’s possible to say that this was *F->p. This is simple for a person to do if they’re familiar with assembly language and debug info, but basically no one is.

I do have to agree with the original point though, I don’t think it was ever refined beyond this initial prototype, it has not been exercised especially outside of x86_64 target. It’s an idea that would be valuable to users but it really needs a champion to pick up the idea and move it forward before it will be useful in general. Even if the existing implementation is removed at this point, I do hope we come back to this in the future and try it again with a bit more time put into completing the idea. It’s a pretty great idea.

1 Like

On macOS, we include the crash metadata in the process status --verbose dump. You can also get it from the SBAPI using SBProcess.GetExtendedCrashInformation.

On macOS, we include the crash metadata in the process status --verbose dump. You can also get it from the SBAPI using SBProcess.GetExtendedCrashInformation.

I don’t know what that means. Does the output of frame diagnose end up in “the crash metadata” somehow?

Note, the initial implementation was pretty decently factored so adding other architectures wouldn’t be hard, and could be the backing for more general “what is the current instruction doing” type inquiries, which would also be valuable. It also has a bunch of tests, though those are x86_64 only because there’s no other backends.

The existing implementation is largely architecture agnostic but it is very tightly coupled to the form of the DWARF the compiler emits which is the source of the current problem.

Ultimately it turned out there is at least one other lldb feature that doesn’t handle DW_OP_call_frame_cfa so I restricted my change to cases where it’s necessary to fix correctness (i.e. the debugger was already broken before the change).