housel updated this revision to Diff 357131.
housel added a comment.
Updated based on reviewer suggestions, thanks.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D105389/new/
https://reviews.llvm.org/D105389
Files:
lldb/bindings/interface/SBProcess.i
lldb/include/lldb/API/SBProcess.h
lldb/source/API/SBProcess.cpp
lldb/test/API/python_api/process/TestProcessAPI.py
lldb/test/API/python_api/process/main.cpp
Index: lldb/test/API/python_api/process/main.cpp
===================================================================
--- lldb/test/API/python_api/process/main.cpp
+++ lldb/test/API/python_api/process/main.cpp
@@ -21,3 +21,13 @@
return 0; // Set break point at this line and check variable 'my_char'.
// Use lldb Python API to set memory content for my_int and check the result.
}
+
+char test_read (char *ptr)
+{
+ return *ptr;
+}
+
+void test_write (char *ptr, char c)
+{
+ *ptr = c;
+}
Index: lldb/test/API/python_api/process/TestProcessAPI.py
===================================================================
--- lldb/test/API/python_api/process/TestProcessAPI.py
+++ lldb/test/API/python_api/process/TestProcessAPI.py
@@ -398,3 +398,58 @@
"Process effective group ID is invalid")
process_info.GetParentProcessID()
+
+ def test_allocate_deallocate_memory(self):
+ """Test Python SBProcess.AllocateMemory() and SBProcess.DeallocateMemory() APIs."""
+ self.build()
+ (target, process, main_thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(
+ self, "// Set break point at this line", lldb.SBFileSpec("main.cpp"))
+
+ # Allocate a block of memory in the target process
+ error = lldb.SBError()
+ addr = process.AllocateMemory(16384, lldb.ePermissionsReadable, error)
+ if not error.Success() or addr == lldb.LLDB_INVALID_ADDRESS:
+ self.fail("SBProcess.AllocateMemory() failed")
+
+ # Now use WriteMemory() API to write 'a' into the allocated
+ # memory. Note that the debugger can do this even though the
+ # block is not set writable.
+ result = process.WriteMemory(addr, 'a', error)
+ if not error.Success() or result != 1:
+ self.fail("SBProcess.WriteMemory() failed")
+
+ # Read from the memory location. This time it should be 'a'.
+ # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
+ # expect to get a Python string as the result object!
+ content = process.ReadMemory(addr, 1, error)
+ if not error.Success():
+ self.fail("SBProcess.ReadMemory() failed")
+ if self.TraceOn():
+ print("memory content:", content)
+
+ self.expect(
+ content,
+ "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
+ exe=False,
+ startstr=b'a')
+
+ # Verify that the process itself can read the allocated memory
+ frame = main_thread.GetFrameAtIndex(0)
+ val = frame.EvaluateExpression(
+ "test_read(reinterpret_cast<char *>({:#x}))".format(addr))
+ self.expect(val.GetValue(),
+ "Result of test_read() matches expected output 'a'",
+ exe=False,
+ startstr="'a'")
+
+ # Verify that the process cannot write into the block
+ val = frame.EvaluateExpression(
+ "test_write(reinterpret_cast<char *>({:#x}), 'b')".format(addr))
+ if val.GetError().Success():
+ self.fail(
+ "test_write() to allocated memory without write permission unexpectedly succeeded")
+
+ # Deallocate the memory
+ error = process.DeallocateMemory(addr)
+ if not error.Success():
+ self.fail("SBProcess.DeallocateMemory() failed")
Index: lldb/source/API/SBProcess.cpp
===================================================================
--- lldb/source/API/SBProcess.cpp
+++ lldb/source/API/SBProcess.cpp
@@ -1288,6 +1288,51 @@
return LLDB_RECORD_RESULT(sb_proc_info);
}
+lldb::addr_t SBProcess::AllocateMemory(size_t size, uint32_t permissions,
+ lldb::SBError &sb_error) {
+ LLDB_RECORD_METHOD(lldb::addr_t, SBProcess, AllocateMemory,
+ (size_t, uint32_t, lldb::SBError &), size, permissions,
+ sb_error);
+
+ lldb::addr_t addr = LLDB_INVALID_ADDRESS;
+ ProcessSP process_sp(GetSP());
+ if (process_sp) {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process_sp->GetRunLock())) {
+ std::lock_guard<std::recursive_mutex> guard(
+ process_sp->GetTarget().GetAPIMutex());
+ addr = process_sp->AllocateMemory(size, permissions, sb_error.ref());
+ } else {
+ sb_error.SetErrorString("process is running");
+ }
+ } else {
+ sb_error.SetErrorString("SBProcess is invalid");
+ }
+ return addr;
+}
+
+lldb::SBError SBProcess::DeallocateMemory(lldb::addr_t ptr) {
+ LLDB_RECORD_METHOD(lldb::SBError, SBProcess, DeallocateMemory, (lldb::addr_t),
+ ptr);
+
+ lldb::SBError sb_error;
+ ProcessSP process_sp(GetSP());
+ if (process_sp) {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process_sp->GetRunLock())) {
+ std::lock_guard<std::recursive_mutex> guard(
+ process_sp->GetTarget().GetAPIMutex());
+ Status error = process_sp->DeallocateMemory(ptr);
+ sb_error.SetError(error);
+ } else {
+ sb_error.SetErrorString("process is running");
+ }
+ } else {
+ sb_error.SetErrorString("SBProcess is invalid");
+ }
+ return sb_error;
+}
+
namespace lldb_private {
namespace repro {
@@ -1417,6 +1462,10 @@
LLDB_REGISTER_METHOD(lldb::SBMemoryRegionInfoList, SBProcess,
GetMemoryRegions, ());
LLDB_REGISTER_METHOD(lldb::SBProcessInfo, SBProcess, GetProcessInfo, ());
+ LLDB_REGISTER_METHOD(lldb::addr_t, SBProcess, AllocateMemory,
+ (size_t, uint32_t, lldb::SBError &));
+ LLDB_REGISTER_METHOD(lldb::SBError, SBProcess, DeallocateMemory,
+ (lldb::addr_t));
LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDOUT);
LLDB_REGISTER_CHAR_PTR_METHOD_CONST(size_t, SBProcess, GetSTDERR);
Index: lldb/include/lldb/API/SBProcess.h
===================================================================
--- lldb/include/lldb/API/SBProcess.h
+++ lldb/include/lldb/API/SBProcess.h
@@ -370,6 +370,45 @@
/// valid.
lldb::SBProcessInfo GetProcessInfo();
+ /// Allocate memory within the process.
+ ///
+ /// This function will allocate memory in the process's address space.
+ ///
+ /// \param[in] size
+ /// The size of the allocation requested.
+ ///
+ /// \param[in] permissions
+ /// Or together any of the lldb::Permissions bits. The
+ /// permissions on a given memory allocation can't be changed
+ /// after allocation. Note that a block that isn't set writable
+ /// can still be written from lldb, just not by the process
+ /// itself.
+ ///
+ /// \param[out] error
+ /// An error object that gets filled in with any errors that
+ /// might occur when trying allocate.
+ ///
+ /// \return
+ /// The address of the allocated buffer in the process, or
+ /// LLDB_INVALID_ADDRESS if the allocation failed.
+ lldb::addr_t AllocateMemory(size_t size, uint32_t permissions,
+ lldb::SBError &error);
+
+ /// Deallocate memory in the process.
+ ///
+ /// This function will deallocate memory in the process's address
+ /// space that was allocated with AllocateMemory.
+ ///
+ /// \param[in] ptr
+ /// A return value from AllocateMemory, pointing to the memory you
+ /// want to deallocate.
+ ///
+ /// \return
+ /// An error object describes any errors that occurred while
+ /// deallocating.
+ ///
+ lldb::SBError DeallocateMemory(lldb::addr_t ptr);
+
protected:
friend class SBAddress;
friend class SBBreakpoint;
Index: lldb/bindings/interface/SBProcess.i
===================================================================
--- lldb/bindings/interface/SBProcess.i
+++ lldb/bindings/interface/SBProcess.i
@@ -417,6 +417,25 @@
lldb::SBProcessInfo
GetProcessInfo();
+ %feature("autodoc", "
+ Allocates a block of memory within the process, with size and
+ access permissions specified in the arguments. The permisssions
+ argument is an or-combination of zero or more of
+ lldb.ePermissionsWritable, lldb.ePermissionsReadable, and
+ lldb.ePermissionsExecutable. Returns the address
+ of the allocated buffer in the process, or
+ lldb.LLDB_INVALID_ADDRESS if the allocation failed.") AllocateMemory;
+
+ lldb::addr_t
+ AllocateMemory(size_t size, uint32_t permissions, lldb::SBError &error);
+
+ %feature("autodoc", "
+ Deallocates the block of memory (previously allocated using
+ AllocateMemory) given in the argument.") DeallocateMemory;
+
+ lldb::SBError
+ DeallocateMemory(lldb::addr_t ptr);
+
STRING_EXTENSION(SBProcess)
#ifdef SWIGPYTHON
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits