TestClassTypesDisassembly.py revision 10cd823ddc9ef4124fafdb43ca24da28f5c8fa32
1"""
2Test the lldb disassemble command on each call frame when stopped on C's ctor.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9
10class IterateFrameAndDisassembleTestCase(TestBase):
11
12    mydir = "class_types"
13
14    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
15    def test_with_dsym_and_run_command(self):
16        """Disassemble each call frame when stopped on C's constructor."""
17        self.buildDsym()
18        self.disassemble_call_stack()
19
20    def test_with_dwarf_and_run_command(self):
21        """Disassemble each call frame when stopped on C's constructor."""
22        self.buildDwarf()
23        self.disassemble_call_stack()
24
25    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
26    def test_with_dsym_and_python_api(self):
27        """Disassemble each call frame when stopped on C's constructor."""
28        self.buildDsym()
29        self.disassemble_call_stack_api()
30
31    def test_with_dwarf_and_python_api(self):
32        """Disassemble each call frame when stopped on C's constructor."""
33        self.buildDwarf()
34        self.disassemble_call_stack_api()
35
36    def breakOnCtor(self):
37        """Setup/run the program so it stops on C's constructor."""
38        exe = os.path.join(os.getcwd(), "a.out")
39        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
40
41        # Break on the ctor function of class C.
42        self.expect("breakpoint set -f main.cpp -l 93", BREAKPOINT_CREATED,
43            startstr = "Breakpoint created: 1: file ='main.cpp', line = 93, locations = 1")
44
45        self.runCmd("run", RUN_SUCCEEDED)
46
47        # The stop reason of the thread should be breakpoint.
48        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
49            substrs = ['state is Stopped',
50                       'stop reason = breakpoint'])
51
52        # We should be stopped on the ctor function of class C.
53        self.expect("thread backtrace", BACKTRACE_DISPLAYED_CORRECTLY,
54            substrs = ['C::C'])
55
56    def disassemble_call_stack(self):
57        """Disassemble each call frame when stopped on C's constructor."""
58        self.breakOnCtor()
59
60        raw_output = self.res.GetOutput()
61        frameRE = re.compile(r"""
62                              ^\s\sframe        # heading for the frame info,
63                              .*                # wildcard, and
64                              0x[0-9a-f]{16}    # the frame pc, and
65                              \sa.out`(.+)      # module`function, and
66                              \s\+\s            # the rest ' + ....'
67                              """, re.VERBOSE)
68        for line in raw_output.split(os.linesep):
69            match = frameRE.search(line)
70            if match:
71                function = match.group(1)
72                #print "line:", line
73                #print "function:", function
74                self.runCmd("disassemble -n '%s'" % function)
75
76    def disassemble_call_stack_api(self):
77        """Disassemble each call frame when stopped on C's constructor."""
78        self.breakOnCtor()
79
80        # Now use the Python API to get at each function on the call stack and
81        # disassemble it.
82        target = self.dbg.GetSelectedTarget()
83        process = target.GetProcess()
84        thread = process.GetThreadAtIndex(0)
85        depth = thread.GetNumFrames()
86        for i in range(depth - 1):
87            frame = thread.GetFrameAtIndex(i)
88            function = frame.GetFunction()
89            self.runCmd("disassemble -n '%s'" % function.GetName())
90
91
92if __name__ == '__main__':
93    import atexit
94    lldb.SBDebugger.Initialize()
95    atexit.register(lambda: lldb.SBDebugger.Terminate())
96    unittest2.main()
97