Display PC instead of <unknown> for stack trace in vscode

It isn't useful for users to see "<unknown>" as a stack trace when lldb fails to symbolicate a stack frame. I've replaced "<unknown>" with the value of the program counter instead.

Test Plan:

To test this, I opened a target that lldb fails to symbolicate in
VSCode, and observed in the CALL STACK section that instead of being
shown as "<unknown>", those stack frames are represented by their
program counters.

I added a new test case, `TestVSCode_stackTraceMissingFunctionName` that
exercises this feature.

I also ran `lldb-dotest -p TestVSCode` and saw that the tests passed.

Differential Revision: https://reviews.llvm.org/D156732
This commit is contained in:
Tom Yang 2023-08-01 10:36:09 -07:00
parent cd29ebb862
commit 786bab4334
4 changed files with 40 additions and 2 deletions

View File

@ -0,0 +1,2 @@
CXX_SOURCES := main.cpp
include Makefile.rules

View File

@ -0,0 +1,26 @@
"""
Test lldb-vscode stack trace response
"""
import vscode
from lldbsuite.test.decorators import *
import os
import lldbvscode_testcase
from lldbsuite.test import lldbtest, lldbutil
class TestVSCode_stackTraceMissingFunctionName(lldbvscode_testcase.VSCodeTestCaseBase):
@skipIfWindows
@skipIfRemote
def test_missingFunctionName(self):
"""
Test that the stack frame without a function name is given its pc in the response.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
self.continue_to_next_stop()
frame_without_function_name = self.get_stackFrames()[0]
self.assertEquals(frame_without_function_name["name"], "0x0000000000000000")

View File

@ -0,0 +1,6 @@
int main() {
typedef void (*FooCallback)();
FooCallback foo_callback = (FooCallback)0;
foo_callback(); // Crash at zero!
return 0;
}

View File

@ -701,8 +701,12 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
const char *function_name = frame.GetDisplayFunctionName();
std::string frame_name =
function_name == nullptr ? std::string() : function_name;
if (frame_name.empty())
frame_name = "<unknown>";
if (frame_name.empty()) {
// If the function name is unavailable, display the pc address as a 16-digit
// hex string, e.g. "0x0000000000012345"
llvm::raw_string_ostream os(frame_name);
os << llvm::format_hex(frame.GetPC(), 18);
}
bool is_optimized = frame.GetFunction().GetIsOptimized();
if (is_optimized)
frame_name += " [opt]";