diff options
-rw-r--r-- | lldb/include/lldb/API/SBProcess.h | 3 | ||||
-rw-r--r-- | lldb/source/API/SBProcess.cpp | 14 | ||||
-rw-r--r-- | lldb/test/python_api/process/TestProcessAPI.py | 90 | ||||
-rw-r--r-- | lldb/test/python_api/process/main.cpp | 2 |
4 files changed, 109 insertions, 0 deletions
diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index e08a806cb0e..342a7b34398 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -53,6 +53,9 @@ public: lldb::SBTarget GetTarget() const; + lldb::ByteOrder + GetByteOrder() const; + size_t PutSTDIN (const char *src, size_t src_len); diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index 3b59960db1e..b56df41ac05 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -366,6 +366,20 @@ SBProcess::GetProcessID () return ret_val; } +ByteOrder +SBProcess::GetByteOrder () const +{ + ByteOrder byteOrder = eByteOrderInvalid; + if (m_opaque_sp) + byteOrder = m_opaque_sp->GetTarget().GetArchitecture().GetByteOrder(); + + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetByteOrder () => %d", m_opaque_sp.get(), byteOrder); + + return byteOrder; +} + uint32_t SBProcess::GetAddressByteSize () const { diff --git a/lldb/test/python_api/process/TestProcessAPI.py b/lldb/test/python_api/process/TestProcessAPI.py index c526dd60679..1e92fa309d3 100644 --- a/lldb/test/python_api/process/TestProcessAPI.py +++ b/lldb/test/python_api/process/TestProcessAPI.py @@ -37,6 +37,19 @@ class ProcessAPITestCase(TestBase): self.buildDwarf() self.write_memory() + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test + def test_access_my_int_with_dsym(self): + """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs.""" + self.buildDsym() + self.access_my_int() + + @python_api_test + def test_access_my_int_with_dwarf(self): + """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs.""" + self.buildDwarf() + self.access_my_int() + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -132,6 +145,83 @@ class ProcessAPITestCase(TestBase): exe=False, startstr = 'a') + def access_my_int(self): + """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) + self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + error = lldb.SBError() + self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error) + + thread = self.process.GetThreadAtIndex(0); + frame = thread.GetFrameAtIndex(0); + + # Get the SBValue for the global variable 'my_int'. + val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(frame, val) + + # If the variable does not have a load address, there's no sense continuing. + if not val.GetLocation(frame).startswith("0x"): + return + + # OK, let's get the hex location of the variable. + location = int(val.GetLocation(frame), 16) + + byteSize = val.GetByteSize() + byteOrder = self.process.GetByteOrder() + bytes = bytearray(byteSize) + + if byteOrder == lldb.eByteOrderBig: + # 256 in big endian => 0x00000100 + # the second byte counted from the end is to be 0b00000001 + bytes[-2] = 0b00000001 + elif byteOrder == lldb.eByteOrderLittle: + # 256 in little endian => 0x00010000 + # the second byte counted from the start is to be 0b00000001 + bytes[1] = 0b00000001 + else: + # Neither big endian nor little endian? Return for now. + return + + # The program logic makes the 'my_int' variable to have int type and value of 0. + # But we want to use the WriteMemory() API to assign 256 to the variable. + + # Now use WriteMemory() API to write 256 into the global variable. + new_value = str(bytes) + result = self.process.WriteMemory(location, new_value, error) + if not error.Success() or result != byteSize: + self.fail("SBProcess.WriteMemory() failed") + + # Get the SBValue for the global variable 'my_int' again, with its updated value. + val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal) + self.expect(val.GetValue(frame), + "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'", + exe=False, + startstr = '256') + + # Now read the memory content. The bytearray should have (byte)1 as the second element. + content = self.process.ReadMemory(location, byteSize, error) + if not error.Success(): + self.fail("SBProcess.ReadMemory() failed") + new_bytes = bytearray(content, "ascii") + if byteOrder == lldb.eByteOrderBig: + if new_bytes[-2] != 0b00000001: + self.fail("Memory content read from 'my_int' does not match (int)256") + elif byteOrder == lldb.eByteOrderLittle: + if new_bytes[1] != 0b00000001: + self.fail("Memory content read from 'my_int' does not match (int)256") + + # Dump the memory content.... + for i in new_bytes: + print "byte:", i + if __name__ == '__main__': import atexit diff --git a/lldb/test/python_api/process/main.cpp b/lldb/test/python_api/process/main.cpp index 0d507b9f3b4..4d5b5e6d7e9 100644 --- a/lldb/test/python_api/process/main.cpp +++ b/lldb/test/python_api/process/main.cpp @@ -11,6 +11,7 @@ // This simple program is to test the lldb Python API related to process. char my_char = 'u'; +int my_int = 0; int main (int argc, char const *argv[]) { @@ -22,4 +23,5 @@ int main (int argc, char const *argv[]) printf("after the loop: my_char='%c'\n", my_char); // 'my_char' should print out as 'x'. 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. } |