110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen"""
210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny ChenTest the lldb disassemble command on each call frame when stopped on C's ctor.
310cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen"""
410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chenimport os, time
610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chenimport unittest2
710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chenimport lldb
810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chenfrom lldbtest import *
9431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
1010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
1110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chenclass IterateFrameAndDisassembleTestCase(TestBase):
1210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
13b794017ee4b085b28249af1511b3bdcaef8924ceJohnny Chen    mydir = os.path.join("lang", "cpp", "class_types")
14a749646c914e6731cb789bcd0f25e5740c47e722Matt Kopec    failing_compilers = ['clang', 'gcc']
1510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
1610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
1721b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
1810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    def test_with_dsym_and_run_command(self):
1910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        """Disassemble each call frame when stopped on C's constructor."""
2010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.buildDsym()
2110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.disassemble_call_stack()
2210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
2321b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
249aa84a120ae567bb5fbdd4a77c744a38e0d85e8bEd Maste    @expectedFailureFreeBSD('llvm.org/pr14540')
25a749646c914e6731cb789bcd0f25e5740c47e722Matt Kopec    @expectedFailureLinux('llvm.org/pr14540', failing_compilers)
2610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    def test_with_dwarf_and_run_command(self):
2710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        """Disassemble each call frame when stopped on C's constructor."""
2810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.buildDwarf()
2910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.disassemble_call_stack()
3010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
3110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
320678f8e583d79475c574cfc89f77e616fa2468c5Johnny Chen    @python_api_test
3321b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
3410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    def test_with_dsym_and_python_api(self):
3510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        """Disassemble each call frame when stopped on C's constructor."""
3610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.buildDsym()
370678f8e583d79475c574cfc89f77e616fa2468c5Johnny Chen        self.disassemble_call_stack_python()
3810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
390678f8e583d79475c574cfc89f77e616fa2468c5Johnny Chen    @python_api_test
4021b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
419aa84a120ae567bb5fbdd4a77c744a38e0d85e8bEd Maste    @expectedFailureFreeBSD('llvm.org/pr14540')
42a749646c914e6731cb789bcd0f25e5740c47e722Matt Kopec    @expectedFailureLinux('llvm.org/pr14540', failing_compilers)
4310cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    def test_with_dwarf_and_python_api(self):
4410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        """Disassemble each call frame when stopped on C's constructor."""
4510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.buildDwarf()
460678f8e583d79475c574cfc89f77e616fa2468c5Johnny Chen        self.disassemble_call_stack_python()
4710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
487bafa919529dd7e3d87e9c3649179029d0158978Johnny Chen    def setUp(self):
490910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        # Call super's setUp().
500910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        TestBase.setUp(self)
517bafa919529dd7e3d87e9c3649179029d0158978Johnny Chen        # Find the line number to break for main.cpp.
527bafa919529dd7e3d87e9c3649179029d0158978Johnny Chen        self.line = line_number('main.cpp', '// Set break point at this line.')
537bafa919529dd7e3d87e9c3649179029d0158978Johnny Chen
5410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    def breakOnCtor(self):
5510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        """Setup/run the program so it stops on C's constructor."""
5610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        exe = os.path.join(os.getcwd(), "a.out")
5710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
5810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
5910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        # Break on the ctor function of class C.
60431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
6110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
6210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
6310cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
6410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        # The stop reason of the thread should be breakpoint.
6510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
66abe0fed36d83e1c37af9dae90c2d25db742b4515Greg Clayton            substrs = ['stopped',
6710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                       'stop reason = breakpoint'])
6810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
6910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        # We should be stopped on the ctor function of class C.
7010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.expect("thread backtrace", BACKTRACE_DISPLAYED_CORRECTLY,
7110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen            substrs = ['C::C'])
7210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
7310cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    def disassemble_call_stack(self):
7410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        """Disassemble each call frame when stopped on C's constructor."""
7510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.breakOnCtor()
7610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
7710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        raw_output = self.res.GetOutput()
7810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        frameRE = re.compile(r"""
7910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                              ^\s\sframe        # heading for the frame info,
8010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                              .*                # wildcard, and
8110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                              0x[0-9a-f]{16}    # the frame pc, and
8210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                              \sa.out`(.+)      # module`function, and
8310cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                              \s\+\s            # the rest ' + ....'
8410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                              """, re.VERBOSE)
8510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        for line in raw_output.split(os.linesep):
8610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen            match = frameRE.search(line)
8710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen            if match:
8810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                function = match.group(1)
8910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                #print "line:", line
9010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                #print "function:", function
9110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen                self.runCmd("disassemble -n '%s'" % function)
9210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
930678f8e583d79475c574cfc89f77e616fa2468c5Johnny Chen    def disassemble_call_stack_python(self):
9410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        """Disassemble each call frame when stopped on C's constructor."""
9510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        self.breakOnCtor()
9610cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
9710cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        # Now use the Python API to get at each function on the call stack and
9810cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        # disassemble it.
9910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        target = self.dbg.GetSelectedTarget()
10010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        process = target.GetProcess()
10110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        thread = process.GetThreadAtIndex(0)
10210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        depth = thread.GetNumFrames()
10310cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen        for i in range(depth - 1):
10410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen            frame = thread.GetFrameAtIndex(i)
10510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen            function = frame.GetFunction()
10643ca9c1249e496802b26c66e3a945560ebfb908cJohnny Chen            # Print the function header.
107d938c00c40de275d6abd9b67753811f9107a21a8Johnny Chen            if self.TraceOn():
108a2486f28182f39648ea6f379fb13bbd579314ef8Johnny Chen                print
109a2486f28182f39648ea6f379fb13bbd579314ef8Johnny Chen                print function
110805fec7ec90a09b94bc4515fcac9b2b03bae153bJohnny Chen            if function:
11143ca9c1249e496802b26c66e3a945560ebfb908cJohnny Chen                # Get all instructions for this function and print them out.
11243ca9c1249e496802b26c66e3a945560ebfb908cJohnny Chen                insts = function.GetInstructions(target)
113d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen                for inst in insts:
114d643c08c3d80ab16308f395aaa5aa7664d506cd3Johnny Chen                    # We could simply do 'print inst' to print out the disassembly.
115ff812486d6a8895ebf80b33431b63ffa7d216468Johnny Chen                    # But we want to print to stdout only if self.TraceOn() is True.
116ff812486d6a8895ebf80b33431b63ffa7d216468Johnny Chen                    disasm = str(inst)
117ff812486d6a8895ebf80b33431b63ffa7d216468Johnny Chen                    if self.TraceOn():
118ff812486d6a8895ebf80b33431b63ffa7d216468Johnny Chen                        print disasm
11910cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
12010cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen
12110cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chenif __name__ == '__main__':
12210cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    import atexit
12310cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    lldb.SBDebugger.Initialize()
12410cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
12510cd823ddc9ef4124fafdb43ca24da28f5c8fa32Johnny Chen    unittest2.main()
126