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