mib updated this revision to Diff 376508.
mib added a comment.
Use `ScriptedInterface::ErrorWithMessage` helper function.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D108953/new/
https://reviews.llvm.org/D108953
Files:
lldb/bindings/interface/SBMemoryRegionInfo.i
lldb/bindings/interface/SBMemoryRegionInfoList.i
lldb/bindings/python/python-wrapper.swig
lldb/examples/python/scripted_process/main.stack-dump
lldb/examples/python/scripted_process/my_scripted_process.py
lldb/include/lldb/API/SBMemoryRegionInfo.h
lldb/include/lldb/API/SBMemoryRegionInfoList.h
lldb/include/lldb/Interpreter/ScriptInterpreter.h
lldb/source/API/SBMemoryRegionInfo.cpp
lldb/source/API/SBMemoryRegionInfoList.cpp
lldb/source/Interpreter/ScriptInterpreter.cpp
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
lldb/test/API/functionalities/scripted_process/main.c
lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===================================================================
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -166,6 +166,10 @@
return nullptr;
}
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data) {
+ return nullptr;
+}
+
extern lldb::ValueObjectSP
LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data) {
return nullptr;
Index: lldb/test/API/functionalities/scripted_process/main.c
===================================================================
--- lldb/test/API/functionalities/scripted_process/main.c
+++ lldb/test/API/functionalities/scripted_process/main.c
@@ -1,5 +1,8 @@
-#include <stdlib.h>
-
-int main() {
- return 0; // break here
+int bar(int i) {
+ int j = i * i;
+ return j; // break here
}
+
+int foo(int i) { return bar(i); }
+
+int main() { return foo(42); }
Index: lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py
@@ -0,0 +1,90 @@
+import os,struct, signal
+
+from typing import Any, Dict
+
+import lldb
+from lldb.plugins.scripted_process import ScriptedProcess
+from lldb.plugins.scripted_process import ScriptedThread
+
+class DummyScriptedProcess(ScriptedProcess):
+ def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
+ super().__init__(target, args)
+
+ def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
+ return self.memory_regions[0]
+
+ def get_thread_with_id(self, tid: int):
+ return {}
+
+ def get_registers_for_thread(self, tid: int):
+ return {}
+
+ def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData:
+ data = lldb.SBData().CreateDataFromCString(
+ self.target.GetByteOrder(),
+ self.target.GetCodeByteSize(),
+ "Hello, world!")
+ return data
+
+ def get_loaded_images(self):
+ return self.loaded_images
+
+ def get_process_id(self) -> int:
+ return 42
+
+ def should_stop(self) -> bool:
+ return True
+
+ def is_alive(self) -> bool:
+ return True
+
+ def get_scripted_thread_plugin(self):
+ return DummyScriptedThread.__module__ + "." + DummyScriptedThread.__name__
+
+
+class DummyScriptedThread(ScriptedThread):
+ def __init__(self, target):
+ super().__init__(target)
+
+ def get_thread_id(self) -> int:
+ return 0x19
+
+ def get_name(self) -> str:
+ return DummyScriptedThread.__name__ + ".thread-1"
+
+ def get_state(self) -> int:
+ return lldb.eStateStopped
+
+ def get_stop_reason(self) -> Dict[str, Any]:
+ return { "type": lldb.eStopReasonSignal, "data": {
+ "signal": signal.SIGINT
+ } }
+
+ def get_stackframes(self):
+ class ScriptedStackFrame:
+ def __init__(idx, cfa, pc, symbol_ctx):
+ self.idx = idx
+ self.cfa = cfa
+ self.pc = pc
+ self.symbol_ctx = symbol_ctx
+
+
+ symbol_ctx = lldb.SBSymbolContext()
+ frame_zero = ScriptedStackFrame(0, 0x42424242, 0x5000000, symbol_ctx)
+ self.frames.append(frame_zero)
+
+ return self.frame_zero[0:0]
+
+ def get_register_context(self) -> str:
+ return struct.pack(
+ '21Q', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
+
+
+def __lldb_init_module(debugger, dict):
+ if not 'SKIP_SCRIPTED_PROCESS_LAUNCH' in os.environ:
+ debugger.HandleCommand(
+ "process launch -C %s.%s" % (__name__,
+ DummyScriptedProcess.__name__))
+ else:
+ print("Name of the class that will manage the scripted process: '%s.%s'"
+ % (__name__, DummyScriptedProcess.__name__))
\ No newline at end of file
Index: lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
===================================================================
--- lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
+++ lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py
@@ -43,41 +43,35 @@
self.expect('script dir(ScriptedProcess)',
substrs=["launch"])
- def test_launch_scripted_process_sbapi(self):
+ def test_scripted_process_and_scripted_thread(self):
"""Test that we can launch an lldb scripted process using the SBAPI,
- check its process ID and read string from memory."""
+ check its process ID, read string from memory, check scripted thread
+ id, name stop reason and register context.
+ """
self.build()
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
self.assertTrue(target, VALID_TARGET)
- scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
+ scripted_process_example_relpath = 'dummy_scripted_process.py'
os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1'
self.runCmd("command script import " + os.path.join(self.getSourceDir(),
- *scripted_process_example_relpath))
+ scripted_process_example_relpath))
launch_info = lldb.SBLaunchInfo(None)
launch_info.SetProcessPluginName("ScriptedProcess")
- launch_info.SetScriptedProcessClassName("my_scripted_process.MyScriptedProcess")
+ launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess")
error = lldb.SBError()
process = target.Launch(launch_info, error)
self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
self.assertEqual(process.GetProcessID(), 42)
- hello_world = "Hello, world!"
- memory_read = process.ReadCStringFromMemory(0x50000000000,
- len(hello_world) + 1, # NULL byte
- error)
-
- self.assertTrue(error.Success(), "Failed to read memory from scripted process.")
- self.assertEqual(hello_world, memory_read)
-
self.assertEqual(process.GetNumThreads(), 1)
thread = process.GetSelectedThread()
self.assertTrue(thread, "Invalid thread.")
self.assertEqual(thread.GetThreadID(), 0x19)
- self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1")
+ self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1")
self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
self.assertGreater(thread.GetNumFrames(), 0)
@@ -94,13 +88,21 @@
for idx, reg in enumerate(registers, start=1):
self.assertEqual(idx, int(reg.value, 16))
- def test_launch_scripted_process_cli(self):
+ def test_launch_scripted_process_stack_frames(self):
"""Test that we can launch an lldb scripted process from the command
line, check its process ID and read string from memory."""
self.build()
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
+
+ self.assertTrue(main_module, "Invalid main module.")
+ error = target.SetModuleLoadAddress(main_module, 0)
+ self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.")
+
scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py']
self.runCmd("command script import " + os.path.join(self.getSourceDir(),
*scripted_process_example_relpath))
@@ -108,12 +110,21 @@
process = target.GetProcess()
self.assertTrue(process, PROCESS_IS_VALID)
self.assertEqual(process.GetProcessID(), 42)
+ self.assertEqual(process.GetNumThreads(), 1)
error = lldb.SBError()
hello_world = "Hello, world!"
memory_read = process.ReadCStringFromMemory(0x50000000000,
len(hello_world) + 1, # NULL byte
error)
+ thread = process.GetSelectedThread()
+ self.assertTrue(thread, "Invalid thread.")
+ self.assertEqual(thread.GetThreadID(), 0x19)
+ self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1")
- self.assertTrue(error.Success(), "Failed to read memory from scripted process.")
- self.assertEqual(hello_world, memory_read)
+ self.assertEqual(thread.GetNumFrames(), 4)
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame, "Invalid frame.")
+ self.assertEqual(frame.GetFunctionName(), "bar")
+ self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42)
+ self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42)
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
@@ -140,6 +140,11 @@
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
python::PythonObject &p, Status &error);
+template <>
+lldb::MemoryRegionInfoSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::MemoryRegionInfoSP>(
+ python::PythonObject &p, Status &error);
+
} // namespace lldb_private
#endif // LLDB_ENABLE_PYTHON
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp
@@ -63,11 +63,30 @@
LLDBSWIGPython_CastPyObjectToSBData(p.get()));
if (!sb_data) {
- error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status.");
+ error.SetErrorString(
+ "Couldn't cast lldb::SBData to lldb::DataExtractorSP.");
return nullptr;
}
return m_interpreter.GetDataExtractorFromSBData(*sb_data);
}
+template <>
+lldb::MemoryRegionInfoSP
+ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::MemoryRegionInfoSP>(
+ python::PythonObject &p, Status &error) {
+
+ lldb::SBMemoryRegionInfo *sb_mem_reg_info =
+ reinterpret_cast<lldb::SBMemoryRegionInfo *>(
+ LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get()));
+
+ if (!sb_mem_reg_info) {
+ error.SetErrorString(
+ "Couldn't cast lldb::SBMemoryRegionInfo to lldb::MemoryRegionInfoSP.");
+ return nullptr;
+ }
+
+ return m_interpreter.GetOpaquePtrFromSBMemoryRegionInfo(*sb_mem_reg_info);
+}
+
#endif
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -85,8 +85,20 @@
lldb::MemoryRegionInfoSP
ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
lldb::addr_t address) {
- // TODO: Implement
- return {};
+ Status error;
+ lldb::MemoryRegionInfoSP mem_region_sp = Dispatch<lldb::MemoryRegionInfoSP>(
+ "get_memory_region_containing_address", error, address);
+
+ if (!mem_region_sp || error.Fail()) {
+ return ErrorWithMessage<lldb::MemoryRegionInfoSP>(
+ __PRETTY_FUNCTION__,
+ llvm::Twine("Null or invalid object (" +
+ llvm::Twine(error.AsCString()) + llvm::Twine(")."))
+ .str(),
+ error);
+ }
+
+ return mem_region_sp;
}
StructuredData::DictionarySP
Index: lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -53,6 +53,7 @@
extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data);
} // namespace lldb_private
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -239,7 +239,7 @@
lldb::DataExtractorSP data_extractor_sp =
GetInterface().ReadMemoryAtAddress(addr, size, error);
- if (!data_extractor_sp || error.Fail())
+ if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail())
return 0;
offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
Index: lldb/source/Interpreter/ScriptInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/ScriptInterpreter.cpp
+++ lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -83,6 +83,11 @@
return Status();
}
+lldb::MemoryRegionInfoSP ScriptInterpreter::GetOpaquePtrFromSBMemoryRegionInfo(
+ const lldb::SBMemoryRegionInfo &mem_region) const {
+ return mem_region.m_opaque_sp;
+}
+
lldb::ScriptLanguage
ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
if (language.equals_insensitive(LanguageToString(eScriptLanguageNone)))
Index: lldb/source/API/SBMemoryRegionInfoList.cpp
===================================================================
--- lldb/source/API/SBMemoryRegionInfoList.cpp
+++ lldb/source/API/SBMemoryRegionInfoList.cpp
@@ -48,6 +48,17 @@
void Clear() { m_regions.clear(); }
+ bool GetMemoryRegionContainingAddress(lldb::addr_t addr,
+ MemoryRegionInfo ®ion_info) {
+ for (auto ®ion : m_regions) {
+ if (region.GetRange().Contains(addr)) {
+ region_info = region;
+ return true;
+ }
+ }
+ return false;
+ }
+
bool GetMemoryRegionInfoAtIndex(size_t index,
MemoryRegionInfo ®ion_info) {
if (index >= GetSize())
@@ -103,6 +114,15 @@
return m_opaque_up->GetSize();
}
+bool SBMemoryRegionInfoList::GetMemoryRegionContainingAddress(
+ lldb::addr_t addr, SBMemoryRegionInfo ®ion_info) {
+ LLDB_RECORD_METHOD(
+ bool, SBMemoryRegionInfoList, GetMemoryRegionContainingAddress,
+ (lldb::addr_t, lldb::SBMemoryRegionInfo &), addr, region_info);
+
+ return m_opaque_up->GetMemoryRegionContainingAddress(addr, region_info.ref());
+}
+
bool SBMemoryRegionInfoList::GetMemoryRegionAtIndex(
uint32_t idx, SBMemoryRegionInfo ®ion_info) {
LLDB_RECORD_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex,
@@ -153,6 +173,9 @@
SBMemoryRegionInfoList, operator=,(
const lldb::SBMemoryRegionInfoList &));
LLDB_REGISTER_METHOD_CONST(uint32_t, SBMemoryRegionInfoList, GetSize, ());
+ LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList,
+ GetMemoryRegionContainingAddress,
+ (lldb::addr_t, lldb::SBMemoryRegionInfo &));
LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex,
(uint32_t, lldb::SBMemoryRegionInfo &));
LLDB_REGISTER_METHOD(void, SBMemoryRegionInfoList, Clear, ());
Index: lldb/source/API/SBMemoryRegionInfo.cpp
===================================================================
--- lldb/source/API/SBMemoryRegionInfo.cpp
+++ lldb/source/API/SBMemoryRegionInfo.cpp
@@ -18,21 +18,39 @@
using namespace lldb;
using namespace lldb_private;
-SBMemoryRegionInfo::SBMemoryRegionInfo() : m_opaque_up(new MemoryRegionInfo()) {
+SBMemoryRegionInfo::SBMemoryRegionInfo() : m_opaque_sp(new MemoryRegionInfo()) {
LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBMemoryRegionInfo);
}
+SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin,
+ lldb::addr_t end, uint32_t permissions,
+ bool mapped, bool stack_memory)
+ : SBMemoryRegionInfo() {
+ LLDB_RECORD_CONSTRUCTOR(
+ SBMemoryRegionInfo,
+ (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool), name,
+ begin, end, permissions, mapped, stack_memory);
+ m_opaque_sp->SetName(name);
+ m_opaque_sp->GetRange().SetRangeBase(begin);
+ m_opaque_sp->GetRange().SetRangeEnd(end);
+ m_opaque_sp->SetLLDBPermissions(permissions);
+ m_opaque_sp->SetMapped(mapped ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ m_opaque_sp->SetIsStackMemory(stack_memory ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+}
+
SBMemoryRegionInfo::SBMemoryRegionInfo(const MemoryRegionInfo *lldb_object_ptr)
- : m_opaque_up(new MemoryRegionInfo()) {
+ : m_opaque_sp(new MemoryRegionInfo()) {
if (lldb_object_ptr)
ref() = *lldb_object_ptr;
}
SBMemoryRegionInfo::SBMemoryRegionInfo(const SBMemoryRegionInfo &rhs)
- : m_opaque_up() {
+ : m_opaque_sp() {
LLDB_RECORD_CONSTRUCTOR(SBMemoryRegionInfo,
(const lldb::SBMemoryRegionInfo &), rhs);
- m_opaque_up = clone(rhs.m_opaque_up);
+ m_opaque_sp = clone(rhs.m_opaque_sp);
}
const SBMemoryRegionInfo &SBMemoryRegionInfo::
@@ -42,7 +60,7 @@
SBMemoryRegionInfo, operator=,(const lldb::SBMemoryRegionInfo &), rhs);
if (this != &rhs)
- m_opaque_up = clone(rhs.m_opaque_up);
+ m_opaque_sp = clone(rhs.m_opaque_sp);
return LLDB_RECORD_RESULT(*this);
}
@@ -51,7 +69,7 @@
void SBMemoryRegionInfo::Clear() {
LLDB_RECORD_METHOD_NO_ARGS(void, SBMemoryRegionInfo, Clear);
- m_opaque_up->Clear();
+ m_opaque_sp->Clear();
}
bool SBMemoryRegionInfo::operator==(const SBMemoryRegionInfo &rhs) const {
@@ -70,56 +88,56 @@
return ref() != rhs.ref();
}
-MemoryRegionInfo &SBMemoryRegionInfo::ref() { return *m_opaque_up; }
+MemoryRegionInfo &SBMemoryRegionInfo::ref() { return *m_opaque_sp; }
-const MemoryRegionInfo &SBMemoryRegionInfo::ref() const { return *m_opaque_up; }
+const MemoryRegionInfo &SBMemoryRegionInfo::ref() const { return *m_opaque_sp; }
lldb::addr_t SBMemoryRegionInfo::GetRegionBase() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBMemoryRegionInfo, GetRegionBase);
- return m_opaque_up->GetRange().GetRangeBase();
+ return m_opaque_sp->GetRange().GetRangeBase();
}
lldb::addr_t SBMemoryRegionInfo::GetRegionEnd() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBMemoryRegionInfo, GetRegionEnd);
- return m_opaque_up->GetRange().GetRangeEnd();
+ return m_opaque_sp->GetRange().GetRangeEnd();
}
bool SBMemoryRegionInfo::IsReadable() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsReadable);
- return m_opaque_up->GetReadable() == MemoryRegionInfo::eYes;
+ return m_opaque_sp->GetReadable() == MemoryRegionInfo::eYes;
}
bool SBMemoryRegionInfo::IsWritable() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsWritable);
- return m_opaque_up->GetWritable() == MemoryRegionInfo::eYes;
+ return m_opaque_sp->GetWritable() == MemoryRegionInfo::eYes;
}
bool SBMemoryRegionInfo::IsExecutable() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsExecutable);
- return m_opaque_up->GetExecutable() == MemoryRegionInfo::eYes;
+ return m_opaque_sp->GetExecutable() == MemoryRegionInfo::eYes;
}
bool SBMemoryRegionInfo::IsMapped() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsMapped);
- return m_opaque_up->GetMapped() == MemoryRegionInfo::eYes;
+ return m_opaque_sp->GetMapped() == MemoryRegionInfo::eYes;
}
const char *SBMemoryRegionInfo::GetName() {
LLDB_RECORD_METHOD_NO_ARGS(const char *, SBMemoryRegionInfo, GetName);
- return m_opaque_up->GetName().AsCString();
+ return m_opaque_sp->GetName().AsCString();
}
bool SBMemoryRegionInfo::HasDirtyMemoryPageList() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, HasDirtyMemoryPageList);
- return m_opaque_up->GetDirtyPageList().hasValue();
+ return m_opaque_sp->GetDirtyPageList().hasValue();
}
uint32_t SBMemoryRegionInfo::GetNumDirtyPages() {
@@ -127,7 +145,7 @@
uint32_t num_dirty_pages = 0;
llvm::Optional<std::vector<addr_t>> dirty_page_list =
- m_opaque_up->GetDirtyPageList();
+ m_opaque_sp->GetDirtyPageList();
if (dirty_page_list.hasValue())
num_dirty_pages = dirty_page_list.getValue().size();
@@ -140,7 +158,7 @@
addr_t dirty_page_addr = LLDB_INVALID_ADDRESS;
const llvm::Optional<std::vector<addr_t>> &dirty_page_list =
- m_opaque_up->GetDirtyPageList();
+ m_opaque_sp->GetDirtyPageList();
if (dirty_page_list.hasValue() && idx < dirty_page_list.getValue().size())
dirty_page_addr = dirty_page_list.getValue()[idx];
@@ -150,7 +168,7 @@
int SBMemoryRegionInfo::GetPageSize() {
LLDB_RECORD_METHOD_NO_ARGS(int, SBMemoryRegionInfo, GetPageSize);
- return m_opaque_up->GetPageSize();
+ return m_opaque_sp->GetPageSize();
}
bool SBMemoryRegionInfo::GetDescription(SBStream &description) {
@@ -158,13 +176,13 @@
(lldb::SBStream &), description);
Stream &strm = description.ref();
- const addr_t load_addr = m_opaque_up->GetRange().base;
+ const addr_t load_addr = m_opaque_sp->GetRange().base;
strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 " ", load_addr,
- load_addr + m_opaque_up->GetRange().size);
- strm.Printf(m_opaque_up->GetReadable() ? "R" : "-");
- strm.Printf(m_opaque_up->GetWritable() ? "W" : "-");
- strm.Printf(m_opaque_up->GetExecutable() ? "X" : "-");
+ load_addr + m_opaque_sp->GetRange().size);
+ strm.Printf(m_opaque_sp->GetReadable() ? "R" : "-");
+ strm.Printf(m_opaque_sp->GetWritable() ? "W" : "-");
+ strm.Printf(m_opaque_sp->GetExecutable() ? "X" : "-");
strm.Printf("]");
return true;
@@ -178,6 +196,9 @@
LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo, ());
LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo,
(const lldb::SBMemoryRegionInfo &));
+ LLDB_REGISTER_CONSTRUCTOR(
+ SBMemoryRegionInfo,
+ (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool));
LLDB_REGISTER_METHOD(
const lldb::SBMemoryRegionInfo &,
SBMemoryRegionInfo, operator=,(const lldb::SBMemoryRegionInfo &));
Index: lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -11,6 +11,7 @@
#include "lldb/API/SBData.h"
#include "lldb/API/SBError.h"
+#include "lldb/API/SBMemoryRegionInfo.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/PluginInterface.h"
@@ -564,6 +565,9 @@
Status GetStatusFromSBError(const lldb::SBError &error) const;
+ lldb::MemoryRegionInfoSP GetOpaquePtrFromSBMemoryRegionInfo(
+ const lldb::SBMemoryRegionInfo &mem_region) const;
+
protected:
Debugger &m_debugger;
lldb::ScriptLanguage m_script_lang;
Index: lldb/include/lldb/API/SBMemoryRegionInfoList.h
===================================================================
--- lldb/include/lldb/API/SBMemoryRegionInfoList.h
+++ lldb/include/lldb/API/SBMemoryRegionInfoList.h
@@ -27,6 +27,9 @@
uint32_t GetSize() const;
+ bool GetMemoryRegionContainingAddress(lldb::addr_t addr,
+ SBMemoryRegionInfo ®ion_info);
+
bool GetMemoryRegionAtIndex(uint32_t idx, SBMemoryRegionInfo ®ion_info);
void Append(lldb::SBMemoryRegionInfo ®ion);
Index: lldb/include/lldb/API/SBMemoryRegionInfo.h
===================================================================
--- lldb/include/lldb/API/SBMemoryRegionInfo.h
+++ lldb/include/lldb/API/SBMemoryRegionInfo.h
@@ -20,6 +20,10 @@
SBMemoryRegionInfo(const lldb::SBMemoryRegionInfo &rhs);
+ SBMemoryRegionInfo(const char *name, lldb::addr_t begin, lldb::addr_t end,
+ uint32_t permissions, bool mapped,
+ bool stack_memory = false);
+
~SBMemoryRegionInfo();
const lldb::SBMemoryRegionInfo &
@@ -117,6 +121,8 @@
friend class SBProcess;
friend class SBMemoryRegionInfoList;
+ friend class lldb_private::ScriptInterpreter;
+
lldb_private::MemoryRegionInfo &ref();
const lldb_private::MemoryRegionInfo &ref() const;
@@ -124,7 +130,7 @@
// Unused.
SBMemoryRegionInfo(const lldb_private::MemoryRegionInfo *lldb_object_ptr);
- lldb::MemoryRegionInfoUP m_opaque_up;
+ lldb::MemoryRegionInfoSP m_opaque_sp;
};
} // namespace lldb
Index: lldb/examples/python/scripted_process/my_scripted_process.py
===================================================================
--- lldb/examples/python/scripted_process/my_scripted_process.py
+++ lldb/examples/python/scripted_process/my_scripted_process.py
@@ -7,11 +7,22 @@
from lldb.plugins.scripted_process import ScriptedThread
class MyScriptedProcess(ScriptedProcess):
+ memory_regions = [
+ lldb.SBMemoryRegionInfo("stack", 0x1040b2000, 0x1040b4000, 0b110, True,
+ True)
+ ]
+
+ stack_memory_dump = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ 'main.stack-dump')
+
def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
super().__init__(target, args)
def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
- return self.memory_regions[0]
+ for region in self.memory_regions:
+ if region.GetRegionBase() <= addr < region.GetRegionEnd():
+ return region
+ return None
def get_thread_with_id(self, tid: int):
return {}
@@ -20,10 +31,25 @@
return {}
def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData:
- data = lldb.SBData().CreateDataFromCString(
+ data = lldb.SBData()
+
+ with open(self.stack_memory_dump, 'rb') as f:
+ stack_mem = f.read(-1)
+ if not stack_mem:
+ return data
+
+ mem_region = self.get_memory_region_containing_address(addr)
+
+ if not mem_region or addr + size > mem_region.GetRegionEnd():
+ return data
+
+ offset = addr - mem_region.GetRegionBase()
+ shrunk_stack_mem = stack_mem[offset:offset + size]
+
+ error = lldb.SBError()
+ data.SetData(error, shrunk_stack_mem,
self.target.GetByteOrder(),
- self.target.GetCodeByteSize(),
- "Hello, world!")
+ self.target.GetAddressByteSize())
return data
def get_loaded_images(self):
@@ -43,6 +69,30 @@
class MyScriptedThread(ScriptedThread):
+ registers = {
+ "rax":0x00000000000006e4,
+ "rbx":0x00000001040b6060,
+ "rcx":0x00000001040b2e00,
+ "rdx":0x00000001040b2ba8,
+ "rdi":0x000000000000002a,
+ "rsi":0x00000001040b2b98,
+ "rbp":0x00000001040b2a20,
+ "rsp":0x00000001040b2a20,
+ "r8":0x00000000003e131e,
+ "r9":0xffffffff00000000,
+ "r10":0x0000000000000000,
+ "r11":0x0000000000000246,
+ "r12":0x000000010007c3a0,
+ "r13":0x00000001040b2b18,
+ "r14":0x0000000100003f90,
+ "r15":0x00000001040b2b88,
+ "rip":0x0000000100003f61,
+ "rflags":0x0000000000000206,
+ "cs":0x000000000000002b,
+ "fs":0x0000000000000000,
+ "gs":0x0000000000000000,
+ }
+
def __init__(self, target):
super().__init__(target)
@@ -73,8 +123,7 @@
return self.frame_zero[0:0]
def get_register_context(self) -> str:
- return struct.pack(
- '21Q', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
+ return struct.pack(f"{len(self.registers)}Q", *self.registers.values())
def __lldb_init_module(debugger, dict):
Index: lldb/bindings/python/python-wrapper.swig
===================================================================
--- lldb/bindings/python/python-wrapper.swig
+++ lldb/bindings/python/python-wrapper.swig
@@ -974,6 +974,22 @@
return sb_ptr;
}
+SWIGEXPORT void*
+LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo
+(
+ PyObject* data
+)
+{
+ lldb::SBMemoryRegionInfo* sb_ptr = NULL;
+
+ int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
+
+ if (valid_cast == -1)
+ return NULL;
+
+ return sb_ptr;
+}
+
SWIGEXPORT bool
LLDBSwigPythonCallCommand
(
Index: lldb/bindings/interface/SBMemoryRegionInfoList.i
===================================================================
--- lldb/bindings/interface/SBMemoryRegionInfoList.i
+++ lldb/bindings/interface/SBMemoryRegionInfoList.i
@@ -24,6 +24,9 @@
uint32_t
GetSize () const;
+ bool
+ GetMemoryRegionContainingAddress (lldb::addr_t addr, SBMemoryRegionInfo ®ion_info);
+
bool
GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo ®ion_info);
Index: lldb/bindings/interface/SBMemoryRegionInfo.i
===================================================================
--- lldb/bindings/interface/SBMemoryRegionInfo.i
+++ lldb/bindings/interface/SBMemoryRegionInfo.i
@@ -20,6 +20,9 @@
SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs);
+ SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin,
+ lldb::addr_t end, uint32_t permissions, bool mapped, bool stack_memory);
+
~SBMemoryRegionInfo ();
void
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits