diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -2839,9 +2839,15 @@ StartHandlingCommand(); - OverrideExecutionContext(m_debugger.GetSelectedExecutionContext()); - auto finalize = llvm::make_scope_exit([this]() { - RestoreExecutionContext(); + ExecutionContext exe_ctx = m_debugger.GetSelectedExecutionContext(); + bool pushed_exe_ctx = false; + if (exe_ctx.HasTargetScope()) { + OverrideExecutionContext(exe_ctx); + pushed_exe_ctx = true; + } + auto finalize = llvm::make_scope_exit([this, pushed_exe_ctx]() { + if (pushed_exe_ctx) + RestoreExecutionContext(); }); lldb_private::CommandReturnObject result(m_debugger.GetUseColor()); diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -7013,7 +7013,7 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) { MachOCorefileAllImageInfos image_infos = GetCorefileAllImageInfos(); - bool added_images = false; + ModuleList added_modules; if (image_infos.IsValid()) { for (const MachOCorefileImageEntry &image : image_infos.all_image_infos) { ModuleSpec module_spec; @@ -7035,7 +7035,7 @@ } } if (module_sp.get()) { - added_images = true; + added_modules.Append(module_sp); for (auto name_vmaddr_tuple : image.segment_load_addresses) { SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList(); if (sectlist) { @@ -7050,5 +7050,6 @@ } } } - return added_images; + process.GetTarget().ModulesDidLoad(added_modules); + return added_modules.GetSize() > 0; } diff --git a/lldb/test/API/macosx/dsym-script-settings-corefile/Makefile b/lldb/test/API/macosx/dsym-script-settings-corefile/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/macosx/dsym-script-settings-corefile/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/macosx/dsym-script-settings-corefile/TestdSYMScriptSettingsCorefile.py b/lldb/test/API/macosx/dsym-script-settings-corefile/TestdSYMScriptSettingsCorefile.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/macosx/dsym-script-settings-corefile/TestdSYMScriptSettingsCorefile.py @@ -0,0 +1,95 @@ +"""Test that settings in dSYM Python scripts are registered when read from corefile.""" + +import os +import re +import subprocess +import shutil + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestdSYMScriptSettingsCorefile(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @no_debug_info_test + @skipUnlessDarwin + @skipIfOutOfTreeDebugserver # newer debugserver required for these qMemoryRegionInfo types + def test(self): + self.build() + exe = self.getBuildArtifact("a.out") + dsym = self.getBuildArtifact("a.out.dSYM") + python_resources_dir = os.path.join(dsym, "Contents", "Resources", "Python") + python_file = os.path.join(self.getSourceDir(), "a_out.py") + osplugin_python_file = os.path.join(self.getSourceDir(), "operating_system.py") + lldbutil.mkdir_p(python_resources_dir) + shutil.copyfile(python_file, os.path.join(python_resources_dir, "a_out.py")) + shutil.copyfile(osplugin_python_file, os.path.join(python_resources_dir, "operating_system.py")) + + corefile = self.getBuildArtifact("process.core") + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "// break here", lldb.SBFileSpec("main.c")) + + self.runCmd("process save-core -s stack " + corefile) + + ci = self.dbg.GetCommandInterpreter() + + result = lldb.SBCommandReturnObject() + ci.HandleCommand("settings show target.process.memory-cache-line-size", result) + init_value_memory_cache_line = re.search(" = ([0-9]+)\s*$", result.GetOutput()).group(1) + self.assertEqual(init_value_memory_cache_line, "512") + + result = lldb.SBCommandReturnObject() + ci.HandleCommand("settings show target.default-arch", result) + self.assertEqual(re.search(" = (.+)\s*$", result.GetOutput()), None) + + result = lldb.SBCommandReturnObject() + ci.HandleCommand("settings show target.prefer-dynamic-value", result) + init_value_prefer_dynamic_value = re.search(" = (.+)\s*$", result.GetOutput()).group(1) + # command driver lldb will have no-run-target; + # SB API test will have no-dynamic-values. + # the custom python sets it to run-target, so just check that + # it's not equal to that. + self.assertNotEqual(init_value_prefer_dynamic_value, "run-target") + + process.Kill() + self.dbg.DeleteTarget(target) + + + self.runCmd("settings set target.load-script-from-symbol-file true", check=False) + def cleanup(): + self.runCmd("settings set target.load-script-from-symbol-file false", check=False) + self.runCmd("settings set target.process.memory-cache-line-size " + init_value_memory_cache_line) + self.runCmd("settings clear target.default-arch") + self.runCmd("settings set target.prefer-dynamic-value " + init_value_prefer_dynamic_value) + self.runCmd("settings clear target.process.python-os-plugin-path") + self.addTearDownHook(cleanup) + + if self.TraceOn(): + self.runCmd("settings show target.process.memory-cache-line-size target.default-arch target.prefer-dynamic-value target.process.python-os-plugin-path") + + # Now load the corefile + target = self.dbg.CreateTarget('') + process = target.LoadCore(corefile) + + result = lldb.SBCommandReturnObject() + ci.HandleCommand("settings show target.process.memory-cache-line-size", result) + new_init_value_memory_cache_line = re.search(" = ([0-9]+)\s*$", result.GetOutput()).group(1) + self.assertEqual(new_init_value_memory_cache_line, "16") + + result = lldb.SBCommandReturnObject() + ci.HandleCommand("settings show target.default-arch", result) + new_default_arch = re.search(" = (.+)\s*$", result.GetOutput()).group(1) + self.assertEqual(new_default_arch, "x86_64") + + result = lldb.SBCommandReturnObject() + ci.HandleCommand("settings show target.prefer-dynamic-value", result) + new_prefer_dynamic_value = re.search(" = (.+)\s*$", result.GetOutput()).group(1) + self.assertEqual(new_prefer_dynamic_value, "run-target") + + if self.TraceOn(): + self.runCmd("settings show target.process.memory-cache-line-size target.default-arch target.prefer-dynamic-value target.process.python-os-plugin-path") + self.runCmd("thread list") + diff --git a/lldb/test/API/macosx/dsym-script-settings-corefile/a_out.py b/lldb/test/API/macosx/dsym-script-settings-corefile/a_out.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/macosx/dsym-script-settings-corefile/a_out.py @@ -0,0 +1,34 @@ +def __lldb_init_module(debugger, internal_dict): + print("") + print("") + # Process settings will be set in the template + set1 = "settings set target.process.memory-cache-line-size 16" + print("Process setting:") + print(set1) + debugger.HandleCommand(set1) + + # Global target settings will be set in the template + set2 = "sett set target.default-arch x86_64" + print("") + print("Global target setting:") + print(set2) + debugger.HandleCommand(set2) + + # Target specific settings need a Target to set in + set3 = "settings set target.prefer-dynamic-value run-target" + print("") + print("Target specific setting:") + print(set3) + debugger.HandleCommand(set3) + + self_path = "{}".format(__file__) + base_dir_name = self_path[:self_path.rfind("/")] + os_plugin = base_dir_name + "/operating_system.py" + set4 = "settings set target.process.python-os-plugin-path \"%s\"" % os_plugin + print("") + print("OS Plugin setting:") + print(set4) + debugger.HandleCommand(set4) + + print("") + print("") diff --git a/lldb/test/API/macosx/dsym-script-settings-corefile/main.c b/lldb/test/API/macosx/dsym-script-settings-corefile/main.c new file mode 100644 --- /dev/null +++ b/lldb/test/API/macosx/dsym-script-settings-corefile/main.c @@ -0,0 +1,4 @@ +#include +int main() { + puts ("HI corefile"); // break here +} diff --git a/lldb/test/API/macosx/dsym-script-settings-corefile/operating_system.py b/lldb/test/API/macosx/dsym-script-settings-corefile/operating_system.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/macosx/dsym-script-settings-corefile/operating_system.py @@ -0,0 +1,45 @@ +import lldb + + +class OperatingSystemPlugIn(object): + """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class""" + + def __init__(self, process): + '''Initialization needs a valid.SBProcess object. + + This plug-in will get created after a live process is valid and has stopped for the first time. + ''' + self.process = None + self.registers = None + self.threads = None + if isinstance(process, lldb.SBProcess) and process.IsValid(): + self.process = process + self.threads = None # Will be an dictionary containing info for each thread + + def get_target(self): + return self.process.target + + def get_thread_info(self): + if not self.threads: + # FIXME: LLDB is not actually parsing thread stop reasons. + self.threads = [{ + 'tid': 0x111111111, + 'name': 'one', + 'queue': 'queue1', + 'state': 'stopped', + 'stop_reason': 'not parsed' + }, { + 'tid': 0x222222222, + 'name': 'two', + 'queue': 'queue2', + 'state': 'stopped', + 'stop_reason': 'not parsed' + }, { + 'tid': 0x333333333, + 'name': 'three', + 'queue': 'queue3', + 'state': 'stopped', + 'stop_reason': 'not parsed - should be "sigstop" though', + 'core': 0 + }] + return self.threads diff --git a/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/a_out.py b/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/a_out.py new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/a_out.py @@ -0,0 +1,34 @@ +def __lldb_init_module(debugger, internal_dict): + print("") + print("") + # Process settings will be set in the template + set1 = "settings set target.process.memory-cache-line-size 16" + print("Process setting:") + print(set1) + debugger.HandleCommand(set1) + + # Global target settings will be set in the template + set2 = "sett set target.default-arch x86_64" + print("") + print("Global target setting:") + print(set2) + debugger.HandleCommand(set2) + + # Target specific settings need a Target to set in + set3 = "settings set target.prefer-dynamic-value run-target" + print("") + print("Target specific setting:") + print(set3) + debugger.HandleCommand(set3) + + self_path = "{}".format(__file__) + base_dir_name = self_path[:self_path.rfind("/")] + os_plugin = base_dir_name + "/operating_system.py" + set4 = "settings set target.process.python-os-plugin-path \"%s\"" % os_plugin + print("") + print("OS Plugin setting:") + print(set4) + debugger.HandleCommand(set4) + + print("") + print("") diff --git a/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/main.c b/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/main.c new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/main.c @@ -0,0 +1,4 @@ +#include +int main() { + puts ("Hello, corefile"); // break here +} diff --git a/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/operating_system.py b/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/operating_system.py new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/OS/Inputs/operating_system.py @@ -0,0 +1,45 @@ +import lldb + + +class OperatingSystemPlugIn(object): + """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class""" + + def __init__(self, process): + '''Initialization needs a valid.SBProcess object. + + This plug-in will get created after a live process is valid and has stopped for the first time. + ''' + self.process = None + self.registers = None + self.threads = None + if isinstance(process, lldb.SBProcess) and process.IsValid(): + self.process = process + self.threads = None # Will be an dictionary containing info for each thread + + def get_target(self): + return self.process.target + + def get_thread_info(self): + if not self.threads: + # FIXME: LLDB is not actually parsing thread stop reasons. + self.threads = [{ + 'tid': 0x111111111, + 'name': 'one', + 'queue': 'queue1', + 'state': 'stopped', + 'stop_reason': 'not parsed' + }, { + 'tid': 0x222222222, + 'name': 'two', + 'queue': 'queue2', + 'state': 'stopped', + 'stop_reason': 'not parsed' + }, { + 'tid': 0x333333333, + 'name': 'three', + 'queue': 'queue3', + 'state': 'stopped', + 'stop_reason': 'not parsed - should be "sigstop" though', + 'core': 0 + }] + return self.threads diff --git a/lldb/test/Shell/ScriptInterpreter/Python/OS/os.test b/lldb/test/Shell/ScriptInterpreter/Python/OS/os.test new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/OS/os.test @@ -0,0 +1,23 @@ +# REQUIRES: system-darwin + +# RUN: %clang_host %S/Inputs/main.c -g -o %t.out +# RUN: mkdir -p %t.out.dSYM/Contents/Resources/Python +# RUN: cp %S/Inputs/a_out.py %t.out.dSYM/Contents/Resources/Python/os_test_tmp_out.py +# RUN: cp %S/Inputs/operating_system.py %t.out.dSYM/Contents/Resources/Python/ + +# RUN: %lldb -x %t.out \ +# RUN: -o 'br s -p break' \ +# RUN: -o 'r' \ +# RUN: -o 'pro save-core -s stack %t.corefile' \ +# RUN: -o 'pro kill' \ +# RUN: -o 'tar del' \ +# RUN: -o 'settings set target.load-script-from-symbol-file true' \ +# RUN: -o 'tar cr -c %t.corefile' \ +# RUN: -o 'sett show target.process.memory-cache-line-size target.default-arch target.prefer-dynamic-value target.process.python-os-plugin-path' \ +# RUN: -o 'thread list' | FileCheck %s + +# CHECK: target.process.memory-cache-line-size (unsigned) = 16 +# CHECK: target.default-arch (arch) = x86_64 +# CHECK: target.prefer-dynamic-value (enum) = run-target +# CHECK: name = 'one', queue = 'queue1' +# CHECK: name = 'two', queue = 'queue2'