mib updated this revision to Diff 412923.
mib added a comment.
Re-format
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D120969/new/
https://reviews.llvm.org/D120969
Files:
lldb/examples/python/scripted_process/scripted_process.py
lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
lldb/source/Plugins/Process/scripted/ScriptedProcess.h
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
lldb/test/API/functionalities/scripted_process/Makefile
lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
lldb/test/API/functionalities/scripted_process/baz.c
lldb/test/API/functionalities/scripted_process/baz.h
lldb/test/API/functionalities/scripted_process/main.cpp
lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py
Index: lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py
===================================================================
--- lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py
+++ lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py
@@ -10,10 +10,10 @@
def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
super().__init__(target, args)
- self.backing_target_idx = args.GetValueForKey("backing_target_idx")
-
self.corefile_target = None
self.corefile_process = None
+
+ self.backing_target_idx = args.GetValueForKey("backing_target_idx")
if (self.backing_target_idx and self.backing_target_idx.IsValid()):
if self.backing_target_idx.GetType() == lldb.eStructuredDataTypeInteger:
idx = self.backing_target_idx.GetIntegerValue(42)
@@ -30,9 +30,22 @@
self.threads[corefile_thread.GetThreadID()] = StackCoreScriptedThread(self, structured_data)
- if len(self.threads) == 3:
+ if len(self.threads) == 2:
self.threads[len(self.threads) - 1].is_stopped = True
+ lib_path = args.GetValueForKey("libbaz_path")
+ if not (lib_path and lib_path.IsValid()) \
+ or lib_path.GetType() != lldb.eStructuredDataTypeString:
+ return
+
+ self.lib_path = lib_path.GetStringValue(256)
+ if not os.path.exists(self.lib_path):
+ return
+
+ lib_load_addr = 0x00000001001e0000
+ self.loaded_images.append({"path": self.lib_path,
+ "load_addr": lib_load_addr})
+
def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
mem_region = lldb.SBMemoryRegionInfo()
error = self.corefile_process.GetMemoryRegionInfo(addr, mem_region)
Index: lldb/test/API/functionalities/scripted_process/main.cpp
===================================================================
--- lldb/test/API/functionalities/scripted_process/main.cpp
+++ lldb/test/API/functionalities/scripted_process/main.cpp
@@ -2,16 +2,20 @@
#include <mutex>
#include <thread>
+extern "C" {
+int baz(int);
+}
+
int bar(int i) {
int j = i * i;
- return j; // break here
+ return j;
}
int foo(int i) { return bar(i); }
void call_and_wait(int &n) {
std::cout << "waiting for computation!" << std::endl;
- while (n != 42 * 42)
+ while (baz(n) != 42)
;
std::cout << "finished computation!" << std::endl;
}
Index: lldb/test/API/functionalities/scripted_process/baz.h
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/scripted_process/baz.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int baz(int j);
Index: lldb/test/API/functionalities/scripted_process/baz.c
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/scripted_process/baz.c
@@ -0,0 +1,8 @@
+#include "baz.h"
+
+#include <math.h>
+
+int baz(int j) {
+ int k = sqrt(j);
+ return k; // break here
+}
Index: lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
===================================================================
--- lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
+++ lldb/test/API/functionalities/scripted_process/TestStackCoreScriptedProcess.py
@@ -25,13 +25,19 @@
def create_stack_skinny_corefile(self, file):
self.build()
target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, "// break here",
- lldb.SBFileSpec("main.cpp"))
+ lldb.SBFileSpec("baz.c"))
self.assertTrue(process.IsValid(), "Process is invalid.")
# FIXME: Use SBAPI to save the process corefile.
self.runCmd("process save-core -s stack " + file)
self.assertTrue(os.path.exists(file), "No stack-only corefile found.")
self.assertTrue(self.dbg.DeleteTarget(target), "Couldn't delete target")
+ def get_module_named(self, target, name):
+ for module in target.modules:
+ if name in module.GetFileSpec().GetFilename():
+ return module
+ return None
+
@skipUnlessDarwin
@skipIfOutOfTreeDebugserver
def test_launch_scripted_process_stack_frames(self):
@@ -41,15 +47,15 @@
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
self.assertTrue(target, VALID_TARGET)
- for module in target.modules:
- if 'a.out' in module.GetFileSpec().GetFilename():
- main_module = module
- break
-
+ main_module = self.get_module_named(target, 'a.out')
self.assertTrue(main_module, "Invalid main module.")
error = target.SetModuleLoadAddress(main_module, 0)
self.assertSuccess(error, "Reloading main module at offset 0 failed.")
+ scripted_dylib = self.get_module_named(target, 'libbaz.dylib')
+ self.assertTrue(scripted_dylib, "Dynamic library libbaz.dylib not found.")
+ self.assertEqual(scripted_dylib.GetObjectFileHeaderAddress().GetLoadAddress(target), 0xffffffffffffffff)
+
os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1'
def cleanup():
del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"]
@@ -68,7 +74,8 @@
structured_data = lldb.SBStructuredData()
structured_data.SetFromJSON(json.dumps({
- "backing_target_idx" : self.dbg.GetIndexOfTarget(corefile_process.GetTarget())
+ "backing_target_idx" : self.dbg.GetIndexOfTarget(corefile_process.GetTarget()),
+ "libbaz_path" : self.getBuildArtifact("libbaz.dylib")
}))
launch_info = lldb.SBLaunchInfo(None)
launch_info.SetProcessPluginName("ScriptedProcess")
@@ -81,10 +88,10 @@
self.assertTrue(process, PROCESS_IS_VALID)
self.assertEqual(process.GetProcessID(), 42)
- self.assertEqual(process.GetNumThreads(), 3)
+ self.assertEqual(process.GetNumThreads(), 2)
thread = process.GetSelectedThread()
self.assertTrue(thread, "Invalid thread.")
- self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-2")
+ self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-1")
self.assertTrue(target.triple, "Invalid target triple")
arch = target.triple.split('-')[0]
@@ -102,9 +109,17 @@
else:
self.assertTrue(thread.GetStopReason(), lldb.eStopReasonSignal)
- self.assertEqual(thread.GetNumFrames(), 6)
+ self.assertEqual(thread.GetNumFrames(), 5)
frame = thread.GetSelectedFrame()
self.assertTrue(frame, "Invalid frame.")
- self.assertIn("bar", frame.GetFunctionName())
- self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
- self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
+ func = frame.GetFunction()
+ self.assertTrue(func, "Invalid function.")
+
+ self.assertIn("baz", frame.GetFunctionName())
+ self.assertEqual(frame.vars.GetSize(), 2)
+ self.assertEqual(int(frame.vars.GetFirstValueByName('j').GetValue()), 42 * 42)
+ self.assertEqual(int(frame.vars.GetFirstValueByName('k').GetValue()), 42)
+
+ scripted_dylib = self.get_module_named(target, 'libbaz.dylib')
+ self.assertTrue(scripted_dylib, "Dynamic library libbaz.dylib not found.")
+ self.assertEqual(scripted_dylib.GetObjectFileHeaderAddress().GetLoadAddress(target), 0x1001e0000)
Index: lldb/test/API/functionalities/scripted_process/Makefile
===================================================================
--- lldb/test/API/functionalities/scripted_process/Makefile
+++ lldb/test/API/functionalities/scripted_process/Makefile
@@ -1,4 +1,13 @@
CXX_SOURCES := main.cpp
ENABLE_THREADS := YES
-include Makefile.rules
+LD_EXTRAS := -L. -lbaz -I.
+
+override ARCH := $(shell uname -m)
+
+all: libbaz.dylib a.out
+libbaz.dylib: baz.c
+ $(MAKE) -f $(MAKEFILE_RULES) ARCH=$(ARCH) \
+ DYLIB_ONLY=YES DYLIB_NAME=baz DYLIB_C_SOURCES=baz.c
+
+include Makefile.rules
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -49,7 +49,7 @@
lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size,
Status &error) override;
- StructuredData::DictionarySP GetLoadedImages() override;
+ StructuredData::ArraySP GetLoadedImages() override;
lldb::pid_t GetProcessID() override;
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -124,9 +124,21 @@
address, size);
}
-StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
- // TODO: Implement
- return {};
+StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
+ Status error;
+ StructuredData::ArraySP array =
+ Dispatch<StructuredData::ArraySP>("get_loaded_images", error);
+
+ if (!array || !array->IsValid() || error.Fail()) {
+ return ScriptedInterface::ErrorWithMessage<StructuredData::ArraySP>(
+ LLVM_PRETTY_FUNCTION,
+ llvm::Twine("Null or invalid object (" +
+ llvm::Twine(error.AsCString()) + llvm::Twine(")."))
+ .str(),
+ error);
+ }
+
+ return array;
}
lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.h
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -89,6 +89,9 @@
bool GetProcessInfo(ProcessInstanceInfo &info) override;
+ lldb_private::StructuredData::ObjectSP
+ GetLoadedDynamicLibrariesInfos() override;
+
protected:
Status DoStop();
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -170,6 +170,7 @@
void ScriptedProcess::DidLaunch() {
CheckInterpreterAndScriptObject();
m_pid = GetInterface().GetProcessID();
+ GetLoadedDynamicLibrariesInfos();
}
Status ScriptedProcess::DoResume() {
@@ -378,6 +379,93 @@
return true;
}
+lldb_private::StructuredData::ObjectSP
+ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
+ CheckInterpreterAndScriptObject();
+
+ Status error;
+ auto error_with_message = [&error](llvm::StringRef message) {
+ return ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION,
+ message.data(), error);
+ };
+
+ StructuredData::ArraySP loaded_images_sp = GetInterface().GetLoadedImages();
+
+ if (!loaded_images_sp || !loaded_images_sp->GetSize())
+ return GetInterface().ErrorWithMessage<StructuredData::ObjectSP>(
+ LLVM_PRETTY_FUNCTION, "No loaded images.", error);
+
+ ModuleList module_list;
+ Target &target = GetTarget();
+
+ auto reload_image = [&target, &module_list, &error_with_message](
+ StructuredData::Object *obj) -> bool {
+ StructuredData::Dictionary *dict = obj->GetAsDictionary();
+
+ if (!dict)
+ return error_with_message("Couldn't cast image object into dictionary.");
+
+ ModuleSpec module_spec;
+ llvm::StringRef value;
+
+ bool has_path = dict->HasKey("path");
+ bool has_uuid = dict->HasKey("uuid");
+ if (!has_path && !has_uuid)
+ return error_with_message("Dictionary should have key 'path' or 'uuid'");
+ if (!dict->HasKey("load_addr"))
+ return error_with_message("Dictionary is missing field 'load_addr'");
+
+ if (has_path) {
+ dict->GetValueForKeyAsString("path", value);
+ module_spec.GetFileSpec().SetPath(value);
+ }
+
+ if (has_uuid) {
+ dict->GetValueForKeyAsString("uuid", value);
+ module_spec.GetUUID().SetFromStringRef(value);
+ }
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ ModuleSP module_sp =
+ target.GetOrCreateModule(module_spec, true /* notify */);
+
+ if (!module_sp)
+ return error_with_message("Couldn't create or get module.");
+
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ lldb::addr_t slide = LLDB_INVALID_OFFSET;
+ dict->GetValueForKeyAsInteger("load_addr", load_addr);
+ dict->GetValueForKeyAsInteger("slide", slide);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return error_with_message(
+ "Couldn't get valid load address or slide offset.");
+
+ if (slide != LLDB_INVALID_OFFSET)
+ load_addr += slide;
+
+ bool changed = false;
+ module_sp->SetLoadAddress(target, load_addr, false /*=value_is_offset*/,
+ changed);
+
+ if (!changed && !module_sp->GetObjectFile())
+ return error_with_message("Couldn't set the load address for module.");
+
+ dict->GetValueForKeyAsString("path", value);
+ FileSpec objfile(value);
+ module_sp->SetFileSpecAndObjectName(objfile, objfile.GetFilename());
+
+ return module_list.AppendIfNeeded(module_sp);
+ };
+
+ if (!loaded_images_sp->ForEach(reload_image))
+ return GetInterface().ErrorWithMessage<StructuredData::ObjectSP>(
+ LLVM_PRETTY_FUNCTION, "Couldn't reload all images.", error);
+
+ target.ModulesDidLoad(module_list);
+
+ return loaded_images_sp;
+}
+
ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
return m_interpreter->GetScriptedProcessInterface();
}
Index: lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
+++ lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
@@ -57,7 +57,7 @@
return nullptr;
}
- virtual StructuredData::DictionarySP GetLoadedImages() { return nullptr; }
+ virtual StructuredData::ArraySP GetLoadedImages() { return nullptr; }
virtual lldb::pid_t GetProcessID() { return LLDB_INVALID_PROCESS_ID; }
Index: lldb/examples/python/scripted_process/scripted_process.py
===================================================================
--- lldb/examples/python/scripted_process/scripted_process.py
+++ lldb/examples/python/scripted_process/scripted_process.py
@@ -19,7 +19,7 @@
memory_regions = None
stack_memory_dump = None
loaded_images = None
- threads = {}
+ threads = None
@abstractmethod
def __init__(self, target, args):
@@ -41,6 +41,8 @@
self.dbg = target.GetDebugger()
if isinstance(args, lldb.SBStructuredData) and args.IsValid():
self.args = args
+ self.threads = {}
+ self.loaded_images = []
@abstractmethod
def get_memory_region_containing_address(self, addr):
@@ -116,8 +118,7 @@
```
class ScriptedProcessImage:
- def __init__(name, file_spec, uuid, load_address):
- self.name = name
+ def __init__(file_spec, uuid, load_address):
self.file_spec = file_spec
self.uuid = uuid
self.load_address = load_address
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits