[Lldb-commits] [lldb] 47f79c6 - [lldb] Add --stack option to `target symbols add` command
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Tue Sep 21 23:08:21 PDT 2021
Author: Jonas Devlieghere
Date: 2021-09-21T23:08:14-07:00
New Revision: 47f79c6057764e0c83016269ae2359f8c5c8d135
URL: https://github.com/llvm/llvm-project/commit/47f79c6057764e0c83016269ae2359f8c5c8d135
DIFF: https://github.com/llvm/llvm-project/commit/47f79c6057764e0c83016269ae2359f8c5c8d135.diff
LOG: [lldb] Add --stack option to `target symbols add` command
Currently you can ask the target symbols add command to locate the debug
symbols for the current frame. This patch add an options to do that for
the whole call stack.
Differential revision: https://reviews.llvm.org/D110011
Added:
lldb/test/API/macosx/add-dsym/TestAddDsymDownload.py
Modified:
lldb/source/Commands/CommandObjectTarget.cpp
Removed:
################################################################################
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 92aa8fc70a7bb..439ac45bfbec5 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -3962,8 +3962,12 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
"name."),
m_current_frame_option(
LLDB_OPT_SET_2, false, "frame", 'F',
- "Locate the debug symbols for the currently selected frame.",
- false, true)
+ "Locate the debug symbols for the currently selected frame.", false,
+ true),
+ m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
+ "Locate the debug symbols for every frame in "
+ "the current call stack.",
+ false, true)
{
m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
@@ -3971,6 +3975,8 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
LLDB_OPT_SET_2);
+ m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,
+ LLDB_OPT_SET_2);
m_option_group.Finalize();
}
@@ -4247,6 +4253,63 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
return true;
}
+ bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
+ assert(m_current_stack_option.GetOptionValue().OptionWasSet());
+
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (!process) {
+ result.AppendError(
+ "a process must exist in order to use the --stack option");
+ return false;
+ }
+
+ const StateType process_state = process->GetState();
+ if (!StateIsStoppedState(process_state, true)) {
+ result.AppendErrorWithFormat("process is not stopped: %s",
+ StateAsCString(process_state));
+ return false;
+ }
+
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (!thread) {
+ result.AppendError("invalid current thread");
+ return false;
+ }
+
+ bool symbols_found = false;
+ uint32_t frame_count = thread->GetStackFrameCount();
+ for (uint32_t i = 0; i < frame_count; ++i) {
+ lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
+
+ ModuleSP frame_module_sp(
+ frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
+ if (!frame_module_sp)
+ continue;
+
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = frame_module_sp->GetUUID();
+
+ if (FileSystem::Instance().Exists(
+ frame_module_sp->GetPlatformFileSpec())) {
+ module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
+ module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
+ }
+
+ bool current_frame_flush = false;
+ if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
+ symbols_found = true;
+ flush |= current_frame_flush;
+ }
+
+ if (!symbols_found) {
+ result.AppendError(
+ "unable to find debug symbols in the current call stack");
+ return false;
+ }
+
+ return true;
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
Target *target = m_exe_ctx.GetTargetPtr();
result.SetStatus(eReturnStatusFailed);
@@ -4257,6 +4320,8 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
const bool frame_option_set =
m_current_frame_option.GetOptionValue().OptionWasSet();
+ const bool stack_option_set =
+ m_current_stack_option.GetOptionValue().OptionWasSet();
const size_t argc = args.GetArgumentCount();
if (argc == 0) {
@@ -4266,6 +4331,8 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
AddSymbolsForFile(result, flush);
else if (frame_option_set)
AddSymbolsForFrame(result, flush);
+ else if (stack_option_set)
+ AddSymbolsForStack(result, flush);
else
result.AppendError("one or more symbol file paths must be specified, "
"or options must be specified");
@@ -4335,6 +4402,7 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
OptionGroupUUID m_uuid_option_group;
OptionGroupFile m_file_option;
OptionGroupBoolean m_current_frame_option;
+ OptionGroupBoolean m_current_stack_option;
};
#pragma mark CommandObjectTargetSymbols
diff --git a/lldb/test/API/macosx/add-dsym/TestAddDsymDownload.py b/lldb/test/API/macosx/add-dsym/TestAddDsymDownload.py
new file mode 100644
index 0000000000000..c83d923b3e387
--- /dev/null
+++ b/lldb/test/API/macosx/add-dsym/TestAddDsymDownload.py
@@ -0,0 +1,98 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+ at skipUnlessDarwin
+class AddDsymDownload(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+ dwarfdump_uuid_regex = re.compile('UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
+
+ def get_uuid(self):
+ dwarfdump_cmd_output = subprocess.check_output(
+ ('/usr/bin/dwarfdump --uuid "%s"' % self.exe),
+ shell=True).decode("utf-8")
+ for line in dwarfdump_cmd_output.splitlines():
+ match = self.dwarfdump_uuid_regex.search(line)
+ if match:
+ return match.group(1)
+ return None
+
+ def create_dsym_for_uuid(self):
+ shell_cmds = [
+ '#! /bin/sh', '# the last argument is the uuid',
+ 'while [ $# -gt 1 ]', 'do', ' shift', 'done', 'ret=0',
+ 'echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>"',
+ 'echo "<!DOCTYPE plist PUBLIC \\"-//Apple//DTD PLIST 1.0//EN\\" \\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\">"',
+ 'echo "<plist version=\\"1.0\\">"', '',
+ 'if [ "$1" != "%s" ]' % (self.uuid), 'then',
+ ' echo "<key>DBGError</key><string>not found</string>"',
+ ' echo "</plist>"', ' exit 1', 'fi',
+ ' uuid=%s' % self.uuid,
+ ' bin=%s' % self.exe,
+ ' dsym=%s' % self.dsym, 'echo "<dict><key>$uuid</key><dict>"', '',
+ 'echo "<key>DBGDSYMPath</key><string>$dsym</string>"',
+ 'echo "<key>DBGSymbolRichExecutable</key><string>$bin</string>"',
+ 'echo "</dict></dict></plist>"', 'exit $ret'
+ ]
+
+ with open(self.dsym_for_uuid, "w") as writer:
+ for l in shell_cmds:
+ writer.write(l + '\n')
+
+ os.chmod(self.dsym_for_uuid, 0o755)
+
+ def setUp(self):
+ TestBase.setUp(self)
+ self.source = 'main.c'
+ self.exe = self.getBuildArtifact("a.out")
+ self.dsym = os.path.join(
+ self.getBuildDir(),
+ "hide.app/Contents/a.out.dSYM/Contents/Resources/DWARF/",
+ os.path.basename(self.exe))
+ self.dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")
+
+ self.buildDefault(dictionary={'MAKE_DSYM': 'YES'})
+ self.assertTrue(os.path.exists(self.exe))
+ self.assertTrue(os.path.exists(self.dsym))
+
+ self.uuid = self.get_uuid()
+ self.assertNotEqual(self.uuid, None, "Could not get uuid for a.out")
+
+ self.create_dsym_for_uuid()
+
+ os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = self.dsym_for_uuid
+ self.addTearDownHook(
+ lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None))
+
+ def do_test(self, command):
+ self.target = self.dbg.CreateTarget(self.exe)
+ self.assertTrue(self.target, VALID_TARGET)
+
+ main_bp = self.target.BreakpointCreateByName("main", "a.out")
+ self.assertTrue(main_bp, VALID_BREAKPOINT)
+
+ self.process = self.target.LaunchSimple(
+ None, None, self.get_process_working_directory())
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ self.assertEquals(self.process.GetState(), lldb.eStateStopped,
+ STOPPED_DUE_TO_BREAKPOINT)
+
+ self.runCmd(command)
+ self.expect("frame select", substrs=['a.out`main at main.c'])
+
+ @no_debug_info_test
+ def test_frame(self):
+ self.do_test("add-dsym --frame")
+
+ @no_debug_info_test
+ def test_uuid(self):
+ self.do_test("add-dsym --uuid {}".format(self.uuid))
+
+ @no_debug_info_test
+ def test_stack(self):
+ self.do_test("add-dsym --stack")
More information about the lldb-commits
mailing list