xref: /llvm-project/lldb/test/API/python_api/process/TestProcessAPI.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest SBProcess APIs, including ReadMemory(), WriteMemory(), and others.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtimport lldb
64a8cc285SJason Molendaimport sys
799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str
1099451b44SJordan Rupprecht
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprechtclass ProcessAPITestCase(TestBase):
1399451b44SJordan Rupprecht    def setUp(self):
1499451b44SJordan Rupprecht        # Call super's setUp().
1599451b44SJordan Rupprecht        TestBase.setUp(self)
1699451b44SJordan Rupprecht        # Find the line number to break inside main().
1799451b44SJordan Rupprecht        self.line = line_number(
182238dcc3SJonas Devlieghere            "main.cpp", "// Set break point at this line and check variable 'my_char'."
192238dcc3SJonas Devlieghere        )
2099451b44SJordan Rupprecht
21c1928033SMed Ismail Bennani    def test_scripted_implementation(self):
22c1928033SMed Ismail Bennani        self.build()
23c1928033SMed Ismail Bennani        exe = self.getBuildArtifact("a.out")
24c1928033SMed Ismail Bennani
252238dcc3SJonas Devlieghere        (target, process, _, _) = lldbutil.run_to_source_breakpoint(
262238dcc3SJonas Devlieghere            self, "Set break point", lldb.SBFileSpec("main.cpp")
272238dcc3SJonas Devlieghere        )
28c1928033SMed Ismail Bennani
29c1928033SMed Ismail Bennani        self.assertTrue(process, PROCESS_IS_VALID)
30c1928033SMed Ismail Bennani        self.assertEqual(process.GetScriptedImplementation(), None)
31c1928033SMed Ismail Bennani
3299451b44SJordan Rupprecht    def test_read_memory(self):
3399451b44SJordan Rupprecht        """Test Python SBProcess.ReadMemory() API."""
3499451b44SJordan Rupprecht        self.build()
3599451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
3699451b44SJordan Rupprecht
3799451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
3899451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
3999451b44SJordan Rupprecht
4099451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
4199451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
4299451b44SJordan Rupprecht
4399451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
442238dcc3SJonas Devlieghere        process = target.LaunchSimple(None, None, self.get_process_working_directory())
4599451b44SJordan Rupprecht
4699451b44SJordan Rupprecht        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
4799451b44SJordan Rupprecht        self.assertTrue(
482238dcc3SJonas Devlieghere            thread.IsValid(), "There should be a thread stopped due to breakpoint"
492238dcc3SJonas Devlieghere        )
5099451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
5199451b44SJordan Rupprecht
5214186773SJim Ingham        # Get the SBValue for the file static variable 'my_char'.
5314186773SJim Ingham        val = frame.FindValue("my_char", lldb.eValueTypeVariableStatic)
5499451b44SJordan Rupprecht        self.DebugSBValue(val)
5599451b44SJordan Rupprecht
5699451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
5799451b44SJordan Rupprecht        # expect to get a Python string as the result object!
5899451b44SJordan Rupprecht        error = lldb.SBError()
5999451b44SJordan Rupprecht        self.assertFalse(val.TypeIsPointerType())
602238dcc3SJonas Devlieghere        content = process.ReadMemory(val.AddressOf().GetValueAsUnsigned(), 1, error)
6199451b44SJordan Rupprecht        if not error.Success():
6299451b44SJordan Rupprecht            self.fail("SBProcess.ReadMemory() failed")
6399451b44SJordan Rupprecht        if self.TraceOn():
6499451b44SJordan Rupprecht            print("memory content:", content)
6599451b44SJordan Rupprecht
6699451b44SJordan Rupprecht        self.expect(
6799451b44SJordan Rupprecht            content,
6899451b44SJordan Rupprecht            "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
6999451b44SJordan Rupprecht            exe=False,
702238dcc3SJonas Devlieghere            startstr=b"x",
712238dcc3SJonas Devlieghere        )
7299451b44SJordan Rupprecht
7399451b44SJordan Rupprecht        # Read (char *)my_char_ptr.
7499451b44SJordan Rupprecht        val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal)
7599451b44SJordan Rupprecht        self.DebugSBValue(val)
762238dcc3SJonas Devlieghere        cstring = process.ReadCStringFromMemory(val.GetValueAsUnsigned(), 256, error)
7799451b44SJordan Rupprecht        if not error.Success():
7899451b44SJordan Rupprecht            self.fail("SBProcess.ReadCStringFromMemory() failed")
7999451b44SJordan Rupprecht        if self.TraceOn():
8099451b44SJordan Rupprecht            print("cstring read is:", cstring)
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht        self.expect(
8399451b44SJordan Rupprecht            cstring,
8499451b44SJordan Rupprecht            "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
8599451b44SJordan Rupprecht            exe=False,
862238dcc3SJonas Devlieghere            startstr="Does it work?",
872238dcc3SJonas Devlieghere        )
8899451b44SJordan Rupprecht
8999451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_cstring'.
9099451b44SJordan Rupprecht        val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
9199451b44SJordan Rupprecht        self.DebugSBValue(val)
9299451b44SJordan Rupprecht
9399451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes
9499451b44SJordan Rupprecht        # from the address, and expect to get a Python string as the result
9599451b44SJordan Rupprecht        # object!
9699451b44SJordan Rupprecht        self.assertFalse(val.TypeIsPointerType())
9799451b44SJordan Rupprecht        cstring = process.ReadCStringFromMemory(
982238dcc3SJonas Devlieghere            val.AddressOf().GetValueAsUnsigned(), 256, error
992238dcc3SJonas Devlieghere        )
10099451b44SJordan Rupprecht        if not error.Success():
10199451b44SJordan Rupprecht            self.fail("SBProcess.ReadCStringFromMemory() failed")
10299451b44SJordan Rupprecht        if self.TraceOn():
10399451b44SJordan Rupprecht            print("cstring read is:", cstring)
10499451b44SJordan Rupprecht
10599451b44SJordan Rupprecht        self.expect(
10699451b44SJordan Rupprecht            cstring,
10799451b44SJordan Rupprecht            "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
10899451b44SJordan Rupprecht            exe=False,
1092238dcc3SJonas Devlieghere            startstr="lldb.SBProcess.ReadCStringFromMemory() works!",
1102238dcc3SJonas Devlieghere        )
11199451b44SJordan Rupprecht
11299451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_uint32'.
11399451b44SJordan Rupprecht        val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal)
11499451b44SJordan Rupprecht        self.DebugSBValue(val)
11599451b44SJordan Rupprecht
11699451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 4 to read 4 bytes
11799451b44SJordan Rupprecht        # from the address, and expect to get an int as the result!
11899451b44SJordan Rupprecht        self.assertFalse(val.TypeIsPointerType())
11999451b44SJordan Rupprecht        my_uint32 = process.ReadUnsignedFromMemory(
1202238dcc3SJonas Devlieghere            val.AddressOf().GetValueAsUnsigned(), 4, error
1212238dcc3SJonas Devlieghere        )
12299451b44SJordan Rupprecht        if not error.Success():
12399451b44SJordan Rupprecht            self.fail("SBProcess.ReadCStringFromMemory() failed")
12499451b44SJordan Rupprecht        if self.TraceOn():
12599451b44SJordan Rupprecht            print("uint32 read is:", my_uint32)
12699451b44SJordan Rupprecht
12799451b44SJordan Rupprecht        if my_uint32 != 12345:
12899451b44SJordan Rupprecht            self.fail(
1292238dcc3SJonas Devlieghere                "Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output"
1302238dcc3SJonas Devlieghere            )
13199451b44SJordan Rupprecht
13299451b44SJordan Rupprecht    def test_write_memory(self):
13399451b44SJordan Rupprecht        """Test Python SBProcess.WriteMemory() API."""
13499451b44SJordan Rupprecht        self.build()
13599451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
13699451b44SJordan Rupprecht
13799451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
13899451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
13999451b44SJordan Rupprecht
14099451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
14199451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
14299451b44SJordan Rupprecht
14399451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
1442238dcc3SJonas Devlieghere        process = target.LaunchSimple(None, None, self.get_process_working_directory())
14599451b44SJordan Rupprecht
14699451b44SJordan Rupprecht        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
14799451b44SJordan Rupprecht        self.assertTrue(
1482238dcc3SJonas Devlieghere            thread.IsValid(), "There should be a thread stopped due to breakpoint"
1492238dcc3SJonas Devlieghere        )
15099451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
15199451b44SJordan Rupprecht
15214186773SJim Ingham        # Get the SBValue for the static variable 'my_char'.
15314186773SJim Ingham        val = frame.FindValue("my_char", lldb.eValueTypeVariableStatic)
15499451b44SJordan Rupprecht        self.DebugSBValue(val)
15599451b44SJordan Rupprecht
15699451b44SJordan Rupprecht        # If the variable does not have a load address, there's no sense
15799451b44SJordan Rupprecht        # continuing.
15899451b44SJordan Rupprecht        if not val.GetLocation().startswith("0x"):
15999451b44SJordan Rupprecht            return
16099451b44SJordan Rupprecht
16199451b44SJordan Rupprecht        # OK, let's get the hex location of the variable.
16299451b44SJordan Rupprecht        location = int(val.GetLocation(), 16)
16399451b44SJordan Rupprecht
16499451b44SJordan Rupprecht        # The program logic makes the 'my_char' variable to have memory content as 'x'.
16599451b44SJordan Rupprecht        # But we want to use the WriteMemory() API to assign 'a' to the
16699451b44SJordan Rupprecht        # variable.
16799451b44SJordan Rupprecht
16899451b44SJordan Rupprecht        # Now use WriteMemory() API to write 'a' into the global variable.
16999451b44SJordan Rupprecht        error = lldb.SBError()
1702238dcc3SJonas Devlieghere        result = process.WriteMemory(location, "a", error)
17199451b44SJordan Rupprecht        if not error.Success() or result != 1:
17299451b44SJordan Rupprecht            self.fail("SBProcess.WriteMemory() failed")
17399451b44SJordan Rupprecht
17499451b44SJordan Rupprecht        # Read from the memory location.  This time it should be 'a'.
17599451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
17699451b44SJordan Rupprecht        # expect to get a Python string as the result object!
17799451b44SJordan Rupprecht        content = process.ReadMemory(location, 1, error)
17899451b44SJordan Rupprecht        if not error.Success():
17999451b44SJordan Rupprecht            self.fail("SBProcess.ReadMemory() failed")
18099451b44SJordan Rupprecht        if self.TraceOn():
18199451b44SJordan Rupprecht            print("memory content:", content)
18299451b44SJordan Rupprecht
18399451b44SJordan Rupprecht        self.expect(
18499451b44SJordan Rupprecht            content,
18599451b44SJordan Rupprecht            "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
18699451b44SJordan Rupprecht            exe=False,
1872238dcc3SJonas Devlieghere            startstr=b"a",
1882238dcc3SJonas Devlieghere        )
18999451b44SJordan Rupprecht
190e6cac17bSMed Ismail Bennani        # Get the SBValue for the global variable 'my_cstring'.
191e6cac17bSMed Ismail Bennani        val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
192e6cac17bSMed Ismail Bennani        self.DebugSBValue(val)
193e6cac17bSMed Ismail Bennani
194e6cac17bSMed Ismail Bennani        addr = val.AddressOf().GetValueAsUnsigned()
195e6cac17bSMed Ismail Bennani
196e6cac17bSMed Ismail Bennani        # Write an empty string to memory
197e6cac17bSMed Ismail Bennani        bytes_written = process.WriteMemoryAsCString(addr, "", error)
198e6cac17bSMed Ismail Bennani        self.assertEqual(bytes_written, 0)
199e6cac17bSMed Ismail Bennani        if not error.Success():
200e6cac17bSMed Ismail Bennani            self.fail("SBProcess.WriteMemoryAsCString() failed")
201e6cac17bSMed Ismail Bennani
202e6cac17bSMed Ismail Bennani        message = "Hello!"
203e6cac17bSMed Ismail Bennani        bytes_written = process.WriteMemoryAsCString(addr, message, error)
204e6cac17bSMed Ismail Bennani        self.assertEqual(bytes_written, len(message) + 1)
205e6cac17bSMed Ismail Bennani        if not error.Success():
206e6cac17bSMed Ismail Bennani            self.fail("SBProcess.WriteMemoryAsCString() failed")
207e6cac17bSMed Ismail Bennani
208e6cac17bSMed Ismail Bennani        cstring = process.ReadCStringFromMemory(
2092238dcc3SJonas Devlieghere            val.AddressOf().GetValueAsUnsigned(), 256, error
2102238dcc3SJonas Devlieghere        )
211e6cac17bSMed Ismail Bennani        if not error.Success():
212e6cac17bSMed Ismail Bennani            self.fail("SBProcess.ReadCStringFromMemory() failed")
213e6cac17bSMed Ismail Bennani
214e6cac17bSMed Ismail Bennani        self.assertEqual(cstring, message)
215e6cac17bSMed Ismail Bennani
21699451b44SJordan Rupprecht    def test_access_my_int(self):
21799451b44SJordan Rupprecht        """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
21899451b44SJordan Rupprecht        self.build()
21999451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
22099451b44SJordan Rupprecht
22199451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
22299451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
22399451b44SJordan Rupprecht
22499451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
22599451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
22699451b44SJordan Rupprecht
22799451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
2282238dcc3SJonas Devlieghere        process = target.LaunchSimple(None, None, self.get_process_working_directory())
22999451b44SJordan Rupprecht
23099451b44SJordan Rupprecht        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
23199451b44SJordan Rupprecht        self.assertTrue(
2322238dcc3SJonas Devlieghere            thread.IsValid(), "There should be a thread stopped due to breakpoint"
2332238dcc3SJonas Devlieghere        )
23499451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
23599451b44SJordan Rupprecht
23699451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_int'.
23799451b44SJordan Rupprecht        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
23899451b44SJordan Rupprecht        self.DebugSBValue(val)
23999451b44SJordan Rupprecht
24099451b44SJordan Rupprecht        # If the variable does not have a load address, there's no sense
24199451b44SJordan Rupprecht        # continuing.
24299451b44SJordan Rupprecht        if not val.GetLocation().startswith("0x"):
24399451b44SJordan Rupprecht            return
24499451b44SJordan Rupprecht
24599451b44SJordan Rupprecht        # OK, let's get the hex location of the variable.
24699451b44SJordan Rupprecht        location = int(val.GetLocation(), 16)
24799451b44SJordan Rupprecht
24899451b44SJordan Rupprecht        # Note that the canonical from of the bytearray is little endian.
24999451b44SJordan Rupprecht        from lldbsuite.test.lldbutil import int_to_bytearray, bytearray_to_int
25099451b44SJordan Rupprecht
25199451b44SJordan Rupprecht        byteSize = val.GetByteSize()
25299451b44SJordan Rupprecht        bytes = int_to_bytearray(256, byteSize)
25399451b44SJordan Rupprecht
25499451b44SJordan Rupprecht        byteOrder = process.GetByteOrder()
25599451b44SJordan Rupprecht        if byteOrder == lldb.eByteOrderBig:
25699451b44SJordan Rupprecht            bytes.reverse()
25799451b44SJordan Rupprecht        elif byteOrder == lldb.eByteOrderLittle:
25899451b44SJordan Rupprecht            pass
25999451b44SJordan Rupprecht        else:
26099451b44SJordan Rupprecht            # Neither big endian nor little endian?  Return for now.
26199451b44SJordan Rupprecht            # Add more logic here if we want to handle other types.
26299451b44SJordan Rupprecht            return
26399451b44SJordan Rupprecht
26499451b44SJordan Rupprecht        # The program logic makes the 'my_int' variable to have int type and value of 0.
26599451b44SJordan Rupprecht        # But we want to use the WriteMemory() API to assign 256 to the
26699451b44SJordan Rupprecht        # variable.
26799451b44SJordan Rupprecht
26899451b44SJordan Rupprecht        # Now use WriteMemory() API to write 256 into the global variable.
26999451b44SJordan Rupprecht        error = lldb.SBError()
27099451b44SJordan Rupprecht        result = process.WriteMemory(location, bytes, error)
27199451b44SJordan Rupprecht        if not error.Success() or result != byteSize:
27299451b44SJordan Rupprecht            self.fail("SBProcess.WriteMemory() failed")
27399451b44SJordan Rupprecht
27499451b44SJordan Rupprecht        # Make sure that the val we got originally updates itself to notice the
27599451b44SJordan Rupprecht        # change:
27699451b44SJordan Rupprecht        self.expect(
27799451b44SJordan Rupprecht            val.GetValue(),
27899451b44SJordan Rupprecht            "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
27999451b44SJordan Rupprecht            exe=False,
2802238dcc3SJonas Devlieghere            startstr="256",
2812238dcc3SJonas Devlieghere        )
28299451b44SJordan Rupprecht
28399451b44SJordan Rupprecht        # And for grins, get the SBValue for the global variable 'my_int'
28499451b44SJordan Rupprecht        # again, to make sure that also tracks the new value:
28599451b44SJordan Rupprecht        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
28699451b44SJordan Rupprecht        self.expect(
28799451b44SJordan Rupprecht            val.GetValue(),
28899451b44SJordan Rupprecht            "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
28999451b44SJordan Rupprecht            exe=False,
2902238dcc3SJonas Devlieghere            startstr="256",
2912238dcc3SJonas Devlieghere        )
29299451b44SJordan Rupprecht
29399451b44SJordan Rupprecht        # Now read the memory content.  The bytearray should have (byte)1 as
29499451b44SJordan Rupprecht        # the second element.
29599451b44SJordan Rupprecht        content = process.ReadMemory(location, byteSize, error)
29699451b44SJordan Rupprecht        if not error.Success():
29799451b44SJordan Rupprecht            self.fail("SBProcess.ReadMemory() failed")
29899451b44SJordan Rupprecht
29999451b44SJordan Rupprecht        # The bytearray_to_int utility function expects a little endian
30099451b44SJordan Rupprecht        # bytearray.
30199451b44SJordan Rupprecht        if byteOrder == lldb.eByteOrderBig:
3022238dcc3SJonas Devlieghere            content = bytearray(content, "ascii")
30399451b44SJordan Rupprecht            content.reverse()
30499451b44SJordan Rupprecht
30599451b44SJordan Rupprecht        new_value = bytearray_to_int(content, byteSize)
30699451b44SJordan Rupprecht        if new_value != 256:
30799451b44SJordan Rupprecht            self.fail("Memory content read from 'my_int' does not match (int)256")
30899451b44SJordan Rupprecht
30999451b44SJordan Rupprecht        # Dump the memory content....
31099451b44SJordan Rupprecht        if self.TraceOn():
31199451b44SJordan Rupprecht            for i in content:
31299451b44SJordan Rupprecht                print("byte:", i)
31399451b44SJordan Rupprecht
31499451b44SJordan Rupprecht    def test_remote_launch(self):
31599451b44SJordan Rupprecht        """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
31699451b44SJordan Rupprecht        self.build()
31799451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
31899451b44SJordan Rupprecht
31999451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
32099451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
32199451b44SJordan Rupprecht
32299451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
3232238dcc3SJonas Devlieghere        process = target.LaunchSimple(None, None, self.get_process_working_directory())
32499451b44SJordan Rupprecht
32599451b44SJordan Rupprecht        if self.TraceOn():
32699451b44SJordan Rupprecht            print("process state:", state_type_to_str(process.GetState()))
327*9c246882SJordan Rupprecht        self.assertNotEqual(process.GetState(), lldb.eStateConnected)
32899451b44SJordan Rupprecht
32999451b44SJordan Rupprecht        error = lldb.SBError()
33099451b44SJordan Rupprecht        success = process.RemoteLaunch(
3312238dcc3SJonas Devlieghere            None, None, None, None, None, None, 0, False, error
3322238dcc3SJonas Devlieghere        )
33399451b44SJordan Rupprecht        self.assertTrue(
33499451b44SJordan Rupprecht            not success,
3352238dcc3SJonas Devlieghere            "RemoteLaunch() should fail for process state != eStateConnected",
3362238dcc3SJonas Devlieghere        )
33799451b44SJordan Rupprecht
33899451b44SJordan Rupprecht    def test_get_num_supported_hardware_watchpoints(self):
33999451b44SJordan Rupprecht        """Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process."""
34099451b44SJordan Rupprecht        self.build()
34199451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
34299451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
34399451b44SJordan Rupprecht
34499451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
34599451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
34699451b44SJordan Rupprecht
34799451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
34899451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
34999451b44SJordan Rupprecht
35099451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
3512238dcc3SJonas Devlieghere        process = target.LaunchSimple(None, None, self.get_process_working_directory())
35299451b44SJordan Rupprecht
35399451b44SJordan Rupprecht        error = lldb.SBError()
35499451b44SJordan Rupprecht        num = process.GetNumSupportedHardwareWatchpoints(error)
35599451b44SJordan Rupprecht        if self.TraceOn() and error.Success():
35699451b44SJordan Rupprecht            print("Number of supported hardware watchpoints: %d" % num)
35799451b44SJordan Rupprecht
35899451b44SJordan Rupprecht    @no_debug_info_test
35966b829acSJonas Devlieghere    @skipIfRemote
36099451b44SJordan Rupprecht    def test_get_process_info(self):
36199451b44SJordan Rupprecht        """Test SBProcess::GetProcessInfo() API with a locally launched process."""
36299451b44SJordan Rupprecht        self.build()
36399451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
36499451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
36599451b44SJordan Rupprecht
36699451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
36799451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
36899451b44SJordan Rupprecht
36999451b44SJordan Rupprecht        # Launch the process and stop at the entry point.
37086aa8e63SJonas Devlieghere        launch_info = target.GetLaunchInfo()
37199451b44SJordan Rupprecht        launch_info.SetWorkingDirectory(self.get_process_working_directory())
37299451b44SJordan Rupprecht        launch_flags = launch_info.GetLaunchFlags()
37399451b44SJordan Rupprecht        launch_flags |= lldb.eLaunchFlagStopAtEntry
37499451b44SJordan Rupprecht        launch_info.SetLaunchFlags(launch_flags)
37599451b44SJordan Rupprecht        error = lldb.SBError()
37699451b44SJordan Rupprecht        process = target.Launch(launch_info, error)
37799451b44SJordan Rupprecht
37899451b44SJordan Rupprecht        if not error.Success():
37999451b44SJordan Rupprecht            self.fail("Failed to launch process")
38099451b44SJordan Rupprecht
38199451b44SJordan Rupprecht        # Verify basic process info can be retrieved successfully
38299451b44SJordan Rupprecht        process_info = process.GetProcessInfo()
38399451b44SJordan Rupprecht        self.assertTrue(process_info.IsValid())
38499451b44SJordan Rupprecht        file_spec = process_info.GetExecutableFile()
38599451b44SJordan Rupprecht        self.assertTrue(file_spec.IsValid())
38699451b44SJordan Rupprecht        process_name = process_info.GetName()
38799451b44SJordan Rupprecht        self.assertIsNotNone(process_name, "Process has a name")
38899451b44SJordan Rupprecht        self.assertGreater(len(process_name), 0, "Process name isn't blank")
38999451b44SJordan Rupprecht        self.assertEqual(file_spec.GetFilename(), "a.out")
39099451b44SJordan Rupprecht        self.assertNotEqual(
3912238dcc3SJonas Devlieghere            process_info.GetProcessID(),
3922238dcc3SJonas Devlieghere            lldb.LLDB_INVALID_PROCESS_ID,
3932238dcc3SJonas Devlieghere            "Process ID is valid",
3942238dcc3SJonas Devlieghere        )
395251a5d9dSBruce Mitchener        triple = process_info.GetTriple()
396251a5d9dSBruce Mitchener        self.assertIsNotNone(triple, "Process has a triple")
39799451b44SJordan Rupprecht
39899451b44SJordan Rupprecht        # Additional process info varies by platform, so just check that
39999451b44SJordan Rupprecht        # whatever info was retrieved is consistent and nothing blows up.
40099451b44SJordan Rupprecht        if process_info.UserIDIsValid():
40199451b44SJordan Rupprecht            self.assertNotEqual(
4022238dcc3SJonas Devlieghere                process_info.GetUserID(), lldb.UINT32_MAX, "Process user ID is valid"
4032238dcc3SJonas Devlieghere            )
40499451b44SJordan Rupprecht        else:
40599451b44SJordan Rupprecht            self.assertEqual(
4062238dcc3SJonas Devlieghere                process_info.GetUserID(), lldb.UINT32_MAX, "Process user ID is invalid"
4072238dcc3SJonas Devlieghere            )
40899451b44SJordan Rupprecht
40999451b44SJordan Rupprecht        if process_info.GroupIDIsValid():
41099451b44SJordan Rupprecht            self.assertNotEqual(
4112238dcc3SJonas Devlieghere                process_info.GetGroupID(), lldb.UINT32_MAX, "Process group ID is valid"
4122238dcc3SJonas Devlieghere            )
41399451b44SJordan Rupprecht        else:
41499451b44SJordan Rupprecht            self.assertEqual(
4152238dcc3SJonas Devlieghere                process_info.GetGroupID(),
4162238dcc3SJonas Devlieghere                lldb.UINT32_MAX,
4172238dcc3SJonas Devlieghere                "Process group ID is invalid",
4182238dcc3SJonas Devlieghere            )
41999451b44SJordan Rupprecht
42099451b44SJordan Rupprecht        if process_info.EffectiveUserIDIsValid():
42199451b44SJordan Rupprecht            self.assertNotEqual(
4222238dcc3SJonas Devlieghere                process_info.GetEffectiveUserID(),
4232238dcc3SJonas Devlieghere                lldb.UINT32_MAX,
4242238dcc3SJonas Devlieghere                "Process effective user ID is valid",
4252238dcc3SJonas Devlieghere            )
42699451b44SJordan Rupprecht        else:
42799451b44SJordan Rupprecht            self.assertEqual(
4282238dcc3SJonas Devlieghere                process_info.GetEffectiveUserID(),
4292238dcc3SJonas Devlieghere                lldb.UINT32_MAX,
4302238dcc3SJonas Devlieghere                "Process effective user ID is invalid",
4312238dcc3SJonas Devlieghere            )
43299451b44SJordan Rupprecht
43399451b44SJordan Rupprecht        if process_info.EffectiveGroupIDIsValid():
43499451b44SJordan Rupprecht            self.assertNotEqual(
4352238dcc3SJonas Devlieghere                process_info.GetEffectiveGroupID(),
4362238dcc3SJonas Devlieghere                lldb.UINT32_MAX,
4372238dcc3SJonas Devlieghere                "Process effective group ID is valid",
4382238dcc3SJonas Devlieghere            )
43999451b44SJordan Rupprecht        else:
44099451b44SJordan Rupprecht            self.assertEqual(
4412238dcc3SJonas Devlieghere                process_info.GetEffectiveGroupID(),
4422238dcc3SJonas Devlieghere                lldb.UINT32_MAX,
4432238dcc3SJonas Devlieghere                "Process effective group ID is invalid",
4442238dcc3SJonas Devlieghere            )
44599451b44SJordan Rupprecht
44699451b44SJordan Rupprecht        process_info.GetParentProcessID()
4472e7ec447SPeter S. Housel
4482e7ec447SPeter S. Housel    def test_allocate_deallocate_memory(self):
4492e7ec447SPeter S. Housel        """Test Python SBProcess.AllocateMemory() and SBProcess.DeallocateMemory() APIs."""
4502e7ec447SPeter S. Housel        self.build()
4512238dcc3SJonas Devlieghere        (
4522238dcc3SJonas Devlieghere            target,
4532238dcc3SJonas Devlieghere            process,
4542238dcc3SJonas Devlieghere            main_thread,
4552238dcc3SJonas Devlieghere            main_breakpoint,
4562238dcc3SJonas Devlieghere        ) = lldbutil.run_to_source_breakpoint(
4572238dcc3SJonas Devlieghere            self, "// Set break point at this line", lldb.SBFileSpec("main.cpp")
4582238dcc3SJonas Devlieghere        )
4592e7ec447SPeter S. Housel
4602e7ec447SPeter S. Housel        # Allocate a block of memory in the target process
4612e7ec447SPeter S. Housel        error = lldb.SBError()
4622e7ec447SPeter S. Housel        addr = process.AllocateMemory(16384, lldb.ePermissionsReadable, error)
4632e7ec447SPeter S. Housel        if not error.Success() or addr == lldb.LLDB_INVALID_ADDRESS:
4642e7ec447SPeter S. Housel            self.fail("SBProcess.AllocateMemory() failed")
4652e7ec447SPeter S. Housel
4662e7ec447SPeter S. Housel        # Now use WriteMemory() API to write 'a' into the allocated
4672e7ec447SPeter S. Housel        # memory. Note that the debugger can do this even though the
4682e7ec447SPeter S. Housel        # block is not set writable.
4692238dcc3SJonas Devlieghere        result = process.WriteMemory(addr, "a", error)
4702e7ec447SPeter S. Housel        if not error.Success() or result != 1:
4712e7ec447SPeter S. Housel            self.fail("SBProcess.WriteMemory() failed")
4722e7ec447SPeter S. Housel
4732e7ec447SPeter S. Housel        # Read from the memory location.  This time it should be 'a'.
4742e7ec447SPeter S. Housel        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
4752e7ec447SPeter S. Housel        # expect to get a Python string as the result object!
4762e7ec447SPeter S. Housel        content = process.ReadMemory(addr, 1, error)
4772e7ec447SPeter S. Housel        if not error.Success():
4782e7ec447SPeter S. Housel            self.fail("SBProcess.ReadMemory() failed")
4792e7ec447SPeter S. Housel        if self.TraceOn():
4802e7ec447SPeter S. Housel            print("memory content:", content)
4812e7ec447SPeter S. Housel
4822e7ec447SPeter S. Housel        self.expect(
4832e7ec447SPeter S. Housel            content,
4842e7ec447SPeter S. Housel            "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
4852e7ec447SPeter S. Housel            exe=False,
4862238dcc3SJonas Devlieghere            startstr=b"a",
4872238dcc3SJonas Devlieghere        )
4882e7ec447SPeter S. Housel
4892e7ec447SPeter S. Housel        # Verify that the process itself can read the allocated memory
4902e7ec447SPeter S. Housel        frame = main_thread.GetFrameAtIndex(0)
4912e7ec447SPeter S. Housel        val = frame.EvaluateExpression(
4922238dcc3SJonas Devlieghere            "test_read(reinterpret_cast<char *>({:#x}))".format(addr)
4932238dcc3SJonas Devlieghere        )
4942238dcc3SJonas Devlieghere        self.expect(
4952238dcc3SJonas Devlieghere            val.GetValue(),
4962e7ec447SPeter S. Housel            "Result of test_read() matches expected output 'a'",
4972e7ec447SPeter S. Housel            exe=False,
4982238dcc3SJonas Devlieghere            startstr="'a'",
4992238dcc3SJonas Devlieghere        )
5002e7ec447SPeter S. Housel
5012e7ec447SPeter S. Housel        # Verify that the process cannot write into the block
5022e7ec447SPeter S. Housel        val = frame.EvaluateExpression(
5032238dcc3SJonas Devlieghere            "test_write(reinterpret_cast<char *>({:#x}), 'b')".format(addr)
5042238dcc3SJonas Devlieghere        )
5052e7ec447SPeter S. Housel        if val.GetError().Success():
5062e7ec447SPeter S. Housel            self.fail(
5072238dcc3SJonas Devlieghere                "test_write() to allocated memory without write permission unexpectedly succeeded"
5082238dcc3SJonas Devlieghere            )
5092e7ec447SPeter S. Housel
5102e7ec447SPeter S. Housel        # Deallocate the memory
5112e7ec447SPeter S. Housel        error = process.DeallocateMemory(addr)
5122e7ec447SPeter S. Housel        if not error.Success():
5132e7ec447SPeter S. Housel            self.fail("SBProcess.DeallocateMemory() failed")
514