Author: Med Ismail Bennani Date: 2023-03-03T19:33:01-08:00 New Revision: e6cac17b563f2e2bc7d04347b0b40a9fe12334c9
URL: https://github.com/llvm/llvm-project/commit/e6cac17b563f2e2bc7d04347b0b40a9fe12334c9 DIFF: https://github.com/llvm/llvm-project/commit/e6cac17b563f2e2bc7d04347b0b40a9fe12334c9.diff LOG: [lldb] Extend SWIG SBProcess interface with WriteMemoryAsCString method This patch tries to address an interoperability issue when writing python string into the process memory. Since the python string is not null-terminated, it would still be written to memory however, when trying to read it again with `SBProcess::ReadCStringFromMemory`, the memory read would fail, since the read string doens't contain a null-terminator, and therefore is not a valid C string. To address that, this patch extends the `SBProcess` SWIG interface to expose a new `WriteMemoryAsCString` method that is only exposed to the SWIG target language. That method checks that the buffer to write is null-terminated and otherwise, it appends a null byte at the end of it. Signed-off-by: Med Ismail Bennani <medismail.benn...@gmail.com> Added: Modified: lldb/bindings/interface/SBProcessExtensions.i lldb/test/API/python_api/process/TestProcessAPI.py Removed: ################################################################################ diff --git a/lldb/bindings/interface/SBProcessExtensions.i b/lldb/bindings/interface/SBProcessExtensions.i index c6660d7f42e1..fe9e6415b618 100644 --- a/lldb/bindings/interface/SBProcessExtensions.i +++ b/lldb/bindings/interface/SBProcessExtensions.i @@ -2,6 +2,18 @@ STRING_EXTENSION_OUTSIDE(SBProcess) %extend lldb::SBProcess { #ifdef SWIGPYTHON %pythoncode %{ + def WriteMemoryAsCString(self, addr, str, error): + ''' + WriteMemoryAsCString(self, addr, str, error): + This functions the same as `WriteMemory` except a null-terminator is appended + to the end of the buffer if it is not there already. + ''' + if not str or len(str) == 0: + return 0 + if not str[-1] == '\0': + str += '\0' + return self.WriteMemory(addr, str, error) + def __get_is_alive__(self): '''Returns "True" if the process is currently alive, "False" otherwise''' s = self.GetState() diff --git a/lldb/test/API/python_api/process/TestProcessAPI.py b/lldb/test/API/python_api/process/TestProcessAPI.py index c56053dad0cf..edb507057283 100644 --- a/lldb/test/API/python_api/process/TestProcessAPI.py +++ b/lldb/test/API/python_api/process/TestProcessAPI.py @@ -186,6 +186,32 @@ def test_write_memory(self): exe=False, startstr=b'a') + # Get the SBValue for the global variable 'my_cstring'. + val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + + addr = val.AddressOf().GetValueAsUnsigned() + + # Write an empty string to memory + bytes_written = process.WriteMemoryAsCString(addr, "", error) + self.assertEqual(bytes_written, 0) + if not error.Success(): + self.fail("SBProcess.WriteMemoryAsCString() failed") + + message = "Hello!" + bytes_written = process.WriteMemoryAsCString(addr, message, error) + self.assertEqual(bytes_written, len(message) + 1) + if not error.Success(): + self.fail("SBProcess.WriteMemoryAsCString() failed") + + cstring = process.ReadCStringFromMemory( + val.AddressOf().GetValueAsUnsigned(), 256, error) + if not error.Success(): + self.fail("SBProcess.ReadCStringFromMemory() failed") + + self.assertEqual(cstring, message) + + def test_access_my_int(self): """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs.""" self.build() _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits