Beispiel #1
0
    def test_watch_address(self):
        """Exercise SBTarget.WatchAddress() API to set a watchpoint."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Now create a breakpoint on main.c.
        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
        self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1,
                        VALID_BREAKPOINT)

        # Now launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None,
                                      self.get_process_working_directory())

        # We should be stopped due to the breakpoint.  Get frame #0.
        process = target.GetProcess()
        self.assertEqual(process.GetState(), lldb.eStateStopped,
                         PROCESS_STOPPED)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        frame0 = thread.GetFrameAtIndex(0)

        value = frame0.FindValue('g_char_ptr', lldb.eValueTypeVariableGlobal)
        pointee = value.CreateValueFromAddress(
            "pointee", value.GetValueAsUnsigned(0),
            value.GetType().GetPointeeType())
        # Watch for write to *g_char_ptr.
        error = lldb.SBError()
        watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False,
                                         True, error)
        self.assertTrue(value and watchpoint,
                        "Successfully found the pointer and set a watchpoint")
        self.DebugSBValue(value)
        self.DebugSBValue(pointee)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        print(watchpoint)

        # Continue.  Expect the program to stop due to the variable being
        # written to.
        process.Continue()

        if (self.TraceOn()):
            lldbutil.print_stacktraces(process)

        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonWatchpoint)
        self.assertTrue(thread, "The thread stopped due to watchpoint")
        self.DebugSBValue(value)
        self.DebugSBValue(pointee)

        self.expect(lldbutil.print_stacktrace(thread, string_buffer=True),
                    exe=False,
                    substrs=[self.violating_func])
Beispiel #2
0
    def test_read_memory(self):
        """Test Python SBProcess.ReadMemory() API."""
        self.build()
        exe = os.path.join(os.getcwd(), "a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Launch the process, and do not stop at the entry point.
        process = target.LaunchSimple (None, None, self.get_process_working_directory())

        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
        self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
        frame = thread.GetFrameAtIndex(0)

        # Get the SBValue for the global variable 'my_char'.
        val = frame.FindValue("my_char", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        # Due to the typemap magic (see lldb.swig), we pass in 1 to ReadMemory and
        # expect to get a Python string as the result object!
        error = lldb.SBError()
        self.assertFalse(val.TypeIsPointerType())
        content = process.ReadMemory(val.AddressOf().GetValueAsUnsigned(), 1, error)
        if not error.Success():
            self.fail("SBProcess.ReadMemory() failed")
        if self.TraceOn():
            print("memory content:", content)

        self.expect(content, "Result from SBProcess.ReadMemory() matches our expected output: 'x'",
                    exe=False,
            startstr = 'x')

        # Read (char *)my_char_ptr.
        val = frame.FindValue("my_char_ptr", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)
        cstring = process.ReadCStringFromMemory(val.GetValueAsUnsigned(), 256, error)
        if not error.Success():
            self.fail("SBProcess.ReadCStringFromMemory() failed")
        if self.TraceOn():
            print("cstring read is:", cstring)

        self.expect(cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
                    exe=False,
            startstr = 'Does it work?')

        # Get the SBValue for the global variable 'my_cstring'.
        val = frame.FindValue("my_cstring", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        # Due to the typemap magic (see lldb.swig), we pass in 256 to read at most 256 bytes
        # from the address, and expect to get a Python string as the result object!
        self.assertFalse(val.TypeIsPointerType())
        cstring = process.ReadCStringFromMemory(val.AddressOf().GetValueAsUnsigned(), 256, error)
        if not error.Success():
            self.fail("SBProcess.ReadCStringFromMemory() failed")
        if self.TraceOn():
            print("cstring read is:", cstring)

        self.expect(cstring, "Result from SBProcess.ReadCStringFromMemory() matches our expected output",
                    exe=False,
            startstr = 'lldb.SBProcess.ReadCStringFromMemory() works!')

        # Get the SBValue for the global variable 'my_uint32'.
        val = frame.FindValue("my_uint32", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        # Due to the typemap magic (see lldb.swig), we pass in 4 to read 4 bytes
        # from the address, and expect to get an int as the result!
        self.assertFalse(val.TypeIsPointerType())
        my_uint32 = process.ReadUnsignedFromMemory(val.AddressOf().GetValueAsUnsigned(), 4, error)
        if not error.Success():
            self.fail("SBProcess.ReadCStringFromMemory() failed")
        if self.TraceOn():
            print("uint32 read is:", my_uint32)

        if my_uint32 != 12345:
            self.fail("Result from SBProcess.ReadUnsignedFromMemory() does not match our expected output")
    def address_breakpoints(self):
        """Test address breakpoints set with shared library of SBAddress work correctly."""
        exe = os.path.join(os.getcwd(), "a.out")

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Now create a breakpoint on main.c by name 'c'.
        breakpoint = target.BreakpointCreateBySourceRegex(
            "Set a breakpoint here", lldb.SBFileSpec("main.c"))
        self.assertTrue(breakpoint and breakpoint.GetNumLocations() >= 1,
                        VALID_BREAKPOINT)

        # Get the breakpoint location from breakpoint after we verified that,
        # indeed, it has one location.
        location = breakpoint.GetLocationAtIndex(0)
        self.assertTrue(location and location.IsEnabled(),
                        VALID_BREAKPOINT_LOCATION)

        # Next get the address from the location, and create an address breakpoint using
        # that address:

        address = location.GetAddress()
        target.BreakpointDelete(breakpoint.GetID())

        breakpoint = target.BreakpointCreateBySBAddress(address)

        # Disable ASLR.  This will allow us to actually test (on platforms that support this flag)
        # that the breakpoint was able to track the module.

        launch_info = lldb.SBLaunchInfo(None)
        flags = launch_info.GetLaunchFlags()
        flags &= ~lldb.eLaunchFlagDisableASLR
        launch_info.SetLaunchFlags(flags)

        error = lldb.SBError()

        process = target.Launch(launch_info, error)
        self.assertTrue(process, PROCESS_IS_VALID)

        # Did we hit our breakpoint?
        from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
        threads = get_threads_stopped_at_breakpoint(process, breakpoint)
        self.assertTrue(
            len(threads) == 1,
            "There should be a thread stopped at our breakpoint")

        # The hit count for the breakpoint should be 1.
        self.assertTrue(breakpoint.GetHitCount() == 1)

        process.Kill()

        # Now re-launch and see that we hit the breakpoint again:
        launch_info.Clear()
        launch_info.SetLaunchFlags(flags)

        process = target.Launch(launch_info, error)
        self.assertTrue(process, PROCESS_IS_VALID)

        thread = get_threads_stopped_at_breakpoint(process, breakpoint)
        self.assertTrue(
            len(threads) == 1,
            "There should be a thread stopped at our breakpoint")

        # The hit count for the breakpoint should now be 2.
        self.assertTrue(breakpoint.GetHitCount() == 2)
Beispiel #4
0
    def test_with_run_command(self):
        """Test the SBData APIs."""
        self.build()
        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)

        lldbutil.run_break_set_by_file_and_line(
            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)

        self.runCmd("run", RUN_SUCCEEDED)

        # The stop reason of the thread should be breakpoint.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                    substrs=['stopped',
                             'stop reason = breakpoint'])

        target = self.dbg.GetSelectedTarget()

        process = target.GetProcess()

        thread = lldbutil.get_stopped_thread(
            process, lldb.eStopReasonBreakpoint)
        self.assertIsNotNone(thread)

        frame = thread.GetSelectedFrame()
        if self.TraceOn():
            print(frame)
        foobar = frame.FindVariable('foobar')
        self.assertTrue(foobar.IsValid())
        if self.TraceOn():
            print(foobar)

        data = foobar.GetPointeeData(0, 2)
        offset = 0
        error = lldb.SBError()

        self.assert_data(data.GetUnsignedInt32, offset, 1)
        offset += 4
        low = data.GetSignedInt16(error, offset)
        self.assertTrue(error.Success())
        offset += 2
        high = data.GetSignedInt16(error, offset)
        self.assertTrue(error.Success())
        offset += 2
        self.assertTrue(
            (low == 9 and high == 0) or (
                low == 0 and high == 9),
            'foo[0].b == 9')
        self.assertTrue(
            fabs(
                data.GetFloat(
                    error,
                    offset) -
                3.14) < 1,
            'foo[0].c == 3.14')
        self.assertTrue(error.Success())
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 8)
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 5)
        offset += 4

        self.runCmd("n")

        offset = 16

        self.assert_data(data.GetUnsignedInt32, offset, 5)

        data = foobar.GetPointeeData(1, 1)

        offset = 0

        self.assert_data(data.GetSignedInt32, offset, 8)
        offset += 4
        self.assert_data(data.GetSignedInt32, offset, 7)
        offset += 8
        self.assertTrue(
            data.GetUnsignedInt32(
                error,
                offset) == 0,
            'do not read beyond end')
        self.assertTrue(not error.Success())
        error.Clear()  # clear the error for the next test

        star_foobar = foobar.Dereference()
        self.assertTrue(star_foobar.IsValid())

        data = star_foobar.GetData()

        if self.TraceOn():
            print(data)

        offset = 0
        self.assert_data(data.GetUnsignedInt32, offset, 1)
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 9)

        foobar_addr = star_foobar.GetLoadAddress()
        foobar_addr += 12

        # http://llvm.org/bugs/show_bug.cgi?id=11579
        # lldb::SBValue::CreateValueFromAddress does not verify SBType::GetPointerType succeeds
        # This should not crash LLDB.
        nothing = foobar.CreateValueFromAddress(
            "nothing", foobar_addr, star_foobar.GetType().GetBasicType(
                lldb.eBasicTypeInvalid))

        new_foobar = foobar.CreateValueFromAddress(
            "f00", foobar_addr, star_foobar.GetType())
        self.assertTrue(new_foobar.IsValid())
        if self.TraceOn():
            print(new_foobar)

        data = new_foobar.GetData()

        if self.TraceOn():
            print(data)

        self.assertTrue(data.uint32[0] == 8, 'then foo[1].a == 8')
        self.assertTrue(data.uint32[1] == 7, 'then foo[1].b == 7')
        # exploiting that sizeof(uint32) == sizeof(float)
        self.assertTrue(fabs(data.float[2] - 3.14) < 1, 'foo[1].c == 3.14')

        self.runCmd("n")

        offset = 0
        self.assert_data(data.GetUnsignedInt32, offset, 8)
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 7)
        offset += 4
        self.assertTrue(
            fabs(
                data.GetFloat(
                    error,
                    offset) -
                3.14) < 1,
            'foo[1].c == 3.14')
        self.assertTrue(error.Success())

        data = new_foobar.GetData()

        if self.TraceOn():
            print(data)

        offset = 0
        self.assert_data(data.GetUnsignedInt32, offset, 8)
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 7)
        offset += 4
        self.assertTrue(
            fabs(
                data.GetFloat(
                    error,
                    offset) -
                6.28) < 1,
            'foo[1].c == 6.28')
        self.assertTrue(error.Success())

        self.runCmd("n")

        barfoo = frame.FindVariable('barfoo')

        data = barfoo.GetData()

        if self.TraceOn():
            print(barfoo)

        if self.TraceOn():
            print(data)

        offset = 0
        self.assert_data(data.GetUnsignedInt32, offset, 1)
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 2)
        offset += 4
        self.assertTrue(
            fabs(
                data.GetFloat(
                    error,
                    offset) -
                3) < 1,
            'barfoo[0].c == 3')
        self.assertTrue(error.Success())
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 4)
        offset += 4
        self.assert_data(data.GetUnsignedInt32, offset, 5)
        offset += 4
        self.assertTrue(
            fabs(
                data.GetFloat(
                    error,
                    offset) -
                6) < 1,
            'barfoo[1].c == 6')
        self.assertTrue(error.Success())

        new_object = barfoo.CreateValueFromData(
            "new_object", data, barfoo.GetType().GetBasicType(
                lldb.eBasicTypeInt))

        if self.TraceOn():
            print(new_object)

        self.assertTrue(new_object.GetValue() == "1", 'new_object == 1')

        if data.GetByteOrder() == lldb.eByteOrderBig:
            data.SetData(
                error,
                '\0\0\0A',
                data.GetByteOrder(),
                data.GetAddressByteSize())
        else:
            data.SetData(
                error,
                'A\0\0\0',
                data.GetByteOrder(),
                data.GetAddressByteSize())
        self.assertTrue(error.Success())

        data2 = lldb.SBData()
        data2.SetData(
            error,
            'BCD',
            data.GetByteOrder(),
            data.GetAddressByteSize())
        self.assertTrue(error.Success())

        data.Append(data2)

        if self.TraceOn():
            print(data)

        # this breaks on EBCDIC
        offset = 0
        self.assert_data(data.GetUnsignedInt32, offset, 65)
        offset += 4
        self.assert_data(data.GetUnsignedInt8, offset, 66)
        offset += 1
        self.assert_data(data.GetUnsignedInt8, offset, 67)
        offset += 1
        self.assert_data(data.GetUnsignedInt8, offset, 68)
        offset += 1

        # check the new API calls introduced per LLVM llvm.org/prenhancement request
        # 11619 (Allow creating SBData values from arrays or primitives in
        # Python)

        hello_str = "hello!"
        data2 = lldb.SBData.CreateDataFromCString(
            process.GetByteOrder(), process.GetAddressByteSize(), hello_str)
        self.assertTrue(len(data2.uint8) == len(hello_str))
        self.assertTrue(data2.uint8[0] == 104, 'h == 104')
        self.assertTrue(data2.uint8[1] == 101, 'e == 101')
        self.assertTrue(data2.uint8[2] == 108, 'l == 108')
        self.assert_data(data2.GetUnsignedInt8, 3, 108)  # l
        self.assertTrue(data2.uint8[4] == 111, 'o == 111')
        self.assert_data(data2.GetUnsignedInt8, 5, 33)  # !

        uint_lists = [[1, 2, 3, 4, 5], [int(i) for i in [1, 2, 3, 4, 5]]]
        int_lists = [[2, -2], [int(i) for i in [2, -2]]]

        for l in uint_lists:
            data2 = lldb.SBData.CreateDataFromUInt64Array(
                process.GetByteOrder(), process.GetAddressByteSize(), l)
            self.assert_data(data2.GetUnsignedInt64, 0, 1)
            self.assert_data(data2.GetUnsignedInt64, 8, 2)
            self.assert_data(data2.GetUnsignedInt64, 16, 3)
            self.assert_data(data2.GetUnsignedInt64, 24, 4)
            self.assert_data(data2.GetUnsignedInt64, 32, 5)

            self.assertTrue(
                data2.uint64s == [
                    1,
                    2,
                    3,
                    4,
                    5],
                'read_data_helper failure: data2 == [1,2,3,4,5]')

        for l in int_lists:
            data2 = lldb.SBData.CreateDataFromSInt32Array(
                process.GetByteOrder(), process.GetAddressByteSize(), l)
            self.assertTrue(
                data2.sint32[
                    0:2] == [
                    2, -2], 'signed32 data2 = [2,-2]')

        data2.Append(
            lldb.SBData.CreateDataFromSInt64Array(
                process.GetByteOrder(),
                process.GetAddressByteSize(),
                int_lists[0]))
        self.assert_data(data2.GetSignedInt32, 0, 2)
        self.assert_data(data2.GetSignedInt32, 4, -2)
        self.assertTrue(
            data2.sint64[
                1:3] == [
                2, -2], 'signed64 data2 = [2,-2]')

        for l in int_lists:
            data2 = lldb.SBData.CreateDataFromSInt64Array(
                process.GetByteOrder(), process.GetAddressByteSize(), l)
            self.assert_data(data2.GetSignedInt64, 0, 2)
            self.assert_data(data2.GetSignedInt64, 8, -2)
            self.assertTrue(
                data2.sint64[
                    0:2] == [
                    2, -2], 'signed64 data2 = [2,-2]')

        for l in uint_lists:
            data2 = lldb.SBData.CreateDataFromUInt32Array(
                process.GetByteOrder(), process.GetAddressByteSize(), l)
            self.assert_data(data2.GetUnsignedInt32, 0, 1)
            self.assert_data(data2.GetUnsignedInt32, 4, 2)
            self.assert_data(data2.GetUnsignedInt32, 8, 3)
            self.assert_data(data2.GetUnsignedInt32, 12, 4)
            self.assert_data(data2.GetUnsignedInt32, 16, 5)

        bool_list = [True, True, False, False, True, False]

        data2 = lldb.SBData.CreateDataFromSInt32Array(
            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
        self.assertTrue(
            data2.sint32[
                0:6] == [
                1,
                1,
                0,
                0,
                1,
                0],
            'signed32 data2 = [1, 1, 0, 0, 1, 0]')

        data2 = lldb.SBData.CreateDataFromUInt32Array(
            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
        self.assertTrue(
            data2.uint32[
                0:6] == [
                1,
                1,
                0,
                0,
                1,
                0],
            'unsigned32 data2 = [1, 1, 0, 0, 1, 0]')

        data2 = lldb.SBData.CreateDataFromSInt64Array(
            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
        self.assertTrue(
            data2.sint64[
                0:6] == [
                1,
                1,
                0,
                0,
                1,
                0],
            'signed64 data2 = [1, 1, 0, 0, 1, 0]')

        data2 = lldb.SBData.CreateDataFromUInt64Array(
            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
        self.assertTrue(
            data2.uint64[
                0:6] == [
                1,
                1,
                0,
                0,
                1,
                0],
            'signed64 data2 = [1, 1, 0, 0, 1, 0]')

        data2 = lldb.SBData.CreateDataFromDoubleArray(
            process.GetByteOrder(), process.GetAddressByteSize(), [
                3.14, 6.28, 2.71])
        self.assertTrue(
            fabs(
                data2.GetDouble(
                    error,
                    0) -
                3.14) < 0.5,
            'double data2[0] = 3.14')
        self.assertTrue(error.Success())
        self.assertTrue(
            fabs(
                data2.GetDouble(
                    error,
                    8) -
                6.28) < 0.5,
            'double data2[1] = 6.28')
        self.assertTrue(error.Success())
        self.assertTrue(
            fabs(
                data2.GetDouble(
                    error,
                    16) -
                2.71) < 0.5,
            'double data2[2] = 2.71')
        self.assertTrue(error.Success())

        data2 = lldb.SBData()

        data2.SetDataFromCString(hello_str)
        self.assertTrue(len(data2.uint8) == len(hello_str))
        self.assert_data(data2.GetUnsignedInt8, 0, 104)
        self.assert_data(data2.GetUnsignedInt8, 1, 101)
        self.assert_data(data2.GetUnsignedInt8, 2, 108)
        self.assert_data(data2.GetUnsignedInt8, 3, 108)
        self.assert_data(data2.GetUnsignedInt8, 4, 111)
        self.assert_data(data2.GetUnsignedInt8, 5, 33)

        data2.SetDataFromUInt64Array([1, 2, 3, 4, 5])
        self.assert_data(data2.GetUnsignedInt64, 0, 1)
        self.assert_data(data2.GetUnsignedInt64, 8, 2)
        self.assert_data(data2.GetUnsignedInt64, 16, 3)
        self.assert_data(data2.GetUnsignedInt64, 24, 4)
        self.assert_data(data2.GetUnsignedInt64, 32, 5)

        self.assertTrue(
            data2.uint64[0] == 1,
            'read_data_helper failure: set data2[0] = 1')
        self.assertTrue(
            data2.uint64[1] == 2,
            'read_data_helper failure: set data2[1] = 2')
        self.assertTrue(
            data2.uint64[2] == 3,
            'read_data_helper failure: set data2[2] = 3')
        self.assertTrue(
            data2.uint64[3] == 4,
            'read_data_helper failure: set data2[3] = 4')
        self.assertTrue(
            data2.uint64[4] == 5,
            'read_data_helper failure: set data2[4] = 5')

        self.assertTrue(
            data2.uint64[
                0:2] == [
                1,
                2],
            'read_data_helper failure: set data2[0:2] = [1,2]')

        data2.SetDataFromSInt32Array([2, -2])
        self.assert_data(data2.GetSignedInt32, 0, 2)
        self.assert_data(data2.GetSignedInt32, 4, -2)

        data2.SetDataFromSInt64Array([2, -2])
        self.assert_data(data2.GetSignedInt64, 0, 2)
        self.assert_data(data2.GetSignedInt64, 8, -2)

        data2.SetDataFromUInt32Array([1, 2, 3, 4, 5])
        self.assert_data(data2.GetUnsignedInt32, 0, 1)
        self.assert_data(data2.GetUnsignedInt32, 4, 2)
        self.assert_data(data2.GetUnsignedInt32, 8, 3)
        self.assert_data(data2.GetUnsignedInt32, 12, 4)
        self.assert_data(data2.GetUnsignedInt32, 16, 5)

        self.assertTrue(
            data2.uint32[0] == 1,
            'read_data_helper failure: set 32-bit data2[0] = 1')
        self.assertTrue(
            data2.uint32[1] == 2,
            'read_data_helper failure: set 32-bit data2[1] = 2')
        self.assertTrue(
            data2.uint32[2] == 3,
            'read_data_helper failure: set 32-bit data2[2] = 3')
        self.assertTrue(
            data2.uint32[3] == 4,
            'read_data_helper failure: set 32-bit data2[3] = 4')
        self.assertTrue(
            data2.uint32[4] == 5,
            'read_data_helper failure: set 32-bit data2[4] = 5')

        data2.SetDataFromDoubleArray([3.14, 6.28, 2.71])
        self.assertTrue(fabs(data2.GetDouble(error, 0) - 3.14)
                        < 0.5, 'set double data2[0] = 3.14')
        self.assertTrue(fabs(data2.GetDouble(error, 8) - 6.28)
                        < 0.5, 'set double data2[1] = 6.28')
        self.assertTrue(fabs(data2.GetDouble(error, 16) - 2.71)
                        < 0.5, 'set double data2[2] = 2.71')

        self.assertTrue(
            fabs(
                data2.double[0] -
                3.14) < 0.5,
            'read_data_helper failure: set double data2[0] = 3.14')
        self.assertTrue(
            fabs(
                data2.double[1] -
                6.28) < 0.5,
            'read_data_helper failure: set double data2[1] = 6.28')
        self.assertTrue(
            fabs(
                data2.double[2] -
                2.71) < 0.5,
            'read_data_helper failure: set double data2[2] = 2.71')
Beispiel #5
0
 def timeValueAsDouble(self):
     error = lldb.SBError()
     return self.valobj.GetChildMemberWithName(
         'm_timeValueAsDouble').GetData().GetDouble(error, 0)
def main(argv):
    description = '''Debugs a program using the LLDB python API and uses asynchronous broadcast events to watch for process state changes.'''
    epilog = '''Examples:

#----------------------------------------------------------------------
# Run "/bin/ls" with the arguments "-lAF /tmp/", and set a breakpoint 
# at "malloc" and backtrace and read all registers each time we stop
#----------------------------------------------------------------------
% ./process_events.py --breakpoint malloc --stop-command bt --stop-command 'register read' -- /bin/ls -lAF /tmp/

'''
    optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog
    parser = optparse.OptionParser(
        description=description,
        prog='process_events',
        usage='usage: process_events [options] program [arg1 arg2]',
        epilog=epilog)
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      help="Enable verbose logging.",
                      default=False)
    parser.add_option(
        '-b',
        '--breakpoint',
        action='append',
        type='string',
        metavar='BPEXPR',
        dest='breakpoints',
        help=
        'Breakpoint commands to create after the target has been created, the values will be sent to the "_regexp-break" command which supports breakpoints by name, file:line, and address.'
    )
    parser.add_option(
        '-a',
        '--arch',
        type='string',
        dest='arch',
        help='The architecture to use when creating the debug target.',
        default=None)
    parser.add_option(
        '--platform',
        type='string',
        metavar='platform',
        dest='platform',
        help=
        'Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".',
        default=None)
    parser.add_option(
        '-l',
        '--launch-command',
        action='append',
        type='string',
        metavar='CMD',
        dest='launch_commands',
        help=
        'LLDB command interpreter commands to run once after the process has launched. This option can be specified more than once.',
        default=[])
    parser.add_option(
        '-s',
        '--stop-command',
        action='append',
        type='string',
        metavar='CMD',
        dest='stop_commands',
        help=
        'LLDB command interpreter commands to run each time the process stops. This option can be specified more than once.',
        default=[])
    parser.add_option(
        '-c',
        '--crash-command',
        action='append',
        type='string',
        metavar='CMD',
        dest='crash_commands',
        help=
        'LLDB command interpreter commands to run in case the process crashes. This option can be specified more than once.',
        default=[])
    parser.add_option(
        '-x',
        '--exit-command',
        action='append',
        type='string',
        metavar='CMD',
        dest='exit_commands',
        help=
        'LLDB command interpreter commands to run once after the process has exited. This option can be specified more than once.',
        default=[])
    parser.add_option('-T',
                      '--no-threads',
                      action='store_false',
                      dest='show_threads',
                      help="Don't show threads when process stops.",
                      default=True)
    parser.add_option(
        '--ignore-errors',
        action='store_false',
        dest='stop_on_error',
        help=
        "Don't stop executing LLDB commands if the command returns an error. This applies to all of the LLDB command interpreter commands that get run for launch, stop, crash and exit.",
        default=True)
    parser.add_option(
        '-n',
        '--run-count',
        type='int',
        dest='run_count',
        metavar='N',
        help='How many times to run the process in case the process exits.',
        default=1)
    parser.add_option(
        '-t',
        '--event-timeout',
        type='int',
        dest='event_timeout',
        metavar='SEC',
        help=
        'Specify the timeout in seconds to wait for process state change events.',
        default=lldb.UINT32_MAX)
    parser.add_option(
        '-e',
        '--environment',
        action='append',
        type='string',
        metavar='ENV',
        dest='env_vars',
        help=
        'Environment variables to set in the inferior process when launching a process.'
    )
    parser.add_option(
        '-d',
        '--working-dir',
        type='string',
        metavar='DIR',
        dest='working_dir',
        help='The the current working directory when launching a process.',
        default=None)
    parser.add_option('-p',
                      '--attach-pid',
                      type='int',
                      dest='attach_pid',
                      metavar='PID',
                      help='Specify a process to attach to by process ID.',
                      default=-1)
    parser.add_option('-P',
                      '--attach-name',
                      type='string',
                      dest='attach_name',
                      metavar='PROCESSNAME',
                      help='Specify a process to attach to by name.',
                      default=None)
    parser.add_option(
        '-w',
        '--attach-wait',
        action='store_true',
        dest='attach_wait',
        help=
        'Wait for the next process to launch when attaching to a process by name.',
        default=False)
    try:
        (options, args) = parser.parse_args(argv)
    except:
        return

    attach_info = None
    launch_info = None
    exe = None
    if args:
        exe = args.pop(0)
        launch_info = lldb.SBLaunchInfo(args)
        if options.env_vars:
            launch_info.SetEnvironmentEntries(options.env_vars, True)
        if options.working_dir:
            launch_info.SetWorkingDirectory(options.working_dir)
    elif options.attach_pid != -1:
        if options.run_count == 1:
            attach_info = lldb.SBAttachInfo(options.attach_pid)
        else:
            print "error: --run-count can't be used with the --attach-pid option"
            sys.exit(1)
    elif not options.attach_name is None:
        if options.run_count == 1:
            attach_info = lldb.SBAttachInfo(options.attach_name,
                                            options.attach_wait)
        else:
            print "error: --run-count can't be used with the --attach-name option"
            sys.exit(1)
    else:
        print 'error: a program path for a program to debug and its arguments are required'
        sys.exit(1)

    # Create a new debugger instance
    debugger = lldb.SBDebugger.Create()
    debugger.SetAsync(True)
    command_interpreter = debugger.GetCommandInterpreter()
    # Create a target from a file and arch

    if exe:
        print "Creating a target for '%s'" % exe
    error = lldb.SBError()
    target = debugger.CreateTarget(exe, options.arch, options.platform, True,
                                   error)

    if target:

        # Set any breakpoints that were specified in the args if we are launching. We use the
        # command line command to take advantage of the shorthand breakpoint creation
        if launch_info and options.breakpoints:
            for bp in options.breakpoints:
                debugger.HandleCommand("_regexp-break %s" % (bp))
            run_commands(command_interpreter, ['breakpoint list'])

        for run_idx in range(options.run_count):
            # Launch the process. Since we specified synchronous mode, we won't return
            # from this function until we hit the breakpoint at main
            error = lldb.SBError()

            if launch_info:
                if options.run_count == 1:
                    print 'Launching "%s"...' % (exe)
                else:
                    print 'Launching "%s"... (launch %u of %u)' % (
                        exe, run_idx + 1, options.run_count)

                process = target.Launch(launch_info, error)
            else:
                if options.attach_pid != -1:
                    print 'Attaching to process %i...' % (options.attach_pid)
                else:
                    if options.attach_wait:
                        print 'Waiting for next to process named "%s" to launch...' % (
                            options.attach_name)
                    else:
                        print 'Attaching to existing process named "%s"...' % (
                            options.attach_name)
                process = target.Attach(attach_info, error)

            # Make sure the launch went ok
            if process and process.GetProcessID(
            ) != lldb.LLDB_INVALID_PROCESS_ID:

                pid = process.GetProcessID()
                print 'Process is %i' % (pid)
                if attach_info:
                    # continue process if we attached as we won't get an initial event
                    process.Continue()

                listener = debugger.GetListener()
                # sign up for process state change events
                stop_idx = 0
                done = False
                while not done:
                    event = lldb.SBEvent()
                    if listener.WaitForEvent(options.event_timeout, event):
                        if lldb.SBProcess.EventIsProcessEvent(event):
                            state = lldb.SBProcess.GetStateFromEvent(event)
                            if state == lldb.eStateInvalid:
                                # Not a state event
                                print 'process event = %s' % (event)
                            else:
                                print "process state changed event: %s" % (
                                    lldb.SBDebugger.StateAsCString(state))
                                if state == lldb.eStateStopped:
                                    if stop_idx == 0:
                                        if launch_info:
                                            print "process %u launched" % (pid)
                                            run_commands(
                                                command_interpreter,
                                                ['breakpoint list'])
                                        else:
                                            print "attached to process %u" % (
                                                pid)
                                            for m in target.modules:
                                                print m
                                            if options.breakpoints:
                                                for bp in options.breakpoints:
                                                    debugger.HandleCommand(
                                                        "_regexp-break %s" %
                                                        (bp))
                                                run_commands(
                                                    command_interpreter,
                                                    ['breakpoint list'])
                                        run_commands(command_interpreter,
                                                     options.launch_commands)
                                    else:
                                        if options.verbose:
                                            print "process %u stopped" % (pid)
                                        run_commands(command_interpreter,
                                                     options.stop_commands)
                                    stop_idx += 1
                                    print_threads(process, options)
                                    print "continuing process %u" % (pid)
                                    process.Continue()
                                elif state == lldb.eStateExited:
                                    exit_desc = process.GetExitDescription()
                                    if exit_desc:
                                        print "process %u exited with status %u: %s" % (
                                            pid, process.GetExitStatus(),
                                            exit_desc)
                                    else:
                                        print "process %u exited with status %u" % (
                                            pid, process.GetExitStatus())
                                    run_commands(command_interpreter,
                                                 options.exit_commands)
                                    done = True
                                elif state == lldb.eStateCrashed:
                                    print "process %u crashed" % (pid)
                                    print_threads(process, options)
                                    run_commands(command_interpreter,
                                                 options.crash_commands)
                                    done = True
                                elif state == lldb.eStateDetached:
                                    print "process %u detached" % (pid)
                                    done = True
                                elif state == lldb.eStateRunning:
                                    # process is running, don't say anything, we will always get one of these after resuming
                                    if options.verbose:
                                        print "process %u resumed" % (pid)
                                elif state == lldb.eStateUnloaded:
                                    print "process %u unloaded, this shouldn't happen" % (
                                        pid)
                                    done = True
                                elif state == lldb.eStateConnected:
                                    print "process connected"
                                elif state == lldb.eStateAttaching:
                                    print "process attaching"
                                elif state == lldb.eStateLaunching:
                                    print "process launching"
                        else:
                            print 'event = %s' % (event)
                    else:
                        # timeout waiting for an event
                        print "no process event for %u seconds, killing the process..." % (
                            options.event_timeout)
                        done = True
                # Now that we are done dump the stdout and stderr
                process_stdout = process.GetSTDOUT(1024)
                if process_stdout:
                    print "Process STDOUT:\n%s" % (process_stdout)
                    while process_stdout:
                        process_stdout = process.GetSTDOUT(1024)
                        print process_stdout
                process_stderr = process.GetSTDERR(1024)
                if process_stderr:
                    print "Process STDERR:\n%s" % (process_stderr)
                    while process_stderr:
                        process_stderr = process.GetSTDERR(1024)
                        print process_stderr
                process.Kill()  # kill the process
            else:
                if error:
                    print error
                else:
                    if launch_info:
                        print 'error: launch failed'
                    else:
                        print 'error: attach failed'

    lldb.SBDebugger.Terminate()
Beispiel #7
0
    def change_value_api(self, exe_name):
        """Exercise some SBValue APIs."""
        exe = os.path.join(os.getcwd(), exe_name)

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Create the breakpoint inside function 'main'.
        breakpoint = target.BreakpointCreateByLocation('main.c', self.line)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Create the breakpoint inside the function 'main'
        check_breakpoint = target.BreakpointCreateByLocation(
            'main.c', self.check_line)
        self.assertTrue(check_breakpoint, VALID_BREAKPOINT)

        # Create the breakpoint inside function 'main'.
        end_breakpoint = target.BreakpointCreateByLocation(
            'main.c', self.end_line)
        self.assertTrue(end_breakpoint, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(None, None, os.getcwd())
        self.assertTrue(process, PROCESS_IS_VALID)

        # Get Frame #0.
        self.assertTrue(process.GetState() == lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        self.assertTrue(
            thread.IsValid(),
            "There should be a thread stopped due to breakpoint condition")
        frame0 = thread.GetFrameAtIndex(0)
        self.assertTrue(frame0.IsValid(), "Got a valid frame.")

        # Get the val variable and change it:
        error = lldb.SBError()

        val_value = frame0.FindVariable("val")
        self.assertTrue(val_value.IsValid(), "Got the SBValue for val")
        actual_value = val_value.GetValueAsSigned(error, 0)
        self.assertTrue(error.Success(), "Got a value from val")
        self.assertTrue(actual_value == 100, "Got the right value from val")

        result = val_value.SetValueFromCString("12345")
        self.assertTrue(result, "Setting val returned True.")
        actual_value = val_value.GetValueAsSigned(error, 0)
        self.assertTrue(error.Success(), "Got a changed value from val")
        self.assertTrue(actual_value == 12345,
                        "Got the right changed value from val")

        # Now check that we can set a structure element:

        mine_value = frame0.FindVariable("mine")
        self.assertTrue(mine_value.IsValid(), "Got the SBValue for mine")

        mine_second_value = mine_value.GetChildMemberWithName("second_val")
        self.assertTrue(mine_second_value.IsValid(),
                        "Got second_val from mine")
        actual_value = mine_second_value.GetValueAsUnsigned(error, 0)
        self.assertTrue(error.Success(),
                        "Got an unsigned value for second_val")
        self.assertTrue(actual_value == 5555)

        result = mine_second_value.SetValueFromCString("98765")
        self.assertTrue(result, "Success setting mine.second_value.")
        actual_value = mine_second_value.GetValueAsSigned(error, 0)
        self.assertTrue(error.Success(),
                        "Got a changed value from mine.second_val")
        self.assertTrue(actual_value == 98765,
                        "Got the right changed value from mine.second_val")

        # Next do the same thing with the pointer version.
        ptr_value = frame0.FindVariable("ptr")
        self.assertTrue(ptr_value.IsValid(), "Got the SBValue for ptr")

        ptr_second_value = ptr_value.GetChildMemberWithName("second_val")
        self.assertTrue(ptr_second_value.IsValid(), "Got second_val from ptr")
        actual_value = ptr_second_value.GetValueAsUnsigned(error, 0)
        self.assertTrue(error.Success(),
                        "Got an unsigned value for ptr->second_val")
        self.assertTrue(actual_value == 6666)

        result = ptr_second_value.SetValueFromCString("98765")
        self.assertTrue(result, "Success setting ptr->second_value.")
        actual_value = ptr_second_value.GetValueAsSigned(error, 0)
        self.assertTrue(error.Success(),
                        "Got a changed value from ptr->second_val")
        self.assertTrue(actual_value == 98765,
                        "Got the right changed value from ptr->second_val")

        # gcc may set multiple locations for breakpoint
        breakpoint.SetEnabled(False)

        # Now continue, grab the stdout and make sure we changed the real values as well...
        process.Continue()

        self.assertTrue(process.GetState() == lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        self.assertTrue(
            thread.IsValid(),
            "There should be a thread stopped due to breakpoint condition")

        expected_value = "Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666"
        stdout = process.GetSTDOUT(1000)
        self.assertTrue(expected_value in stdout,
                        "STDOUT showed changed values.")

        # Finally, change the stack pointer to 0, and we should not make it to our end breakpoint.
        frame0 = thread.GetFrameAtIndex(0)
        self.assertTrue(frame0.IsValid(), "Second time: got a valid frame.")
        sp_value = frame0.FindValue("sp", lldb.eValueTypeRegister)
        self.assertTrue(sp_value.IsValid(), "Got a stack pointer value")
        result = sp_value.SetValueFromCString("1")
        self.assertTrue(result, "Setting sp returned true.")
        actual_value = sp_value.GetValueAsUnsigned(error, 0)
        self.assertTrue(error.Success(), "Got a changed value for sp")
        self.assertTrue(actual_value == 1,
                        "Got the right changed value for sp.")

        # Boundary condition test the SBValue.CreateValueFromExpression() API.
        # LLDB should not crash!
        nosuchval = mine_value.CreateValueFromExpression(None, None)

        process.Continue()

        self.assertTrue(process.GetState() == lldb.eStateStopped)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        self.assertTrue(
            thread == None,
            "We should not have managed to hit our second breakpoint with sp == 1"
        )

        process.Kill()
    def ivars_in_blocks(self):
        """Test printing the ivars of the self when captured in blocks"""
        exe = os.path.join(os.getcwd(), "a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        breakpoint = target.BreakpointCreateBySourceRegex(
            '// Break here inside the block.', self.class_source_file_spec)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        breakpoint_two = target.BreakpointCreateBySourceRegex(
            '// Break here inside the class method block.',
            self.class_source_file_spec)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        process = target.LaunchSimple(None, None, os.getcwd())
        self.assertTrue(process, "Created a process.")
        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        "Stopped it too.")

        thread_list = lldbutil.get_threads_stopped_at_breakpoint(
            process, breakpoint)
        self.assertTrue(len(thread_list) == 1)
        thread = thread_list[0]

        frame = thread.GetFrameAtIndex(0)
        self.assertTrue(frame, "frame 0 is valid")

        # First use the FindVariable API to see if we can find the ivar by undecorated name:
        direct_blocky = frame.GetValueForVariablePath("blocky_ivar")
        self.assertTrue(direct_blocky, "Found direct access to blocky_ivar.")

        # Now get it as a member of "self" and make sure the two values are equal:
        self_var = frame.GetValueForVariablePath("self")
        self.assertTrue(self_var, "Found self in block.")
        indirect_blocky = self_var.GetChildMemberWithName("blocky_ivar")
        self.assertTrue(indirect_blocky, "Found blocky_ivar through self")

        error = lldb.SBError()
        direct_value = direct_blocky.GetValueAsSigned(error)
        self.assertTrue(error.Success(), "Got direct value for blocky_ivar")

        indirect_value = indirect_blocky.GetValueAsSigned(error)
        self.assertTrue(error.Success(), "Got indirect value for blocky_ivar")

        self.assertTrue(direct_value == indirect_value,
                        "Direct and indirect values are equal.")

        # Now make sure that we can get at the captured ivar through the expression parser.
        # Doing a little trivial math will force this into the real expression parser:
        direct_expr = frame.EvaluateExpression("blocky_ivar + 10")
        self.assertTrue(direct_expr,
                        "Got blocky_ivar through the expression parser")

        # Again, get the value through self directly and make sure they are the same:
        indirect_expr = frame.EvaluateExpression("self->blocky_ivar + 10")
        self.assertTrue(
            indirect_expr,
            "Got blocky ivar through expression parser using self.")

        direct_value = direct_expr.GetValueAsSigned(error)
        self.assertTrue(error.Success(),
                        "Got value from direct use of expression parser")

        indirect_value = indirect_expr.GetValueAsSigned(error)
        self.assertTrue(
            error.Success(),
            "Got value from indirect access using the expression parser")

        self.assertTrue(
            direct_value == indirect_value,
            "Direct ivar access and indirect through expression parser produce same value."
        )

        process.Continue()
        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        "Stopped at the second breakpoint.")

        thread_list = lldbutil.get_threads_stopped_at_breakpoint(
            process, breakpoint_two)
        self.assertTrue(len(thread_list) == 1)
        thread = thread_list[0]

        frame = thread.GetFrameAtIndex(0)
        self.assertTrue(frame, "frame 0 is valid")

        expr = frame.EvaluateExpression("(ret)")
        self.assertTrue(
            expr,
            "Successfully got a local variable in a block in a class method.")

        ret_value_signed = expr.GetValueAsSigned(error)
        print 'ret_value_signed = %i' % (ret_value_signed)
        self.assertTrue(
            ret_value_signed == 5,
            "The local variable in the block was what we expected.")
Beispiel #9
0
    def do_test(self, use_target_create):
        self.absent_file = '/nosuch_dir/nosuch_subdir/nosuch_executable'
        self.a_packet_file = None
        class MyResponder(MockGDBServerResponder):
            def __init__(self, testcase):
                MockGDBServerResponder.__init__(self)
                self.after_launch = False
                self.testcase = testcase
                self.current_thread = 0
                
            def A(self, packet):
                # This is the main test, we want to see that lldb DID send the
                # A packet to get debugserver to load the file.
                # Skip the length and second length:
                print("Got A packet: {0}".format(packet))
                a_arr = packet.split(",")
                self.testcase.a_packet_file = bytearray.fromhex(a_arr[2]).decode()
                return "OK"

            def qXferRead(self, obj, annex, offset, length):
                if annex == "target.xml":
                    return """<?xml version="1.0"?>
                        <target version="1.0">
                          <architecture>i386:x86-64</architecture>
                          <feature name="org.gnu.gdb.i386.core">
                            <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
                          </feature>
                        </target>""", False
                else:
                    return None, False

            def qC(self):
                if not self.after_launch:
                    return "QC0"
                return "0"

            def qfThreadInfo(self):
                if not self.after_launch:
                    return "OK"
                return "m0"

            def qsThreadInfo(self):
                if not self.after_launch:
                    return "OK"
                return "l"

            def qLaunchSuccess(self):
                return "OK"

            def qProcessInfo(self):
                return "$pid:10b70;parent-pid:10b20;real-uid:1f6;real-gid:14;effective-uid:1f6;effective-gid:14;cputype:1000007;cpusubtype:8;ptrsize:8;ostype:macosx;vendor:apple;endian:little;"

            
        error = lldb.SBError()
        self.server.responder = MyResponder(self)
        target = lldb.SBTarget()
        if (use_target_create):
            create_cmd = "target create --arch x86_64-apple-macosx --platform remote-macosx --remote-file {0}".format(self.absent_file)
            self.runCmd(create_cmd)
            target = self.dbg.GetSelectedTarget()
            self.assertTrue(target.IsValid(), "Made a valid target")
        else:
            target = self.dbg.CreateTarget(None, "x86_64-apple-macosx", "remote-macosx", False, error)
            self.assertSuccess(error, "Made a valid target")

        launch_info = target.GetLaunchInfo()
        if (not use_target_create):
            launch_info.SetExecutableFile(lldb.SBFileSpec(self.absent_file), True)
        flags = launch_info.GetLaunchFlags()
        flags |= lldb.eLaunchFlagStopAtEntry
        launch_info.SetLaunchFlags(flags)

        process = self.connect(target)
        self.assertTrue(process.IsValid(), "Process is valid")

        # We need to fetch the connected event:
        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected])

        self.server.responder.after_launch = True

        process = target.Launch(launch_info, error)

        self.assertSuccess(error, "Successfully launched.")
        self.assertEqual(process.GetState(), lldb.eStateStopped, "Should be stopped at entry")
        self.assertIsNotNone(self.a_packet_file, "A packet was sent")
        self.assertEqual(self.absent_file, self.a_packet_file, "The A packet file was correct")
Beispiel #10
0
    def do_test(self):
        """Check that we can examine module globals in the expression parser"""
        exe_name = "a.out"
        exe = self.getBuildArtifact(exe_name)

        # Create the target
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Target variables. This is not actually expected to work, but
        # also shouldn't crash.
        g_counter = target.EvaluateExpression("g_counter")
        self.assertTrue(
            g_counter.IsValid(),
            "g_counter returned a valid value object.")

        # Set the breakpoints
        outer_bkpt = target.BreakpointCreateBySourceRegex(
            'Set top_level breakpoint here', self.main_source_spec)
        self.assertTrue(outer_bkpt.GetNumLocations() > 0, VALID_BREAKPOINT)

        function_bkpt = target.BreakpointCreateBySourceRegex(
            'Set function breakpoint here', self.main_source_spec)
        self.assertTrue(function_bkpt.GetNumLocations() > 0, VALID_BREAKPOINT)

        # Launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None, os.getcwd())

        self.assertTrue(process, PROCESS_IS_VALID)

        # Frame #0 should be at our breakpoint.
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, outer_bkpt)

        self.assertTrue(len(threads) == 1)
        self.thread = threads[0]

        # All the variables should be uninitialized at this point.  Maybe sure
        # they look that way:
        frame = self.thread.frames[0]
        options = lldb.SBExpressionOptions()
        options.SetFetchDynamicValue(lldb.eDynamicCanRunTarget)

        error = lldb.SBError()

        # Examine the variables before initialization:

        g_counter = frame.EvaluateExpression("g_counter", options)
        self.assertTrue(
            g_counter.IsValid(),
            "g_counter returned a valid value object.")
        value = g_counter.GetValueAsSigned(error)
        self.assertSuccess(error, "Got a value for g_counter")
        self.assertTrue(
            value == 0,
            "g_counter value is the uninitialized one.")

        foo_var = frame.EvaluateExpression("my_foo", options)
        self.assertTrue(
            foo_var.IsValid(),
            "foo_var returned a valid value object.")
        value = foo_var.GetValueAsUnsigned(error)
        self.assertSuccess(error, "foo_var has a value.")
        self.assertTrue(value == 0, "foo_var is null before initialization.")

        my_large_dude = frame.EvaluateExpression("my_large_dude", options)
        self.assertTrue(my_large_dude.IsValid(),
                        "my_large_dude returned a valid value object.")
        value = my_large_dude.GetValue()
        self.assertSuccess(error, "Got a value for my_large_dude")
        self.assertTrue(
            value is None,
            "my_large_dude value is the uninitialized one.")

        # Now proceed to the breakpoint in our main function, make sure we can
        # still read these variables and they now have the right values.
        threads = lldbutil.continue_to_breakpoint(process, function_bkpt)
        self.assertTrue(len(threads) == 1)

        self.thread = threads[0]

        # Examine the variables before initialization:

        g_counter = frame.EvaluateExpression("g_counter", options)
        self.assertTrue(
            g_counter.IsValid(),
            "g_counter returned a valid value object.")
        value = g_counter.GetValueAsSigned(error)
        self.assertSuccess(error, "Got a value for g_counter")
        self.assertTrue(value == 2, "g_counter value should be 2.")

        foo_var = frame.EvaluateExpression("my_foo", options)
        self.assertTrue(
            foo_var.IsValid(),
            "foo_var returned a valid value object.")
        foo_var_x = foo_var.GetChildMemberWithName("x")
        self.assertTrue(foo_var_x.IsValid(), "Got value object for foo_var.x")
        value = foo_var_x.GetValueAsUnsigned(error)
        self.assertSuccess(error, "foo_var.x has a value.")
        self.assertTrue(value == 1, "foo_var is null before initialization.")

        my_large_dude = frame.EvaluateExpression("my_large_dude", options)
        self.assertTrue(my_large_dude.IsValid(),
                        "my_large_dude returned a valid value object.")
        my_large_dude_y = my_large_dude.GetChildMemberWithName("y")
        self.assertTrue(
            my_large_dude_y.IsValid(),
            "Got value object for my_large_dude.y")
        value = my_large_dude_y.GetValueAsUnsigned(error)
        self.assertSuccess(error, "Got a value for my_large_dude.y")
        self.assertTrue(
            value == 20,
            "my_large_dude value is the uninitialized one.")
Beispiel #11
0
    def test_watch_iter(self):
        """Exercise SBTarget.watchpoint_iter() API to iterate on the available watchpoints."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Create a breakpoint on main.c in order to set our watchpoint later.
        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
        self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1,
                        VALID_BREAKPOINT)

        # Now launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None,
                                      self.get_process_working_directory())

        # We should be stopped due to the breakpoint.  Get frame #0.
        process = target.GetProcess()
        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        PROCESS_STOPPED)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        frame0 = thread.GetFrameAtIndex(0)

        # Watch 'global' for read and write.
        value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
        error = lldb.SBError()
        watchpoint = value.Watch(True, False, True, error)
        self.assertTrue(
            value and watchpoint,
            "Successfully found the variable and set a watchpoint")
        self.DebugSBValue(value)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        # There should be only 1 watchpoint location under the target.
        self.assertTrue(target.GetNumWatchpoints() == 1)
        self.assertTrue(watchpoint.IsEnabled())
        watch_id = watchpoint.GetID()
        self.assertTrue(watch_id != 0)

        # Continue.  Expect the program to stop due to the variable being
        # written to.
        process.Continue()

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        # Print the stack traces.
        lldbutil.print_stacktraces(process)

        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonWatchpoint)
        self.assertTrue(thread, "The thread stopped due to watchpoint")
        self.DebugSBValue(value)

        # We currently only support hardware watchpoint.  Verify that we have a
        # meaningful hardware index at this point.  Exercise the printed repr of
        # SBWatchpointLocation.
        print(watchpoint)
        if not self.affected_by_radar_34564183():
            self.assertTrue(watchpoint.GetHardwareIndex() != -1)

        # SBWatchpoint.GetDescription() takes a description level arg.
        print(lldbutil.get_description(watchpoint, lldb.eDescriptionLevelFull))

        # Now disable the 'rw' watchpoint.  The program won't stop when it reads
        # 'global' next.
        watchpoint.SetEnabled(False)
        self.assertTrue(watchpoint.GetHardwareIndex() == -1)
        self.assertFalse(watchpoint.IsEnabled())

        # Continue.  The program does not stop again when the variable is being
        # read from because the watchpoint location has been disabled.
        process.Continue()

        # At this point, the inferior process should have exited.
        self.assertTrue(process.GetState() == lldb.eStateExited,
                        PROCESS_EXITED)

        # Verify some vital statistics and exercise the iterator API.
        for watchpoint in target.watchpoint_iter():
            self.assertTrue(watchpoint)
            self.assertTrue(watchpoint.GetWatchSize() == 4)
            self.assertTrue(watchpoint.GetHitCount() == 1)
            print(watchpoint)
    def expr_syscall(self):
        exe = self.getBuildArtifact("a.out")

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        listener = lldb.SBListener("my listener")

        # launch the inferior and don't wait for it to stop
        self.dbg.SetAsync(True)
        error = lldb.SBError()
        flags = target.GetLaunchInfo().GetLaunchFlags()
        process = target.Launch(
            listener,
            None,  # argv
            None,  # envp
            None,  # stdin_path
            None,  # stdout_path
            None,  # stderr_path
            None,  # working directory
            flags,  # launch flags
            False,  # Stop at entry
            error)  # error

        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)

        event = lldb.SBEvent()

        # Give the child enough time to reach the syscall,
        # while clearing out all the pending events.
        # The last WaitForEvent call will time out after 2 seconds.
        while listener.WaitForEvent(2, event):
            pass

        # now the process should be running (blocked in the syscall)
        self.assertEqual(process.GetState(), lldb.eStateRunning,
                         "Process is running")

        # send the process a signal
        process.SendAsyncInterrupt()
        while listener.WaitForEvent(2, event):
            pass

        # as a result the process should stop
        # in all likelihood we have stopped in the middle of the sleep()
        # syscall
        self.assertEqual(process.GetState(), lldb.eStateStopped,
                         PROCESS_STOPPED)
        thread = process.GetSelectedThread()

        # try evaluating a couple of expressions in this state
        self.expect_expr("release_flag = 1", result_value="1")
        self.expect_expr("(int)getpid()",
                         result_value=str(process.GetProcessID()))

        # and run the process to completion
        process.Continue()

        # process all events
        while listener.WaitForEvent(10, event):
            new_state = lldb.SBProcess.GetStateFromEvent(event)
            if new_state == lldb.eStateExited:
                break

        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), 0)
Beispiel #13
0
 def _GetValueAsUnsigned(self):
     serr = lldb.SBError()
     retval = self._sbval19k84obscure747.GetValueAsUnsigned(serr)
     if serr.success:
         return retval
     raise ValueError("Failed to read unsigned data. "+ str(self._sbval19k84obscure747) +"(type =" + str(self._sbval19k84obscure747_type) + ") Error description: " + serr.GetCString())
Beispiel #14
0
print("Target executable is '%s'." % target_path)
print("Current working directory is '%s'" % os.getcwd())

# Start the timeout watchdog
start_watchdog()

# Create a new debugger instance
debugger = lldb.SBDebugger.Create()

# When we step or continue, don't return from the function until the process
# stops. We do this by setting the async mode to false.
debugger.SetAsync(False)

# Create a target from a file and arch
print("Creating a target for '%s'" % target_path)
target_error = lldb.SBError()
target = debugger.CreateTarget(target_path, None, None, True, target_error)

if not target:
    print("Could not create debugging target '" + target_path + "': " +
          str(target_error) + ". Aborting.",
          file=sys.stderr)
    sys.exit(1)

# Register the breakpoint callback for every breakpoint
start_breakpoint_listener(target)

command_interpreter = debugger.GetCommandInterpreter()

try:
    script_file = open(script_path, 'r')
Beispiel #15
0
    def test_get_process_info(self):
        """Test SBProcess::GetProcessInfo() API with a locally launched process."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Launch the process and stop at the entry point.
        launch_info = lldb.SBLaunchInfo(None)
        launch_info.SetWorkingDirectory(self.get_process_working_directory())
        launch_flags = launch_info.GetLaunchFlags()
        launch_flags |= lldb.eLaunchFlagStopAtEntry
        launch_info.SetLaunchFlags(launch_flags)
        error = lldb.SBError()
        process = target.Launch(launch_info, error)

        if not error.Success():
            self.fail("Failed to launch process")

        # Verify basic process info can be retrieved successfully
        process_info = process.GetProcessInfo()
        self.assertTrue(process_info.IsValid())
        file_spec = process_info.GetExecutableFile()
        self.assertTrue(file_spec.IsValid())
        process_name = process_info.GetName()
        self.assertIsNotNone(process_name, "Process has a name")
        self.assertGreater(len(process_name), 0, "Process name isn't blank")
        self.assertEqual(file_spec.GetFilename(), "a.out")
        self.assertNotEqual(process_info.GetProcessID(),
                            lldb.LLDB_INVALID_PROCESS_ID,
                            "Process ID is valid")

        # Additional process info varies by platform, so just check that
        # whatever info was retrieved is consistent and nothing blows up.
        if process_info.UserIDIsValid():
            self.assertNotEqual(process_info.GetUserID(), lldb.UINT32_MAX,
                                "Process user ID is valid")
        else:
            self.assertEqual(process_info.GetUserID(), lldb.UINT32_MAX,
                             "Process user ID is invalid")

        if process_info.GroupIDIsValid():
            self.assertNotEqual(process_info.GetGroupID(), lldb.UINT32_MAX,
                                "Process group ID is valid")
        else:
            self.assertEqual(process_info.GetGroupID(), lldb.UINT32_MAX,
                             "Process group ID is invalid")

        if process_info.EffectiveUserIDIsValid():
            self.assertNotEqual(process_info.GetEffectiveUserID(),
                                lldb.UINT32_MAX,
                                "Process effective user ID is valid")
        else:
            self.assertEqual(process_info.GetEffectiveUserID(),
                             lldb.UINT32_MAX,
                             "Process effective user ID is invalid")

        if process_info.EffectiveGroupIDIsValid():
            self.assertNotEqual(process_info.GetEffectiveGroupID(),
                                lldb.UINT32_MAX,
                                "Process effective group ID is valid")
        else:
            self.assertEqual(process_info.GetEffectiveGroupID(),
                             lldb.UINT32_MAX,
                             "Process effective group ID is invalid")

        process_info.GetParentProcessID()
Beispiel #16
0
def memfind(target, options, args, result):
    num_args = len(args)
    start_addr = 0
    if num_args == 1:
        if options.size > 0:
            print_error(
                "error: --size must be specified if there is no ENDADDR argument",
                True, result)
            return
        start_addr = int(args[0], 0)
    elif num_args == 2:
        if options.size != 0:
            print_error(
                "error: --size can't be specified with an ENDADDR argument",
                True, result)
            return
        start_addr = int(args[0], 0)
        end_addr = int(args[1], 0)
        if start_addr >= end_addr:
            print_error(
                "error: inavlid memory range [%#x - %#x)" %
                (start_addr, end_addr), True, result)
            return
        options.size = end_addr - start_addr
    else:
        print_error("error: memfind takes 1 or 2 arguments", True, result)
        return

    if not options.data:
        print('error: no data specified to search for', file=result)
        return

    if not target:
        print('error: invalid target', file=result)
        return
    process = target.process
    if not process:
        print('error: invalid process', file=result)
        return

    error = lldb.SBError()
    bytes = process.ReadMemory(start_addr, options.size, error)
    if error.Success():
        num_matches = 0
        print("Searching memory range [%#x - %#x) for" %
              (start_addr, end_addr),
              end=' ',
              file=result)
        for byte in options.data:
            print('%2.2x' % ord(byte), end=' ', file=result)
        print(file=result)

        match_index = string.find(bytes, options.data)
        while match_index != -1:
            num_matches = num_matches + 1
            print('%#x: %#x + %u' %
                  (start_addr + match_index, start_addr, match_index),
                  file=result)
            match_index = string.find(bytes, options.data, match_index + 1)

        if num_matches == 0:
            print("error: no matches found", file=result)
    else:
        print('error: %s' % (error.GetCString()), file=result)
Beispiel #17
0
    def do_return_value(self):
        """Test getting return values from stepping out."""
        exe = os.path.join(os.getcwd(), "a.out")
        error = lldb.SBError()

        self.target = self.dbg.CreateTarget(exe)
        self.assertTrue(self.target, VALID_TARGET)

        inner_sint_bkpt = self.target.BreakpointCreateByName("inner_sint", exe)
        self.assertTrue(inner_sint_bkpt, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        self.process = self.target.LaunchSimple(None, None, os.getcwd())

        self.assertTrue(self.process, PROCESS_IS_VALID)

        # The stop reason of the thread should be breakpoint.
        self.assertTrue(self.process.GetState() == lldb.eStateStopped,
                        STOPPED_DUE_TO_BREAKPOINT)

        # Now finish, and make sure the return value is correct.
        thread = lldbutil.get_stopped_thread(self.process,
                                             lldb.eStopReasonBreakpoint)

        # inner_sint returns the variable value, so capture that here:
        in_int = thread.GetFrameAtIndex(0).FindVariable(
            "value").GetValueAsSigned(error)
        self.assertTrue(error.Success())

        thread.StepOut()

        self.assertTrue(self.process.GetState() == lldb.eStateStopped)
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)

        frame = thread.GetFrameAtIndex(0)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "outer_sint")

        return_value = thread.GetStopReturnValue()
        self.assertTrue(return_value.IsValid())

        ret_int = return_value.GetValueAsSigned(error)
        self.assertTrue(error.Success())
        self.assertTrue(in_int == ret_int)

        # Run again and we will stop in inner_sint the second time outer_sint is called.
        #Then test stepping out two frames at once:

        self.process.Continue()
        thread_list = lldbutil.get_threads_stopped_at_breakpoint(
            self.process, inner_sint_bkpt)
        self.assertTrue(len(thread_list) == 1)
        thread = thread_list[0]

        # We are done with the inner_sint breakpoint:
        self.target.BreakpointDelete(inner_sint_bkpt.GetID())

        frame = thread.GetFrameAtIndex(1)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "outer_sint")
        in_int = frame.FindVariable("value").GetValueAsSigned(error)
        self.assertTrue(error.Success())

        thread.StepOutOfFrame(frame)

        self.assertTrue(self.process.GetState() == lldb.eStateStopped)
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)
        frame = thread.GetFrameAtIndex(0)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "main")

        ret_value = thread.GetStopReturnValue()
        self.assertTrue(return_value.IsValid())
        ret_int = ret_value.GetValueAsSigned(error)
        self.assertTrue(error.Success())
        self.assertTrue(2 * in_int == ret_int)

        # Now try some simple returns that have different types:
        inner_float_bkpt = self.target.BreakpointCreateByName(
            "inner_float", exe)
        self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT)
        self.process.Continue()
        thread_list = lldbutil.get_threads_stopped_at_breakpoint(
            self.process, inner_float_bkpt)
        self.assertTrue(len(thread_list) == 1)
        thread = thread_list[0]

        self.target.BreakpointDelete(inner_float_bkpt.GetID())

        frame = thread.GetFrameAtIndex(0)
        in_value = frame.FindVariable("value")
        in_float = float(in_value.GetValue())
        thread.StepOut()

        self.assertTrue(self.process.GetState() == lldb.eStateStopped)
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)

        frame = thread.GetFrameAtIndex(0)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "outer_float")

        return_value = thread.GetStopReturnValue()
        self.assertTrue(return_value.IsValid())
        return_float = float(return_value.GetValue())

        self.assertTrue(in_float == return_float)

        self.return_and_test_struct_value("return_one_int")
        self.return_and_test_struct_value("return_two_int")
        self.return_and_test_struct_value("return_three_int")
        self.return_and_test_struct_value("return_four_int")
        self.return_and_test_struct_value("return_five_int")

        self.return_and_test_struct_value("return_two_double")
        self.return_and_test_struct_value("return_one_double_two_float")
        self.return_and_test_struct_value("return_one_int_one_float_one_int")

        self.return_and_test_struct_value("return_one_pointer")
        self.return_and_test_struct_value("return_two_pointer")
        self.return_and_test_struct_value("return_one_float_one_pointer")
        self.return_and_test_struct_value("return_one_int_one_pointer")
        self.return_and_test_struct_value("return_three_short_one_float")

        self.return_and_test_struct_value("return_one_int_one_double")
        self.return_and_test_struct_value("return_one_int_one_double_one_int")
        self.return_and_test_struct_value(
            "return_one_short_one_double_one_short")
        self.return_and_test_struct_value("return_one_float_one_int_one_float")
        self.return_and_test_struct_value("return_two_float")
        # I am leaving out the packed test until we have a way to tell CLANG
        # about alignment when reading DWARF for packed types.
        #self.return_and_test_struct_value ("return_one_int_one_double_packed")
        self.return_and_test_struct_value("return_one_int_one_long")
    def test_setpgid(self):
        self.build()
        exe = os.path.join(os.getcwd(), 'a.out')

        # Use a file as a synchronization point between test and inferior.
        pid_file_path = lldbutil.append_to_process_working_directory(
            "pid_file_%d" % (int(time.time())))
        self.addTearDownHook(
            lambda: self.run_platform_command("rm %s" % (pid_file_path)))

        popen = self.spawnSubprocess(exe, [pid_file_path])
        self.addTearDownHook(self.cleanupSubprocesses)

        max_attempts = 5
        for i in range(max_attempts):
            err, retcode, msg = self.run_platform_command("ls %s" %
                                                          pid_file_path)
            if err.Success() and retcode == 0:
                break
            else:
                print(msg)
            if i < max_attempts:
                # Exponential backoff!
                time.sleep(pow(2, i) * 0.30)
        else:
            self.fail("Child PID file %s not found even after %d attempts." %
                      (pid_file_path, max_attempts))

        err, retcode, pid = self.run_platform_command("cat %s" %
                                                      (pid_file_path))

        self.assertTrue(
            err.Success() and retcode == 0,
            "Failed to read file %s: %s, retcode: %d" %
            (pid_file_path, err.GetCString(), retcode))

        # make sure we cleanup the forked child also
        def cleanupChild():
            if lldb.remote_platform:
                lldb.remote_platform.Kill(int(pid))
            else:
                if os.path.exists("/proc/" + pid):
                    os.kill(int(pid), signal.SIGKILL)

        self.addTearDownHook(cleanupChild)

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        listener = lldb.SBListener("my.attach.listener")
        error = lldb.SBError()
        process = target.AttachToProcessWithID(listener, int(pid), error)
        self.assertTrue(error.Success() and process, PROCESS_IS_VALID)

        # set a breakpoint just before the setpgid() call
        lldbutil.run_break_set_by_file_and_line(self,
                                                'main.c',
                                                self.line,
                                                num_expected_locations=-1)

        thread = process.GetSelectedThread()

        # release the child from its loop
        value = thread.GetSelectedFrame().EvaluateExpression(
            "release_child_flag = 1")
        self.assertTrue(value.IsValid() and value.GetValueAsUnsigned(0) == 1)
        process.Continue()

        # make sure the child's process group id is different from its pid
        value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")
        self.assertTrue(value.IsValid())
        self.assertNotEqual(value.GetValueAsUnsigned(0), int(pid))

        # step over the setpgid() call
        thread.StepOver()
        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonPlanComplete)

        # verify that the process group has been set correctly
        # this also checks that we are still in full control of the child
        value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)")
        self.assertTrue(value.IsValid())
        self.assertEqual(value.GetValueAsUnsigned(0), int(pid))

        # run to completion
        process.Continue()
        self.assertEqual(process.GetState(), lldb.eStateExited)
def main(argv):
    description = '''Debugs a program using the LLDB python API and does crash analysis on stop events'''
    epilog = '''Examples:

% ./exploitaben.py -- /path/to/app -exampleflag -otherflag file_that_causes.crash

'''
    optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog
    parser = optparse.OptionParser(
        description=description,
        prog='process_events',
        usage='usage: process_events [options] program [arg1 arg2]',
        epilog=epilog)
    parser.add_option('-v',
                      '--verbose',
                      action='store_true',
                      dest='verbose',
                      help="Enable verbose logging.",
                      default=False)
    parser.add_option(
        '-b',
        '--breakpoint',
        action='append',
        type='string',
        metavar='BPEXPR',
        dest='breakpoints',
        help=
        'Breakpoint commands to create after the target has been created, the values will be sent to the "_regexp-break" command which supports breakpoints by name, file:line, and address.'
    )
    parser.add_option(
        '-c',
        '--crash-command',
        action='append',
        type='string',
        metavar='CMD',
        dest='crash_commands',
        help=
        'LLDB command interpreter commands to run in case the process crashes. This option can be specified more than once.',
        default=[])
    parser.add_option(
        '-x',
        '--exit-command',
        action='append',
        type='string',
        metavar='CMD',
        dest='exit_commands',
        help=
        'LLDB command interpreter commands to run once after the process has exited. This option can be specified more than once.',
        default=[])
    parser.add_option(
        '--ignore-errors',
        action='store_false',
        dest='stop_on_error',
        help=
        "Don't stop executing LLDB commands if the command returns an error. This applies to all of the LLDB command interpreter commands that get run for launch, stop, crash and exit.",
        default=True)
    parser.add_option(
        '-t',
        '--event-timeout',
        type='int',
        dest='event_timeout',
        metavar='SEC',
        help=
        'Specify the timeout in seconds to wait for process state change events.',
        default=lldb.UINT32_MAX)
    parser.add_option(
        '-e',
        '--environment',
        action='append',
        type='string',
        metavar='ENV',
        dest='env_vars',
        help=
        'Environment variables to set in the inferior process when launching a process.'
    )
    parser.add_option(
        '-d',
        '--working-dir',
        type='string',
        metavar='DIR',
        dest='working_dir',
        help='The the current working directory when launching a process.',
        default=None)
    parser.add_option('-p',
                      '--attach-pid',
                      type='int',
                      dest='attach_pid',
                      metavar='PID',
                      help='Specify a process to attach to by process ID.',
                      default=-1)
    parser.add_option('-P',
                      '--attach-name',
                      type='string',
                      dest='attach_name',
                      metavar='PROCESSNAME',
                      help='Specify a process to attach to by name.',
                      default=None)
    parser.add_option(
        '-w',
        '--attach-wait',
        action='store_true',
        dest='attach_wait',
        help=
        'Wait for the next process to launch when attaching to a process by name.',
        default=False)
    parser.add_option(
        '-O',
        '--show-output',
        action='store_true',
        dest='show_output',
        help='Print the captured stdout/stderr from the target at exit.',
        default=False)
    parser.add_option('-N',
                      '--no-color',
                      action='store_true',
                      dest='no_color',
                      help='Print the output without color encoding',
                      default=False)

    try:
        (options, args) = parser.parse_args(argv)
    except:
        return

    options.run_count = 1

    # I used a closure because we need to wait until options have been parsed
    def debug(str):
        if options.verbose:
            print str

    attach_info = None
    launch_info = None
    exe = None
    if args:
        exe = args.pop(0)
        launch_info = lldb.SBLaunchInfo(args)
        if options.env_vars:
            launch_info.SetEnvironmentEntries(options.env_vars, True)
        if options.working_dir:
            launch_info.SetWorkingDirectory(options.working_dir)
    elif options.attach_pid != -1:
        if options.run_count == 1:
            attach_info = lldb.SBAttachInfo(options.attach_pid)
        else:
            print "error: --run-count can't be used with the --attach-pid option"
            sys.exit(1)
    elif options.attach_name is not None:
        attach_info = lldb.SBAttachInfo(options.attach_name,
                                        options.attach_wait)
        if options.attach_wait:
            waiting = True
    else:
        print 'error: a program path for a program to debug and its arguments are required'
        sys.exit(1)

    # Create a new debugger instance
    debugger = lldb.SBDebugger.Create()
    debugger.SetAsync(True)
    command_interpreter = debugger.GetCommandInterpreter()
    # Create a target from a file and arch

    if exe:
        debug("Creating a target for '%s'" % exe)

    error = lldb.SBError()
    target = debugger.CreateTarget(exe, None, None, True, error)

    if target:
        # Set any breakpoints that were specified in the args if we are launching. We use the
        # command line command to take advantage of the shorthand breakpoint creation
        if launch_info and options.breakpoints:
            for bp in options.breakpoints:
                debugger.HandleCommand("_regexp-break %s" % (bp))
            run_commands(command_interpreter, ['breakpoint list'], options)

        for run_idx in range(options.run_count):
            # Launch the process. Since we specified synchronous mode, we won't return
            # from this function until we hit the breakpoint at main
            error = lldb.SBError()

            if launch_info:
                if options.run_count == 1:
                    debug('Launching "%s"...' % (exe))
                else:
                    debug('Launching "%s"... (launch %u of %u)' %
                          (exe, run_idx + 1, options.run_count))

                process = target.Launch(launch_info, error)
            else:
                if options.attach_pid != -1:
                    debug('Attaching to process %i...' % (options.attach_pid))
                else:
                    if options.attach_wait:
                        debug(
                            'Waiting for next to process named "%s" to launch...'
                            % (options.attach_name))
                    else:
                        debug('Attaching to existing process named "%s"...' %
                              (options.attach_name))
                process = target.Attach(attach_info, error)

            # Make sure the launch went ok
            if process and options.attach_wait or process.GetProcessID(
            ) != lldb.LLDB_INVALID_PROCESS_ID:
                pid = process.GetProcessID()
                listener = debugger.GetListener()
                # sign up for process state change events
                done = False
                # moved this outside the main event loop so we re-use one C++
                # object. Saves a lot of __init__ calls.
                event = lldb.SBEvent()
                while not done:
                    if listener.WaitForEvent(options.event_timeout, event):
                        if lldb.SBProcess.EventIsProcessEvent(event):
                            state = lldb.SBProcess.GetStateFromEvent(event)
                            if state == lldb.eStateInvalid:
                                # Not a state event
                                debug('process event = %s' % (event))
                            else:
                                # don't call StateAsCString in the critical path!
                                # debug("process state changed event: %s" % (lldb.SBDebugger.StateAsCString(state)))
                                if state == lldb.eStateStopped:
                                    debug("process %u stopped" % (pid))
                                    # handle initial stop event after attach ( including attach_wait )
                                    if options.attach_name:
                                        debug("Attached to {}!".format(
                                            options.attach_name))
                                        # clobber the attach_name option to save using a scratch variable ;)
                                        options.attach_name = False
                                        process.Continue()
                                        continue

                                    # OK, now it's a 'real' stop.

                                    # skip ahead to the first faulting thread. Not perfect, but better
                                    # than nothing.
                                    # TODO: Handle cases where multiple threads have a StopReason
                                    # ( need to find one first )
                                    for thread in process:
                                        if thread.GetStopReason(
                                        ) != lldb.eStopReasonNone:
                                            process.SetSelectedThread(thread)
                                            break

                                    if not process.selected_thread.GetFrameAtIndex(
                                            0).IsValid():
                                        print "[ABORT] no valid frames in faulting thread"
                                        done = True
                                        continue

                                    # Adding some parser sugar...
                                    print "Stack trace:"
                                    run_commands(command_interpreter,
                                                 ['bt 25'], options)
                                    print "Nearby code:"
                                    try:
                                        run_commands(
                                            command_interpreter,
                                            ['disass -p -c 10 -b -F intel'],
                                            options)
                                    except:
                                        print "<disassembly failed>"

                                    analyzer = lldbx86.Analyzer(
                                        target, options.no_color)

                                    # will fall back to uncolorized when termcolors is not available
                                    registers = analyzer.prettyRegisters()
                                    for reg, val in registers.iteritems():
                                        print "    %3.3s = %s" % (reg, val)

                                    print "Hash: %s" % stack_hash(
                                        process.selected_thread)
                                    print "ANALYSIS INDICATORS:"
                                    print "--------------------"
                                    print "StopDesc:           %s" % analyzer.getStopDescription(
                                    )
                                    print "AvNearNull:         %s" % analyzer.isAvNearNull(
                                    )
                                    print "AvNearSP:           %s" % analyzer.isAvNearSP(
                                    )
                                    print "BadBeef:            %s" % analyzer.isAvBadBeef(
                                    )
                                    print "Access Type:        %s" % analyzer.getAccessType(
                                        analyzer.getCurrentInstruction())
                                    regs = analyzer.getInsnRegisters(
                                        analyzer.getCurrentInstruction())
                                    print "Registers:          %s" % ' '.join(
                                        map(
                                            lambda r: "{}={}".format(
                                                r, regs[r]), regs.keys()))
                                    print "BlockMov:           %s" % analyzer.isBlockMove(
                                    )
                                    print "Weird PC:           %s" % analyzer.isPcWeird(
                                    )
                                    print "Weird SP:           %s" % analyzer.isSpWeird(
                                    )
                                    print "Suspicious Funcs:   %s" % " ".join(
                                        analyzer.getSuspiciousStackFuncs())
                                    print "Illegal Insn:       %s" % analyzer.isIllegalInstruction(
                                    )
                                    print "Huge Stack:         %s" % analyzer.isStackHuge(
                                    )
                                    done = True
                                elif state == lldb.eStateExited:
                                    exit_desc = process.GetExitDescription()
                                    if exit_desc:
                                        debug(
                                            "process %u exited with status %u: %s"
                                            % (pid, process.GetExitStatus(),
                                               exit_desc))
                                    else:
                                        debug(
                                            "process %u exited with status %u"
                                            % (pid, process.GetExitStatus()))
                                    run_commands(command_interpreter,
                                                 options.exit_commands,
                                                 options)
                                    done = True
                                elif state == lldb.eStateCrashed:
                                    # TODO no idea when this happens without first hitting a stop event
                                    debug("process %u crashed" % (pid))
                                    print_threads(process, options)
                                    run_commands(command_interpreter,
                                                 options.crash_commands,
                                                 options)
                                    done = True
                                elif state == lldb.eStateDetached:
                                    debug("process %u detached" % (pid))
                                    done = True
                                elif state == lldb.eStateRunning:
                                    debug("process %u resumed" % (pid))
                                elif state == lldb.eStateUnloaded:
                                    debug(
                                        "process %u unloaded, this shouldn't happen"
                                        % (pid))
                                    done = True
                                elif state == lldb.eStateConnected:
                                    debug("process connected")
                                elif state == lldb.eStateAttaching:
                                    debug("process attaching")
                                elif state == lldb.eStateLaunching:
                                    debug("process launching")
                        else:
                            debug('event = %s' % (event))
                    else:
                        # timeout waiting for an event
                        print "no process event for %u seconds, killing the process..." % (
                            options.event_timeout)
                        done = True
                if options.show_output:
                    process_stdout = process.GetSTDOUT(1024)
                    if process_stdout:
                        print "Process STDOUT:\n%s" % (process_stdout)
                        while process_stdout:
                            process_stdout = process.GetSTDOUT(1024)
                            print process_stdout
                    process_stderr = process.GetSTDERR(1024)
                    if process_stderr:
                        print "Process STDERR:\n%s" % (process_stderr)
                        while process_stderr:
                            process_stderr = process.GetSTDERR(1024)
                            print process_stderr

                process.Kill()
            else:
                if error:
                    print error
                else:
                    if launch_info:
                        print 'error: launch failed'
                    else:
                        print 'error: attach failed'

    lldb.SBDebugger.Terminate()
Beispiel #20
0
    def test(self):
        """Test stepping over watchpoints."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(self.target, VALID_TARGET)

        lldbutil.run_break_set_by_symbol(self, 'main')

        process = target.LaunchSimple(None, None,
                                      self.get_process_working_directory())
        self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        PROCESS_STOPPED)

        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        self.assertTrue(thread.IsValid(), "Failed to get thread.")

        frame = thread.GetFrameAtIndex(0)
        self.assertTrue(frame.IsValid(), "Failed to get frame.")

        read_value = frame.FindValue('g_watch_me_read',
                                     lldb.eValueTypeVariableGlobal)
        self.assertTrue(read_value.IsValid(), "Failed to find read value.")

        error = lldb.SBError()

        # resolve_location=True, read=True, write=False
        read_watchpoint = read_value.Watch(True, True, False, error)
        self.assertTrue(
            error.Success(),
            "Error while setting watchpoint: %s" % error.GetCString())
        self.assertTrue(read_watchpoint, "Failed to set read watchpoint.")

        thread.StepOver()
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonWatchpoint,
                        STOPPED_DUE_TO_WATCHPOINT)
        self.assertTrue(thread.GetStopDescription(20) == 'watchpoint 1')

        process.Continue()
        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        PROCESS_STOPPED)
        self.assertTrue(thread.GetStopDescription(20) == 'step over')

        self.step_inst_for_watchpoint(1)

        write_value = frame.FindValue('g_watch_me_write',
                                      lldb.eValueTypeVariableGlobal)
        self.assertTrue(write_value, "Failed to find write value.")

        # Most of the MIPS boards provide only one H/W watchpoints, and S/W
        # watchpoints are not supported yet
        arch = self.getArchitecture()
        if re.match("^mips", arch):
            self.runCmd("watchpoint delete 1")

        # resolve_location=True, read=False, write=True
        write_watchpoint = write_value.Watch(True, False, True, error)
        self.assertTrue(write_watchpoint, "Failed to set write watchpoint.")
        self.assertTrue(
            error.Success(),
            "Error while setting watchpoint: %s" % error.GetCString())

        thread.StepOver()
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonWatchpoint,
                        STOPPED_DUE_TO_WATCHPOINT)
        self.assertTrue(thread.GetStopDescription(20) == 'watchpoint 2')

        process.Continue()
        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        PROCESS_STOPPED)
        self.assertTrue(thread.GetStopDescription(20) == 'step over')

        self.step_inst_for_watchpoint(2)
Beispiel #21
0
    def do_test(self):
        target = self.createTestTarget()

        # Now create a breakpoint in main.c at the source matching
        # "Set a breakpoint here"
        breakpoint = target.BreakpointCreateBySourceRegex(
            "Set a breakpoint here", lldb.SBFileSpec("main.c"))
        self.assertTrue(breakpoint and breakpoint.GetNumLocations() >= 1,
                        VALID_BREAKPOINT)

        error = lldb.SBError()
        # This is the launch info.  If you want to launch with arguments or
        # environment variables, add them using SetArguments or
        # SetEnvironmentEntries

        launch_info = target.GetLaunchInfo()
        process = target.Launch(launch_info, error)
        self.assertTrue(process, PROCESS_IS_VALID)

        # Did we hit our breakpoint?
        from lldbsuite.test.lldbutil import get_threads_stopped_at_breakpoint
        threads = get_threads_stopped_at_breakpoint(process, breakpoint)
        self.assertEqual(len(threads), 1,
                         "There should be a thread stopped at our breakpoint")

        # The hit count for the breakpoint should be 1.
        self.assertEquals(breakpoint.GetHitCount(), 1)

        frame = threads[0].GetFrameAtIndex(0)
        command_result = lldb.SBCommandReturnObject()
        interp = self.dbg.GetCommandInterpreter()

        # Just get args:
        result = interp.HandleCommand("frame var -l", command_result)
        self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult,
                         "frame var -a didn't succeed")
        output = command_result.GetOutput()
        self.assertIn("argc", output, "Args didn't find argc")
        self.assertIn("argv", output, "Args didn't find argv")
        self.assertNotIn("test_var", output, "Args found a local")
        self.assertNotIn("g_var", output, "Args found a global")

        # Just get locals:
        result = interp.HandleCommand("frame var -a", command_result)
        self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult,
                         "frame var -a didn't succeed")
        output = command_result.GetOutput()
        self.assertNotIn("argc", output, "Locals found argc")
        self.assertNotIn("argv", output, "Locals found argv")
        self.assertIn("test_var", output, "Locals didn't find test_var")
        self.assertNotIn("g_var", output, "Locals found a global")

        # Get the file statics:
        result = interp.HandleCommand("frame var -l -a -g", command_result)
        self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult,
                         "frame var -a didn't succeed")
        output = command_result.GetOutput()
        self.assertNotIn("argc", output, "Globals found argc")
        self.assertNotIn("argv", output, "Globals found argv")
        self.assertNotIn("test_var", output, "Globals found test_var")
        self.assertIn("g_var", output, "Globals didn't find g_var")
Beispiel #22
0
    def test_with_python_api(self):
        """Test that adding, deleting and modifying watchpoints sends the appropriate events."""
        self.build()

        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        self.main_source_spec = lldb.SBFileSpec(self.main_source)

        break_in_main = target.BreakpointCreateBySourceRegex(
            '// Put a breakpoint here.', self.main_source_spec)
        self.assertTrue(break_in_main, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple(None, None,
                                      self.get_process_working_directory())

        self.assertTrue(process, PROCESS_IS_VALID)

        # The stop reason of the thread should be breakpoint.
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, break_in_main)

        if len(threads) != 1:
            self.fail("Failed to stop at first breakpoint in main.")

        thread = threads[0]
        frame = thread.GetFrameAtIndex(0)
        local_var = frame.FindVariable("local_var")
        self.assertTrue(local_var.IsValid())

        self.listener = lldb.SBListener("com.lldb.testsuite_listener")
        self.target_bcast = target.GetBroadcaster()
        self.target_bcast.AddListener(
            self.listener, lldb.SBTarget.eBroadcastBitWatchpointChanged)
        self.listener.StartListeningForEvents(
            self.target_bcast, lldb.SBTarget.eBroadcastBitWatchpointChanged)

        error = lldb.SBError()
        local_watch = local_var.Watch(True, False, True, error)
        if not error.Success():
            self.fail("Failed to make watchpoint for local_var: %s" %
                      (error.GetCString()))

        self.GetWatchpointEvent(lldb.eWatchpointEventTypeAdded)
        # Now change some of the features of this watchpoint and make sure we
        # get events:
        local_watch.SetEnabled(False)
        self.GetWatchpointEvent(lldb.eWatchpointEventTypeDisabled)

        local_watch.SetEnabled(True)
        self.GetWatchpointEvent(lldb.eWatchpointEventTypeEnabled)

        local_watch.SetIgnoreCount(10)
        self.GetWatchpointEvent(lldb.eWatchpointEventTypeIgnoreChanged)

        condition = "1 == 2"
        local_watch.SetCondition(condition)
        self.GetWatchpointEvent(lldb.eWatchpointEventTypeConditionChanged)

        self.assertTrue(
            local_watch.GetCondition() == condition,
            'make sure watchpoint condition is "' + condition + '"')
Beispiel #23
0
    def test_watch_val(self):
        """Exercise SBValue.Watch() API to set a watchpoint."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Now create a breakpoint on main.c.
        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
        self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1,
                        VALID_BREAKPOINT)

        # Now launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None,
                                      self.get_process_working_directory())

        # We should be stopped due to the breakpoint.  Get frame #0.
        process = target.GetProcess()
        self.assertState(process.GetState(), lldb.eStateStopped,
                         PROCESS_STOPPED)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        frame0 = thread.GetFrameAtIndex(0)

        # Watch 'global' for read and write.
        value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
        error = lldb.SBError()
        watchpoint = value.Watch(True, True, True, error)
        self.assertTrue(
            value and watchpoint,
            "Successfully found the variable and set a watchpoint")
        self.DebugSBValue(value)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        print(watchpoint)

        # Continue.  Expect the program to stop due to the variable being
        # written to.
        process.Continue()

        if (self.TraceOn()):
            lldbutil.print_stacktraces(process)

        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonWatchpoint)
        self.assertTrue(thread, "The thread stopped due to watchpoint")
        self.DebugSBValue(value)

        # Continue.  Expect the program to stop due to the variable being read
        # from.
        process.Continue()

        if (self.TraceOn()):
            lldbutil.print_stacktraces(process)

        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonWatchpoint)
        self.assertTrue(thread, "The thread stopped due to watchpoint")
        self.DebugSBValue(value)

        # Continue the process.  We don't expect the program to be stopped
        # again.
        process.Continue()

        # At this point, the inferior process should have exited.
        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)

        self.dbg.DeleteTarget(target)
        self.assertFalse(watchpoint.IsValid())
Beispiel #24
0
def display_match_results(result,
                          options,
                          arg_str_description,
                          expr_sbvalue,
                          print_no_matches=True):
    if expr_sbvalue.error.Success():
        if expr_sbvalue.unsigned:
            match_value = lldb.value(expr_sbvalue)
            i = 0
            match_idx = 0
            while 1:
                print_entry = True
                match_entry = match_value[i]
                i += 1
                if i >= options.max_matches:
                    result.AppendMessage(
                        'error: the max number of matches (%u) was reached, use the --max-matches option to get more results'
                        % (options.max_matches))
                    break
                malloc_addr = match_entry.addr.sbvalue.unsigned
                if malloc_addr == 0:
                    break
                malloc_size = int(match_entry.size)
                offset = int(match_entry.offset)

                if options.offset >= 0 and options.offset != offset:
                    print_entry = False
                else:
                    match_addr = malloc_addr + offset
                    dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(
                        lldb.eDynamicCanRunTarget)
                    description = '[%u] %s: addr = 0x%x' % (
                        match_idx, arg_str_description, malloc_addr)
                    if offset != 0:
                        description += ' + %u' % (offset)
                    description += ', size = %u' % (malloc_size)
                    derefed_dynamic_value = None
                    if dynamic_value.type.name == 'void *':
                        if options.type == 'pointer' and malloc_size == 4096:
                            error = lldb.SBError()
                            data = bytearray(
                                lldb.process.ReadMemory(
                                    malloc_addr, 16, error))
                            if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
                                description += ', type = (AUTORELEASE!)'
                    else:
                        derefed_dynamic_value = dynamic_value.deref
                        if derefed_dynamic_value:
                            derefed_dynamic_type = derefed_dynamic_value.type
                            derefed_dynamic_type_size = derefed_dynamic_type.size
                            derefed_dynamic_type_name = derefed_dynamic_type.name
                            description += ', type = %s <%u>' % (
                                derefed_dynamic_type_name,
                                derefed_dynamic_type_size)
                            if offset < derefed_dynamic_type_size:
                                member_list = list()
                                get_member_types_for_offset(
                                    derefed_dynamic_type, offset, member_list)
                                if member_list:
                                    member_path = ''
                                    for member in member_list:
                                        member_name = member.name
                                        if member_name:
                                            if member_path:
                                                member_path += '.'
                                            member_path += member_name
                                    if member_path:
                                        if options.ivar_regex_blacklist:
                                            for ivar_regex in options.ivar_regex_blacklist:
                                                if ivar_regex.match(
                                                        member_path):
                                                    print_entry = False
                                        description += ', ivar = %s' % (
                                            member_path)
                if print_entry:
                    match_idx += 1
                    result_output = ''
                    if description:
                        result_output += description
                        if options.print_type and derefed_dynamic_value:
                            result_output += '%s' % (derefed_dynamic_value)
                        if options.print_object_description and dynamic_value:
                            desc = dynamic_value.GetObjectDescription()
                            if desc:
                                result_output += ', po=%s' % (desc)
                    if result_output:
                        result.AppendMessage(result_output)
                    if options.memory:
                        cmd_result = lldb.SBCommandReturnObject()
                        memory_command = "memory read -f %s 0x%x 0x%x" % (
                            options.format, malloc_addr,
                            malloc_addr + malloc_size)
                        lldb.debugger.GetCommandInterpreter().HandleCommand(
                            memory_command, cmd_result)
                        result.AppendMessage(cmd_result.GetOutput())
                    if options.stack_history:
                        dump_stack_history_entries(result, malloc_addr, 1)
                    elif options.stack:
                        dump_stack_history_entries(result, malloc_addr, 0)
            return i
        elif print_no_matches:
            result.AppendMessage('no matches found for %s' %
                                 (arg_str_description))
    else:
        result.AppendMessage(str(expr_sbvalue.error))
    return 0
Beispiel #25
0
    def test_access_my_int(self):
        """Test access 'my_int' using Python SBProcess.GetByteOrder() and other APIs."""
        self.build()
        exe = os.path.join(os.getcwd(), "a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

        # Launch the process, and do not stop at the entry point.
        process = target.LaunchSimple (None, None, self.get_process_working_directory())

        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
        self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
        frame = thread.GetFrameAtIndex(0)

        # Get the SBValue for the global variable 'my_int'.
        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
        self.DebugSBValue(val)

        # If the variable does not have a load address, there's no sense continuing.
        if not val.GetLocation().startswith("0x"):
            return

        # OK, let's get the hex location of the variable.
        location = int(val.GetLocation(), 16)

        # Note that the canonical from of the bytearray is little endian.
        from lldbsuite.test.lldbutil import int_to_bytearray, bytearray_to_int

        byteSize = val.GetByteSize()
        bytes = int_to_bytearray(256, byteSize)

        byteOrder = process.GetByteOrder()
        if byteOrder == lldb.eByteOrderBig:
            bytes.reverse()
        elif byteOrder == lldb.eByteOrderLittle:
            pass
        else:
            # Neither big endian nor little endian?  Return for now.
            # Add more logic here if we want to handle other types.
            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)
        error = lldb.SBError()
        result = process.WriteMemory(location, new_value, error)
        if not error.Success() or result != byteSize:
            self.fail("SBProcess.WriteMemory() failed")

        # Make sure that the val we got originally updates itself to notice the change:
        self.expect(val.GetValue(),
                    "SBProcess.ReadMemory() successfully writes (int)256 to the memory location for 'my_int'",
                    exe=False,
            startstr = '256')

        # And for grins, get the SBValue for the global variable 'my_int' again, to make sure that also tracks the new value:
        val = frame.FindValue("my_int", lldb.eValueTypeVariableGlobal)
        self.expect(val.GetValue(),
                    "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 = process.ReadMemory(location, byteSize, error)
        if not error.Success():
            self.fail("SBProcess.ReadMemory() failed")

        # Use "ascii" as the encoding because each element of 'content' is in the range [0..255].
        new_bytes = bytearray(content, "ascii")

        # The bytearray_to_int utility function expects a little endian bytearray.
        if byteOrder == lldb.eByteOrderBig:
            new_bytes.reverse()

        new_value = bytearray_to_int(new_bytes, byteSize)
        if new_value != 256:
            self.fail("Memory content read from 'my_int' does not match (int)256")

        # Dump the memory content....
        if self.TraceOn():
            for i in new_bytes:
                print("byte:", i)
Beispiel #26
0
    def test_set_watch_ignore_count(self):
        """Test SBWatchpoint.SetIgnoreCount() API."""
        self.build()
        exe = self.getBuildArtifact("a.out")

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # Create a breakpoint on main.c in order to set our watchpoint later.
        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
        self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1,
                        VALID_BREAKPOINT)

        # Now launch the process, and do not stop at the entry point.
        process = target.LaunchSimple(None, None,
                                      self.get_process_working_directory())

        # We should be stopped due to the breakpoint.  Get frame #0.
        process = target.GetProcess()
        self.assertEqual(process.GetState(), lldb.eStateStopped,
                         PROCESS_STOPPED)
        thread = lldbutil.get_stopped_thread(process,
                                             lldb.eStopReasonBreakpoint)
        frame0 = thread.GetFrameAtIndex(0)

        # Watch 'global' for read and write.
        value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
        error = lldb.SBError()
        watchpoint = value.Watch(True, True, True, error)
        self.assertTrue(
            value and watchpoint,
            "Successfully found the variable and set a watchpoint")
        self.DebugSBValue(value)

        # Hide stdout if not running with '-t' option.
        if not self.TraceOn():
            self.HideStdout()

        # There should be only 1 watchpoint location under the target.
        self.assertEqual(target.GetNumWatchpoints(), 1)
        watchpoint = target.GetWatchpointAtIndex(0)
        self.assertTrue(watchpoint.IsEnabled())
        self.assertEqual(watchpoint.GetIgnoreCount(), 0)
        watch_id = watchpoint.GetID()
        self.assertNotEqual(watch_id, 0)
        print(watchpoint)

        # Now immediately set the ignore count to 2.  When we continue, expect the
        # inferior to run to its completion without stopping due to watchpoint.
        watchpoint.SetIgnoreCount(2)
        print(watchpoint)
        process.Continue()

        # At this point, the inferior process should have exited.
        self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)

        # Verify some vital statistics.
        self.assertTrue(watchpoint)
        self.assertEqual(watchpoint.GetWatchSize(), 4)
        self.assertEqual(watchpoint.GetHitCount(), 2)
        print(watchpoint)
Beispiel #27
0
target = dbg.CreateTarget(binpath)

for module in target.module_iter():
    print str(module)

    for symbol in module:
        if (symbol.GetType() == lldb.eSymbolTypeCode):
            if (symbol.GetName()):
                print("{} {}-{}".format(symbol.GetName(),
                                        symbol.GetStartAddress(),
                                        symbol.GetEndAddress()))
                target.BreakpointCreateByName(symbol.GetName(), binpath)

print("Start Tracing...")

error = lldb.SBError()
listener = lldb.SBListener("my listener")
event = lldb.SBEvent()
stream = lldb.SBStream()

process = target.Launch(
    listener,
    None,  # argv
    None,  # envp
    None,  # stdin_path
    None,  # stdout_path
    None,  # stderr_path
    None,  # working directory
    0,  # launch flag
    True,  # stop at entry
    error)  # error
Beispiel #28
0
    def test_with_python(self):
        """Test getting return values from stepping out."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        (self.target, self.process, thread,
         inner_sint_bkpt) = lldbutil.run_to_name_breakpoint(self,
                                                            "inner_sint",
                                                            exe_name=exe)

        error = lldb.SBError()

        # inner_sint returns the variable value, so capture that here:
        in_int = thread.GetFrameAtIndex(0).FindVariable(
            "value").GetValueAsSigned(error)
        self.assertTrue(error.Success())

        thread.StepOut()

        self.assertTrue(self.process.GetState() == lldb.eStateStopped)
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)

        frame = thread.GetFrameAtIndex(0)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "outer_sint(int)")

        return_value = thread.GetStopReturnValue()
        self.assertTrue(return_value.IsValid())

        ret_int = return_value.GetValueAsSigned(error)
        self.assertTrue(error.Success())
        self.assertTrue(in_int == ret_int)

        # Run again and we will stop in inner_sint the second time outer_sint is called.
        # Then test stepping out two frames at once:

        thread_list = lldbutil.continue_to_breakpoint(self.process,
                                                      inner_sint_bkpt)
        self.assertTrue(len(thread_list) == 1)
        thread = thread_list[0]

        # We are done with the inner_sint breakpoint:
        self.target.BreakpointDelete(inner_sint_bkpt.GetID())

        frame = thread.GetFrameAtIndex(1)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "outer_sint(int)")
        in_int = frame.FindVariable("value").GetValueAsSigned(error)
        self.assertTrue(error.Success())

        thread.StepOutOfFrame(frame)

        self.assertTrue(self.process.GetState() == lldb.eStateStopped)
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)
        frame = thread.GetFrameAtIndex(0)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "main")

        ret_value = thread.GetStopReturnValue()
        self.assertTrue(return_value.IsValid())
        ret_int = ret_value.GetValueAsSigned(error)
        self.assertTrue(error.Success())
        self.assertTrue(2 * in_int == ret_int)

        # Now try some simple returns that have different types:
        inner_float_bkpt = self.target.BreakpointCreateByName(
            "inner_float(float)", exe)
        self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT)
        self.process.Continue()
        thread_list = lldbutil.get_threads_stopped_at_breakpoint(
            self.process, inner_float_bkpt)
        self.assertTrue(len(thread_list) == 1)
        thread = thread_list[0]

        self.target.BreakpointDelete(inner_float_bkpt.GetID())

        frame = thread.GetFrameAtIndex(0)
        in_value = frame.FindVariable("value")
        in_float = float(in_value.GetValue())
        thread.StepOut()

        self.assertTrue(self.process.GetState() == lldb.eStateStopped)
        self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete)

        frame = thread.GetFrameAtIndex(0)
        fun_name = frame.GetFunctionName()
        self.assertTrue(fun_name == "outer_float(float)")

        #return_value = thread.GetStopReturnValue()
        #self.assertTrue(return_value.IsValid())
        #return_float = float(return_value.GetValue())

        #self.assertTrue(in_float == return_float)

        if not self.affected_by_radar_34562999(
        ) and not self.affected_by_pr44132():
            self.return_and_test_struct_value("return_one_int")
            self.return_and_test_struct_value("return_two_int")
            self.return_and_test_struct_value("return_three_int")
            self.return_and_test_struct_value("return_four_int")
            if not self.affected_by_pr33042():
                self.return_and_test_struct_value("return_five_int")

            self.return_and_test_struct_value("return_two_double")
            self.return_and_test_struct_value("return_one_double_two_float")
            self.return_and_test_struct_value(
                "return_one_int_one_float_one_int")

            self.return_and_test_struct_value("return_one_pointer")
            self.return_and_test_struct_value("return_two_pointer")
            self.return_and_test_struct_value("return_one_float_one_pointer")
            self.return_and_test_struct_value("return_one_int_one_pointer")
            self.return_and_test_struct_value("return_three_short_one_float")

            self.return_and_test_struct_value("return_one_int_one_double")
            self.return_and_test_struct_value(
                "return_one_int_one_double_one_int")
            self.return_and_test_struct_value(
                "return_one_short_one_double_one_short")
            self.return_and_test_struct_value(
                "return_one_float_one_int_one_float")
            self.return_and_test_struct_value("return_two_float")
            # I am leaving out the packed test until we have a way to tell CLANG
            # about alignment when reading DWARF for packed types.
            #self.return_and_test_struct_value ("return_one_int_one_double_packed")
            self.return_and_test_struct_value("return_one_int_one_long")
    def test(self):
        """Test expr + formatters for good interoperability."""
        self.build()

        # This is the function to remove the custom formats in order to have a
        # clean slate for the next test case.
        def cleanup():
            self.runCmd('type summary clear', check=False)
            self.runCmd('type synthetic clear', check=False)

        # Execute the cleanup function during test case tear down.
        self.addTearDownHook(cleanup)
        """Test expr + formatters for good interoperability."""
        self.runCmd("file " + self.getBuildArtifact("a.out"),
                    CURRENT_EXECUTABLE_SET)

        lldbutil.run_break_set_by_file_and_line(self,
                                                "main.cpp",
                                                self.line,
                                                loc_exact=True)

        self.runCmd("run", RUN_SUCCEEDED)
        self.runCmd("command script import formatters.py")
        self.runCmd("command script import foosynth.py")

        if self.TraceOn():
            self.runCmd("frame variable foo1 --show-types")
            self.runCmd("frame variable foo1.b --show-types")
            self.runCmd("frame variable foo1.b.b_ref --show-types")

        self.filecheck("expression --show-types -- *(new_foo(47))", __file__,
                       '-check-prefix=EXPR-TYPES-NEW-FOO')
        # EXPR-TYPES-NEW-FOO: (foo) ${{.*}} = {
        # EXPR-TYPES-NEW-FOO-NEXT:   (int) a = 47
        # EXPR-TYPES-NEW-FOO-NEXT:   (int *) a_ptr = 0x
        # EXPR-TYPES-NEW-FOO-NEXT:   (bar) b = {
        # EXPR-TYPES-NEW-FOO-NEXT:     (int) i = 94
        # EXPR-TYPES-NEW-FOO-NEXT:     (int *) i_ptr = 0x
        # EXPR-TYPES-NEW-FOO-NEXT:     (baz) b = {
        # EXPR-TYPES-NEW-FOO-NEXT:       (int) h = 97
        # EXPR-TYPES-NEW-FOO-NEXT:       (int) k = 99
        # EXPR-TYPES-NEW-FOO-NEXT:     }
        # EXPR-TYPES-NEW-FOO-NEXT:     (baz &) b_ref = 0x
        # EXPR-TYPES-NEW-FOO-NEXT:   }
        # EXPR-TYPES-NEW-FOO-NEXT: }

        self.runCmd("type summary add -F formatters.foo_SummaryProvider3 foo")
        self.filecheck("expression foo1", __file__,
                       '-check-prefix=EXPR-FOO1opts')
        # EXPR-FOO1opts: (foo) $
        # EXPR-FOO1opts-SAME: a = 12
        # EXPR-FOO1opts-SAME: a_ptr = {{[0-9]+}} -> 13
        # EXPR-FOO1opts-SAME: i = 24
        # EXPR-FOO1opts-SAME: i_ptr = {{[0-9]+}} -> 25
        # EXPR-FOO1opts-SAME: b_ref = {{[0-9]+}}
        # EXPR-FOO1opts-SAME: h = 27
        # EXPR-FOO1opts-SAME: k = 29
        # EXPR-FOO1opts-SAME: WITH_OPTS

        self.runCmd("type summary delete foo")

        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")

        self.expect("expression new_int(12)", substrs=['(int *) $', ' = 0x'])

        self.runCmd(
            "type summary add -s \"${var%pointer} -> ${*var%decimal}\" \"int *\""
        )

        self.expect("expression new_int(12)",
                    substrs=['(int *) $', '= 0x', ' -> 12'])

        self.expect("expression foo1.a_ptr",
                    substrs=['(int *) $', '= 0x', ' -> 13'])

        self.filecheck("expression foo1", __file__, '-check-prefix=EXPR-FOO1')
        # EXPR-FOO1: (foo) $
        # EXPR-FOO1-SAME: a = 12
        # EXPR-FOO1-SAME: a_ptr = {{[0-9]+}} -> 13
        # EXPR-FOO1-SAME: i = 24
        # EXPR-FOO1-SAME: i_ptr = {{[0-9]+}} -> 25
        # EXPR-FOO1-SAME: b_ref = {{[0-9]+}}
        # EXPR-FOO1-SAME: h = 27
        # EXPR-FOO1-SAME: k = 29

        self.filecheck("expression --ptr-depth=1 -- new_foo(47)", __file__,
                       '-check-prefix=EXPR-PTR-DEPTH1')
        # EXPR-PTR-DEPTH1: (foo *) $
        # EXPR-PTR-DEPTH1-SAME: a = 47
        # EXPR-PTR-DEPTH1-SAME: a_ptr = {{[0-9]+}} -> 48
        # EXPR-PTR-DEPTH1-SAME: i = 94
        # EXPR-PTR-DEPTH1-SAME: i_ptr = {{[0-9]+}} -> 95

        self.filecheck("expression foo2", __file__, '-check-prefix=EXPR-FOO2')
        # EXPR-FOO2: (foo) $
        # EXPR-FOO2-SAME: a = 121
        # EXPR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122
        # EXPR-FOO2-SAME: i = 242
        # EXPR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243
        # EXPR-FOO2-SAME: h = 245
        # EXPR-FOO2-SAME: k = 247

        object_name = self.res.GetOutput()
        object_name = object_name[7:]
        object_name = object_name[0:object_name.find(' =')]

        self.filecheck("frame variable foo2", __file__,
                       '-check-prefix=VAR-FOO2')
        # VAR-FOO2: (foo) foo2
        # VAR-FOO2-SAME: a = 121
        # VAR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122
        # VAR-FOO2-SAME: i = 242
        # VAR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243
        # VAR-FOO2-SAME: h = 245
        # VAR-FOO2-SAME: k = 247

        # The object is the same as foo2, so use the EXPR-FOO2 checks.
        self.filecheck("expression $" + object_name, __file__,
                       '-check-prefix=EXPR-FOO2')

        self.runCmd("type summary delete foo")
        self.runCmd(
            "type synthetic add --python-class foosynth.FooSyntheticProvider foo"
        )

        self.expect("expression --show-types -- $" + object_name,
                    substrs=['(foo) $', ' = {', '(int) *i_ptr = 243'])

        self.runCmd("n")
        self.runCmd("n")

        self.runCmd("type synthetic delete foo")
        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")

        self.expect("expression foo2",
                    substrs=[
                        '(foo) $', 'a = 7777', 'a_ptr = ', ' -> 122',
                        'i = 242', 'i_ptr = ', ' -> 8888'
                    ])

        self.expect("expression $" + object_name + '.a', substrs=['7777'])

        self.expect("expression *$" + object_name + '.b.i_ptr',
                    substrs=['8888'])

        self.expect("expression $" + object_name,
                    substrs=[
                        '(foo) $', 'a = 121', 'a_ptr = ', ' -> 122', 'i = 242',
                        'i_ptr = ', ' -> 8888', 'h = 245', 'k = 247'
                    ])

        self.runCmd("type summary delete foo")
        self.runCmd(
            "type synthetic add --python-class foosynth.FooSyntheticProvider foo"
        )

        self.expect("expression --show-types -- $" + object_name,
                    substrs=['(foo) $', ' = {', '(int) *i_ptr = 8888'])

        self.runCmd("n")

        self.runCmd("type synthetic delete foo")
        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")

        self.expect("expression $" + object_name,
                    substrs=[
                        '(foo) $', 'a = 121', 'a_ptr = ', ' -> 122', 'i = 242',
                        'i_ptr = ', ' -> 8888', 'k = 247'
                    ])

        process = self.dbg.GetSelectedTarget().GetProcess()
        thread = process.GetThreadAtIndex(0)
        frame = thread.GetSelectedFrame()

        frozen = frame.EvaluateExpression("$" + object_name + ".a_ptr")

        a_data = frozen.GetPointeeData()

        error = lldb.SBError()
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 0) == 122, '*a_ptr = 122')

        ret = line_number("main.cpp", "Done initializing")
        self.runCmd("thread until " + str(ret))

        self.expect("frame variable numbers",
                    substrs=['1', '2', '3', '4', '5'])

        self.expect("expression numbers", substrs=['1', '2', '3', '4', '5'])

        frozen = frame.EvaluateExpression("&numbers")

        a_data = frozen.GetPointeeData(0, 1)

        self.assertTrue(
            a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5')

        frozen = frame.EvaluateExpression("numbers")

        a_data = frozen.GetData()

        self.assertTrue(
            a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4')
        self.assertTrue(
            a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5')
Beispiel #30
0
def simple_backtrace(debugger):
    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    cur_thread = process.GetSelectedThread()

    initial_fp = cur_thread.GetFrameAtIndex(0).GetFP()

    # If the pseudoreg "fp" isn't recognized, on arm hardcode to r7 which is
    # correct for Darwin programs.
    if initial_fp == lldb.LLDB_INVALID_ADDRESS and target.triple[0:3] == "arm":
        for reggroup in cur_thread.GetFrameAtIndex(1).registers:
            if reggroup.GetName() == "General Purpose Registers":
                for reg in reggroup:
                    if reg.GetName() == "r7":
                        initial_fp = int(reg.GetValue(), 16)

    module_list = []
    address_list = [cur_thread.GetFrameAtIndex(0).GetPC()]
    this_module = backtrace_print_frame(target, 0,
                                        cur_thread.GetFrameAtIndex(0).GetPC(),
                                        initial_fp)
    print_stack_frame(process, initial_fp)
    print ""
    if this_module is not None:
        module_list.append(this_module)
    if cur_thread.GetNumFrames() < 2:
        return [module_list, address_list]

    cur_fp = process.ReadPointerFromMemory(initial_fp, lldb.SBError())
    cur_pc = process.ReadPointerFromMemory(
        initial_fp + process.GetAddressByteSize(), lldb.SBError())

    frame_num = 1

    while cur_pc != 0 and cur_fp != 0 and cur_pc != lldb.LLDB_INVALID_ADDRESS and cur_fp != lldb.LLDB_INVALID_ADDRESS:
        address_list.append(cur_pc)
        this_module = backtrace_print_frame(target, frame_num, cur_pc, cur_fp)
        print_stack_frame(process, cur_fp)
        print ""
        if this_module is not None:
            module_list.append(this_module)
        frame_num = frame_num + 1
        next_pc = 0
        next_fp = 0
        if target.triple[0:6] == "x86_64" or target.triple[
                0:4] == "i386" or target.triple[0:3] == "arm":
            error = lldb.SBError()
            next_pc = process.ReadPointerFromMemory(
                cur_fp + process.GetAddressByteSize(), error)
            if not error.Success():
                next_pc = 0
            next_fp = process.ReadPointerFromMemory(cur_fp, error)
            if not error.Success():
                next_fp = 0
        # Clear the 0th bit for arm frames - this indicates it is a thumb frame
        if target.triple[0:3] == "arm" and (next_pc & 1) == 1:
            next_pc = next_pc & ~1
        cur_pc = next_pc
        cur_fp = next_fp
    this_module = backtrace_print_frame(target, frame_num, cur_pc, cur_fp)
    print_stack_frame(process, cur_fp)
    print ""
    if this_module is not None:
        module_list.append(this_module)
    return [module_list, address_list]