199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest SBProcess APIs, including ReadMemory(), WriteMemory(), and others.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtfrom __future__ import print_function
699451b44SJordan Rupprecht
799451b44SJordan Rupprecht
899451b44SJordan Rupprechtimport lldb
999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1199451b44SJordan Rupprechtfrom lldbsuite.test.lldbutil import get_stopped_thread, state_type_to_str
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtclass ProcessAPITestCase(TestBase):
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprecht    def setUp(self):
1799451b44SJordan Rupprecht        # Call super's setUp().
1899451b44SJordan Rupprecht        TestBase.setUp(self)
1999451b44SJordan Rupprecht        # Find the line number to break inside main().
2099451b44SJordan Rupprecht        self.line = line_number(
2199451b44SJordan Rupprecht            "main.cpp",
2299451b44SJordan Rupprecht            "// Set break point at this line and check variable 'my_char'.")
2399451b44SJordan Rupprecht
2499451b44SJordan Rupprecht    def test_read_memory(self):
2599451b44SJordan Rupprecht        """Test Python SBProcess.ReadMemory() API."""
2699451b44SJordan Rupprecht        self.build()
2799451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
2899451b44SJordan Rupprecht
2999451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
3099451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
3199451b44SJordan Rupprecht
3299451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
3399451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
3499451b44SJordan Rupprecht
3599451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
3699451b44SJordan Rupprecht        process = target.LaunchSimple(
3799451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
4099451b44SJordan Rupprecht        self.assertTrue(
4199451b44SJordan Rupprecht            thread.IsValid(),
4299451b44SJordan Rupprecht            "There should be a thread stopped due to breakpoint")
4399451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_char'.
4699451b44SJordan Rupprecht        val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
4799451b44SJordan Rupprecht        self.DebugSBValue(val)
4899451b44SJordan Rupprecht
4999451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
5099451b44SJordan Rupprecht        # expect to get a Python string as the result object!
5199451b44SJordan Rupprecht        error = lldb.SBError()
5299451b44SJordan Rupprecht        self.assertFalse(val.TypeIsPointerType())
5399451b44SJordan Rupprecht        content = process.ReadMemory(
5499451b44SJordan Rupprecht            val.AddressOf().GetValueAsUnsigned(), 1, error)
5599451b44SJordan Rupprecht        if not error.Success():
5699451b44SJordan Rupprecht            self.fail("SBProcess.ReadMemory() failed")
5799451b44SJordan Rupprecht        if self.TraceOn():
5899451b44SJordan Rupprecht            print("memory content:", content)
5999451b44SJordan Rupprecht
6099451b44SJordan Rupprecht        self.expect(
6199451b44SJordan Rupprecht            content,
6299451b44SJordan Rupprecht            "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
6399451b44SJordan Rupprecht            exe=False,
6499451b44SJordan Rupprecht            startstr=b'x')
6599451b44SJordan Rupprecht
6699451b44SJordan Rupprecht        # Read (char *)my_char_ptr.
6799451b44SJordan Rupprecht        val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal)
6899451b44SJordan Rupprecht        self.DebugSBValue(val)
6999451b44SJordan Rupprecht        cstring = process.ReadCStringFromMemory(
7099451b44SJordan Rupprecht            val.GetValueAsUnsigned(), 256, error)
7199451b44SJordan Rupprecht        if not error.Success():
7299451b44SJordan Rupprecht            self.fail("SBProcess.ReadCStringFromMemory() failed")
7399451b44SJordan Rupprecht        if self.TraceOn():
7499451b44SJordan Rupprecht            print("cstring read is:", cstring)
7599451b44SJordan Rupprecht
7699451b44SJordan Rupprecht        self.expect(
7799451b44SJordan Rupprecht            cstring,
7899451b44SJordan Rupprecht            "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
7999451b44SJordan Rupprecht            exe=False,
8099451b44SJordan Rupprecht            startstr='Does it work?')
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_cstring'.
8399451b44SJordan Rupprecht        val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
8499451b44SJordan Rupprecht        self.DebugSBValue(val)
8599451b44SJordan Rupprecht
8699451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes
8799451b44SJordan Rupprecht        # from the address, and expect to get a Python string as the result
8899451b44SJordan Rupprecht        # object!
8999451b44SJordan Rupprecht        self.assertFalse(val.TypeIsPointerType())
9099451b44SJordan Rupprecht        cstring = process.ReadCStringFromMemory(
9199451b44SJordan Rupprecht            val.AddressOf().GetValueAsUnsigned(), 256, error)
9299451b44SJordan Rupprecht        if not error.Success():
9399451b44SJordan Rupprecht            self.fail("SBProcess.ReadCStringFromMemory() failed")
9499451b44SJordan Rupprecht        if self.TraceOn():
9599451b44SJordan Rupprecht            print("cstring read is:", cstring)
9699451b44SJordan Rupprecht
9799451b44SJordan Rupprecht        self.expect(
9899451b44SJordan Rupprecht            cstring,
9999451b44SJordan Rupprecht            "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
10099451b44SJordan Rupprecht            exe=False,
10199451b44SJordan Rupprecht            startstr='lldb.SBProcess.ReadCStringFromMemory() works!')
10299451b44SJordan Rupprecht
10399451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_uint32'.
10499451b44SJordan Rupprecht        val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal)
10599451b44SJordan Rupprecht        self.DebugSBValue(val)
10699451b44SJordan Rupprecht
10799451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 4 to read 4 bytes
10899451b44SJordan Rupprecht        # from the address, and expect to get an int as the result!
10999451b44SJordan Rupprecht        self.assertFalse(val.TypeIsPointerType())
11099451b44SJordan Rupprecht        my_uint32 = process.ReadUnsignedFromMemory(
11199451b44SJordan Rupprecht            val.AddressOf().GetValueAsUnsigned(), 4, error)
11299451b44SJordan Rupprecht        if not error.Success():
11399451b44SJordan Rupprecht            self.fail("SBProcess.ReadCStringFromMemory() failed")
11499451b44SJordan Rupprecht        if self.TraceOn():
11599451b44SJordan Rupprecht            print("uint32 read is:", my_uint32)
11699451b44SJordan Rupprecht
11799451b44SJordan Rupprecht        if my_uint32 != 12345:
11899451b44SJordan Rupprecht            self.fail(
11999451b44SJordan Rupprecht                "Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output")
12099451b44SJordan Rupprecht
12199451b44SJordan Rupprecht    def test_write_memory(self):
12299451b44SJordan Rupprecht        """Test Python SBProcess.WriteMemory() API."""
12399451b44SJordan Rupprecht        self.build()
12499451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
12599451b44SJordan Rupprecht
12699451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
12799451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
12899451b44SJordan Rupprecht
12999451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
13099451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
13199451b44SJordan Rupprecht
13299451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
13399451b44SJordan Rupprecht        process = target.LaunchSimple(
13499451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
13599451b44SJordan Rupprecht
13699451b44SJordan Rupprecht        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
13799451b44SJordan Rupprecht        self.assertTrue(
13899451b44SJordan Rupprecht            thread.IsValid(),
13999451b44SJordan Rupprecht            "There should be a thread stopped due to breakpoint")
14099451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
14199451b44SJordan Rupprecht
14299451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_char'.
14399451b44SJordan Rupprecht        val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
14499451b44SJordan Rupprecht        self.DebugSBValue(val)
14599451b44SJordan Rupprecht
14699451b44SJordan Rupprecht        # If the variable does not have a load address, there's no sense
14799451b44SJordan Rupprecht        # continuing.
14899451b44SJordan Rupprecht        if not val.GetLocation().startswith("0x"):
14999451b44SJordan Rupprecht            return
15099451b44SJordan Rupprecht
15199451b44SJordan Rupprecht        # OK, let's get the hex location of the variable.
15299451b44SJordan Rupprecht        location = int(val.GetLocation(), 16)
15399451b44SJordan Rupprecht
15499451b44SJordan Rupprecht        # The program logic makes the 'my_char' variable to have memory content as 'x'.
15599451b44SJordan Rupprecht        # But we want to use the WriteMemory() API to assign 'a' to the
15699451b44SJordan Rupprecht        # variable.
15799451b44SJordan Rupprecht
15899451b44SJordan Rupprecht        # Now use WriteMemory() API to write 'a' into the global variable.
15999451b44SJordan Rupprecht        error = lldb.SBError()
16099451b44SJordan Rupprecht        result = process.WriteMemory(location, 'a', error)
16199451b44SJordan Rupprecht        if not error.Success() or result != 1:
16299451b44SJordan Rupprecht            self.fail("SBProcess.WriteMemory() failed")
16399451b44SJordan Rupprecht
16499451b44SJordan Rupprecht        # Read from the memory location.  This time it should be 'a'.
16599451b44SJordan Rupprecht        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
16699451b44SJordan Rupprecht        # expect to get a Python string as the result object!
16799451b44SJordan Rupprecht        content = process.ReadMemory(location, 1, error)
16899451b44SJordan Rupprecht        if not error.Success():
16999451b44SJordan Rupprecht            self.fail("SBProcess.ReadMemory() failed")
17099451b44SJordan Rupprecht        if self.TraceOn():
17199451b44SJordan Rupprecht            print("memory content:", content)
17299451b44SJordan Rupprecht
17399451b44SJordan Rupprecht        self.expect(
17499451b44SJordan Rupprecht            content,
17599451b44SJordan Rupprecht            "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
17699451b44SJordan Rupprecht            exe=False,
17799451b44SJordan Rupprecht            startstr=b'a')
17899451b44SJordan Rupprecht
17999451b44SJordan Rupprecht    def test_access_my_int(self):
18099451b44SJordan Rupprecht        """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
18199451b44SJordan Rupprecht        self.build()
18299451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
18399451b44SJordan Rupprecht
18499451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
18599451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
18699451b44SJordan Rupprecht
18799451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
18899451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
18999451b44SJordan Rupprecht
19099451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
19199451b44SJordan Rupprecht        process = target.LaunchSimple(
19299451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
19399451b44SJordan Rupprecht
19499451b44SJordan Rupprecht        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
19599451b44SJordan Rupprecht        self.assertTrue(
19699451b44SJordan Rupprecht            thread.IsValid(),
19799451b44SJordan Rupprecht            "There should be a thread stopped due to breakpoint")
19899451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
19999451b44SJordan Rupprecht
20099451b44SJordan Rupprecht        # Get the SBValue for the global variable 'my_int'.
20199451b44SJordan Rupprecht        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
20299451b44SJordan Rupprecht        self.DebugSBValue(val)
20399451b44SJordan Rupprecht
20499451b44SJordan Rupprecht        # If the variable does not have a load address, there's no sense
20599451b44SJordan Rupprecht        # continuing.
20699451b44SJordan Rupprecht        if not val.GetLocation().startswith("0x"):
20799451b44SJordan Rupprecht            return
20899451b44SJordan Rupprecht
20999451b44SJordan Rupprecht        # OK, let's get the hex location of the variable.
21099451b44SJordan Rupprecht        location = int(val.GetLocation(), 16)
21199451b44SJordan Rupprecht
21299451b44SJordan Rupprecht        # Note that the canonical from of the bytearray is little endian.
21399451b44SJordan Rupprecht        from lldbsuite.test.lldbutil import int_to_bytearray, bytearray_to_int
21499451b44SJordan Rupprecht
21599451b44SJordan Rupprecht        byteSize = val.GetByteSize()
21699451b44SJordan Rupprecht        bytes = int_to_bytearray(256, byteSize)
21799451b44SJordan Rupprecht
21899451b44SJordan Rupprecht        byteOrder = process.GetByteOrder()
21999451b44SJordan Rupprecht        if byteOrder == lldb.eByteOrderBig:
22099451b44SJordan Rupprecht            bytes.reverse()
22199451b44SJordan Rupprecht        elif byteOrder == lldb.eByteOrderLittle:
22299451b44SJordan Rupprecht            pass
22399451b44SJordan Rupprecht        else:
22499451b44SJordan Rupprecht            # Neither big endian nor little endian?  Return for now.
22599451b44SJordan Rupprecht            # Add more logic here if we want to handle other types.
22699451b44SJordan Rupprecht            return
22799451b44SJordan Rupprecht
22899451b44SJordan Rupprecht        # The program logic makes the 'my_int' variable to have int type and value of 0.
22999451b44SJordan Rupprecht        # But we want to use the WriteMemory() API to assign 256 to the
23099451b44SJordan Rupprecht        # variable.
23199451b44SJordan Rupprecht
23299451b44SJordan Rupprecht        # Now use WriteMemory() API to write 256 into the global variable.
23399451b44SJordan Rupprecht        error = lldb.SBError()
23499451b44SJordan Rupprecht        result = process.WriteMemory(location, bytes, error)
23599451b44SJordan Rupprecht        if not error.Success() or result != byteSize:
23699451b44SJordan Rupprecht            self.fail("SBProcess.WriteMemory() failed")
23799451b44SJordan Rupprecht
23899451b44SJordan Rupprecht        # Make sure that the val we got originally updates itself to notice the
23999451b44SJordan Rupprecht        # change:
24099451b44SJordan Rupprecht        self.expect(
24199451b44SJordan Rupprecht            val.GetValue(),
24299451b44SJordan Rupprecht            "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
24399451b44SJordan Rupprecht            exe=False,
24499451b44SJordan Rupprecht            startstr='256')
24599451b44SJordan Rupprecht
24699451b44SJordan Rupprecht        # And for grins, get the SBValue for the global variable 'my_int'
24799451b44SJordan Rupprecht        # again, to make sure that also tracks the new value:
24899451b44SJordan Rupprecht        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
24999451b44SJordan Rupprecht        self.expect(
25099451b44SJordan Rupprecht            val.GetValue(),
25199451b44SJordan Rupprecht            "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
25299451b44SJordan Rupprecht            exe=False,
25399451b44SJordan Rupprecht            startstr='256')
25499451b44SJordan Rupprecht
25599451b44SJordan Rupprecht        # Now read the memory content.  The bytearray should have (byte)1 as
25699451b44SJordan Rupprecht        # the second element.
25799451b44SJordan Rupprecht        content = process.ReadMemory(location, byteSize, error)
25899451b44SJordan Rupprecht        if not error.Success():
25999451b44SJordan Rupprecht            self.fail("SBProcess.ReadMemory() failed")
26099451b44SJordan Rupprecht
26199451b44SJordan Rupprecht        # The bytearray_to_int utility function expects a little endian
26299451b44SJordan Rupprecht        # bytearray.
26399451b44SJordan Rupprecht        if byteOrder == lldb.eByteOrderBig:
26499451b44SJordan Rupprecht            content = bytearray(content, 'ascii')
26599451b44SJordan Rupprecht            content.reverse()
26699451b44SJordan Rupprecht
26799451b44SJordan Rupprecht        new_value = bytearray_to_int(content, byteSize)
26899451b44SJordan Rupprecht        if new_value != 256:
26999451b44SJordan Rupprecht            self.fail("Memory content read from 'my_int' does not match (int)256")
27099451b44SJordan Rupprecht
27199451b44SJordan Rupprecht        # Dump the memory content....
27299451b44SJordan Rupprecht        if self.TraceOn():
27399451b44SJordan Rupprecht            for i in content:
27499451b44SJordan Rupprecht                print("byte:", i)
27599451b44SJordan Rupprecht
27699451b44SJordan Rupprecht    def test_remote_launch(self):
27799451b44SJordan Rupprecht        """Test SBProcess.RemoteLaunch() API with a process not in eStateConnected, and it should fail."""
27899451b44SJordan Rupprecht        self.build()
27999451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
28099451b44SJordan Rupprecht
28199451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
28299451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
28399451b44SJordan Rupprecht
28499451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
28599451b44SJordan Rupprecht        process = target.LaunchSimple(
28699451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
28799451b44SJordan Rupprecht
28899451b44SJordan Rupprecht        if self.TraceOn():
28999451b44SJordan Rupprecht            print("process state:", state_type_to_str(process.GetState()))
29099451b44SJordan Rupprecht        self.assertTrue(process.GetState() != lldb.eStateConnected)
29199451b44SJordan Rupprecht
29299451b44SJordan Rupprecht        error = lldb.SBError()
29399451b44SJordan Rupprecht        success = process.RemoteLaunch(
29499451b44SJordan Rupprecht            None, None, None, None, None, None, 0, False, error)
29599451b44SJordan Rupprecht        self.assertTrue(
29699451b44SJordan Rupprecht            not success,
29799451b44SJordan Rupprecht            "RemoteLaunch() should fail for process state != eStateConnected")
29899451b44SJordan Rupprecht
29999451b44SJordan Rupprecht    def test_get_num_supported_hardware_watchpoints(self):
30099451b44SJordan Rupprecht        """Test SBProcess.GetNumSupportedHardwareWatchpoints() API with a process."""
30199451b44SJordan Rupprecht        self.build()
30299451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
30399451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
30499451b44SJordan Rupprecht
30599451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
30699451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
30799451b44SJordan Rupprecht
30899451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
30999451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
31099451b44SJordan Rupprecht
31199451b44SJordan Rupprecht        # Launch the process, and do not stop at the entry point.
31299451b44SJordan Rupprecht        process = target.LaunchSimple(
31399451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
31499451b44SJordan Rupprecht
31599451b44SJordan Rupprecht        error = lldb.SBError()
31699451b44SJordan Rupprecht        num = process.GetNumSupportedHardwareWatchpoints(error)
31799451b44SJordan Rupprecht        if self.TraceOn() and error.Success():
31899451b44SJordan Rupprecht            print("Number of supported hardware watchpoints: %d" % num)
31999451b44SJordan Rupprecht
32099451b44SJordan Rupprecht    @no_debug_info_test
321*66b829acSJonas Devlieghere    @skipIfRemote
32299451b44SJordan Rupprecht    def test_get_process_info(self):
32399451b44SJordan Rupprecht        """Test SBProcess::GetProcessInfo() API with a locally launched process."""
32499451b44SJordan Rupprecht        self.build()
32599451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
32699451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
32799451b44SJordan Rupprecht
32899451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
32999451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
33099451b44SJordan Rupprecht
33199451b44SJordan Rupprecht        # Launch the process and stop at the entry point.
33286aa8e63SJonas Devlieghere        launch_info = target.GetLaunchInfo()
33399451b44SJordan Rupprecht        launch_info.SetWorkingDirectory(self.get_process_working_directory())
33499451b44SJordan Rupprecht        launch_flags = launch_info.GetLaunchFlags()
33599451b44SJordan Rupprecht        launch_flags |= lldb.eLaunchFlagStopAtEntry
33699451b44SJordan Rupprecht        launch_info.SetLaunchFlags(launch_flags)
33799451b44SJordan Rupprecht        error = lldb.SBError()
33899451b44SJordan Rupprecht        process = target.Launch(launch_info, error)
33999451b44SJordan Rupprecht
34099451b44SJordan Rupprecht        if not error.Success():
34199451b44SJordan Rupprecht            self.fail("Failed to launch process")
34299451b44SJordan Rupprecht
34399451b44SJordan Rupprecht        # Verify basic process info can be retrieved successfully
34499451b44SJordan Rupprecht        process_info = process.GetProcessInfo()
34599451b44SJordan Rupprecht        self.assertTrue(process_info.IsValid())
34699451b44SJordan Rupprecht        file_spec = process_info.GetExecutableFile()
34799451b44SJordan Rupprecht        self.assertTrue(file_spec.IsValid())
34899451b44SJordan Rupprecht        process_name = process_info.GetName()
34999451b44SJordan Rupprecht        self.assertIsNotNone(process_name, "Process has a name")
35099451b44SJordan Rupprecht        self.assertGreater(len(process_name), 0, "Process name isn't blank")
35199451b44SJordan Rupprecht        self.assertEqual(file_spec.GetFilename(), "a.out")
35299451b44SJordan Rupprecht        self.assertNotEqual(
35399451b44SJordan Rupprecht            process_info.GetProcessID(), lldb.LLDB_INVALID_PROCESS_ID,
35499451b44SJordan Rupprecht            "Process ID is valid")
355251a5d9dSBruce Mitchener        triple = process_info.GetTriple()
356251a5d9dSBruce Mitchener        self.assertIsNotNone(triple, "Process has a triple")
35799451b44SJordan Rupprecht
35899451b44SJordan Rupprecht        # Additional process info varies by platform, so just check that
35999451b44SJordan Rupprecht        # whatever info was retrieved is consistent and nothing blows up.
36099451b44SJordan Rupprecht        if process_info.UserIDIsValid():
36199451b44SJordan Rupprecht            self.assertNotEqual(
36299451b44SJordan Rupprecht                process_info.GetUserID(), lldb.UINT32_MAX,
36399451b44SJordan Rupprecht                "Process user ID is valid")
36499451b44SJordan Rupprecht        else:
36599451b44SJordan Rupprecht            self.assertEqual(
36699451b44SJordan Rupprecht                process_info.GetUserID(), lldb.UINT32_MAX,
36799451b44SJordan Rupprecht                "Process user ID is invalid")
36899451b44SJordan Rupprecht
36999451b44SJordan Rupprecht        if process_info.GroupIDIsValid():
37099451b44SJordan Rupprecht            self.assertNotEqual(
37199451b44SJordan Rupprecht                process_info.GetGroupID(), lldb.UINT32_MAX,
37299451b44SJordan Rupprecht                "Process group ID is valid")
37399451b44SJordan Rupprecht        else:
37499451b44SJordan Rupprecht            self.assertEqual(
37599451b44SJordan Rupprecht                process_info.GetGroupID(), lldb.UINT32_MAX,
37699451b44SJordan Rupprecht                "Process group ID is invalid")
37799451b44SJordan Rupprecht
37899451b44SJordan Rupprecht        if process_info.EffectiveUserIDIsValid():
37999451b44SJordan Rupprecht            self.assertNotEqual(
38099451b44SJordan Rupprecht                process_info.GetEffectiveUserID(), lldb.UINT32_MAX,
38199451b44SJordan Rupprecht                "Process effective user ID is valid")
38299451b44SJordan Rupprecht        else:
38399451b44SJordan Rupprecht            self.assertEqual(
38499451b44SJordan Rupprecht                process_info.GetEffectiveUserID(), lldb.UINT32_MAX,
38599451b44SJordan Rupprecht                "Process effective user ID is invalid")
38699451b44SJordan Rupprecht
38799451b44SJordan Rupprecht        if process_info.EffectiveGroupIDIsValid():
38899451b44SJordan Rupprecht            self.assertNotEqual(
38999451b44SJordan Rupprecht                process_info.GetEffectiveGroupID(), lldb.UINT32_MAX,
39099451b44SJordan Rupprecht                "Process effective group ID is valid")
39199451b44SJordan Rupprecht        else:
39299451b44SJordan Rupprecht            self.assertEqual(
39399451b44SJordan Rupprecht                process_info.GetEffectiveGroupID(), lldb.UINT32_MAX,
39499451b44SJordan Rupprecht                "Process effective group ID is invalid")
39599451b44SJordan Rupprecht
39699451b44SJordan Rupprecht        process_info.GetParentProcessID()
3972e7ec447SPeter S. Housel
3982e7ec447SPeter S. Housel    def test_allocate_deallocate_memory(self):
3992e7ec447SPeter S. Housel        """Test Python SBProcess.AllocateMemory() and SBProcess.DeallocateMemory() APIs."""
4002e7ec447SPeter S. Housel        self.build()
4012e7ec447SPeter S. Housel        (target, process, main_thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(
4022e7ec447SPeter S. Housel            self, "// Set break point at this line", lldb.SBFileSpec("main.cpp"))
4032e7ec447SPeter S. Housel
4042e7ec447SPeter S. Housel        # Allocate a block of memory in the target process
4052e7ec447SPeter S. Housel        error = lldb.SBError()
4062e7ec447SPeter S. Housel        addr = process.AllocateMemory(16384, lldb.ePermissionsReadable, error)
4072e7ec447SPeter S. Housel        if not error.Success() or addr == lldb.LLDB_INVALID_ADDRESS:
4082e7ec447SPeter S. Housel            self.fail("SBProcess.AllocateMemory() failed")
4092e7ec447SPeter S. Housel
4102e7ec447SPeter S. Housel        # Now use WriteMemory() API to write 'a' into the allocated
4112e7ec447SPeter S. Housel        # memory. Note that the debugger can do this even though the
4122e7ec447SPeter S. Housel        # block is not set writable.
4132e7ec447SPeter S. Housel        result = process.WriteMemory(addr, 'a', error)
4142e7ec447SPeter S. Housel        if not error.Success() or result != 1:
4152e7ec447SPeter S. Housel            self.fail("SBProcess.WriteMemory() failed")
4162e7ec447SPeter S. Housel
4172e7ec447SPeter S. Housel        # Read from the memory location.  This time it should be 'a'.
4182e7ec447SPeter S. Housel        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
4192e7ec447SPeter S. Housel        # expect to get a Python string as the result object!
4202e7ec447SPeter S. Housel        content = process.ReadMemory(addr, 1, error)
4212e7ec447SPeter S. Housel        if not error.Success():
4222e7ec447SPeter S. Housel            self.fail("SBProcess.ReadMemory() failed")
4232e7ec447SPeter S. Housel        if self.TraceOn():
4242e7ec447SPeter S. Housel            print("memory content:", content)
4252e7ec447SPeter S. Housel
4262e7ec447SPeter S. Housel        self.expect(
4272e7ec447SPeter S. Housel            content,
4282e7ec447SPeter S. Housel            "Result from SBProcess.ReadMemory() matches our expected output: 'a'",
4292e7ec447SPeter S. Housel            exe=False,
4302e7ec447SPeter S. Housel            startstr=b'a')
4312e7ec447SPeter S. Housel
4322e7ec447SPeter S. Housel        # Verify that the process itself can read the allocated memory
4332e7ec447SPeter S. Housel        frame = main_thread.GetFrameAtIndex(0)
4342e7ec447SPeter S. Housel        val = frame.EvaluateExpression(
4352e7ec447SPeter S. Housel            "test_read(reinterpret_cast<char *>({:#x}))".format(addr))
4362e7ec447SPeter S. Housel        self.expect(val.GetValue(),
4372e7ec447SPeter S. Housel                    "Result of test_read() matches expected output 'a'",
4382e7ec447SPeter S. Housel                    exe=False,
4392e7ec447SPeter S. Housel                    startstr="'a'")
4402e7ec447SPeter S. Housel
4412e7ec447SPeter S. Housel        # Verify that the process cannot write into the block
4422e7ec447SPeter S. Housel        val = frame.EvaluateExpression(
4432e7ec447SPeter S. Housel            "test_write(reinterpret_cast<char *>({:#x}), 'b')".format(addr))
4442e7ec447SPeter S. Housel        if val.GetError().Success():
4452e7ec447SPeter S. Housel            self.fail(
4462e7ec447SPeter S. Housel                "test_write() to allocated memory without write permission unexpectedly succeeded")
4472e7ec447SPeter S. Housel
4482e7ec447SPeter S. Housel        # Deallocate the memory
4492e7ec447SPeter S. Housel        error = process.DeallocateMemory(addr)
4502e7ec447SPeter S. Housel        if not error.Success():
4512e7ec447SPeter S. Housel            self.fail("SBProcess.DeallocateMemory() failed")
452