[Lldb-commits] [lldb] [lldb-dap] Add: show return value on step out (PR #106907)

via lldb-commits lldb-commits at lists.llvm.org
Thu Feb 13 09:22:02 PST 2025


================
@@ -663,6 +663,41 @@ def do_test_indexedVariables(self, enableSyntheticChildDebugging: bool):
         ]["variables"]
         self.verify_variables(verify_children, children)
 
+    def test_return_variables(self):
----------------
jimingham wrote:

lldb will do almost the right thing if it can't figure out the return value of a function.  The SBValue that SBThread::GetStopReturnValue() returns won't be valid.  I say that's "almost the right thing" because a better return would be a valid SBValue with an error that tells you why we couldn't fetch the return value.

In general, lldb will always be able to get the return value of functions that return their values in registers, since that information has to be available at the moment you step out of the function.  It doesn't matter whether the return is in one or multiple registers, so long as lldb can figure out from the ABI and the return type that it is returned in one or more registers, the information is available for lldb to figure out the value.

For return values that are bigger than will fit in registers for that ABI, the function gets passed the address that the caller expects the return value to be written to.  In the Itanium ABI - which is what for instance x86_64 uses, the ABI mandates that the return address be written back to the "return address register" specifically so that analysis tools like debuggers could reconstruct it.  But for the arm64 ABI someone decided that benefit wasn't worth the extra store & write, so the function is free to reuse that address-passing register.  That means the only way that lldb could reconstruct the return value was if it stopped at the first instruction of the function, wrote down the address passed in, and then it would have it on stepping out.

We've toyed with ideas like: if you put a breakpoint anywhere in function A(), then we'll also put a breakpoint on the start of the function so we can transparently capture this value.  And when we step into a function, we could stop at the first instruction and write down the address as well.  This is probably doable, but no one has done it yet.

What I was mostly saying is if we have one test that tests both in register returns and in memory returns, then we'd have to disable the entire test for ABI's that don't restore the return address.  But if we had one test for in register returns, and one for in memory, we could keep running the first test, and not lose coverage for something that should work.

https://github.com/llvm/llvm-project/pull/106907


More information about the lldb-commits mailing list