TestStdCXXDisassembly.py revision 0910eb32b94bd67b0357d34d0951aad197742569
190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen"""
254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny ChenTest the lldb disassemble command on lib stdc++.
390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen"""
490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenimport os, time
690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenimport unittest2
790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenimport lldb
890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenfrom lldbtest import *
990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
1090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenclass StdCXXDisassembleTestCase(TestBase):
1190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
1290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen    mydir = "stl"
1390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
1445ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen    def setUp(self):
150910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        # Call super's setUp().
160910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        TestBase.setUp(self)
1745ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen        # Find the line number to break inside main().
1845ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen        self.line = line_number('main.cpp', '// Set break point at this line.')
1945ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen
2054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen    # rdar://problem/8504895
2154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen    # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]"
2290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen    @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
2390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen    def test_stdcxx_disasm(self):
2490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib."""
2590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        self.buildDefault()
2690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        exe = os.path.join(os.getcwd(), "a.out")
2790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
2890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
2945ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen        # rdar://problem/8543077
3045ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen        # test/stl: clang built binaries results in the breakpoint locations = 3,
3145ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen        # is this a problem with clang generated debug info?
3245ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen        #
3390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        # Break on line 13 of main.cpp.
3445ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
3545ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen                    BREAKPOINT_CREATED,
3645ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
3745ac7ac0a0cea43c3874d986da8b107695d630c1Johnny Chen                        self.line)
3890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
3990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
4090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
4190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        # Now let's get the target as well as the process objects.
4290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        target = self.dbg.GetSelectedTarget()
4390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        process = target.GetProcess()
4490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
4590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        # The process should be in a 'Stopped' state.
4690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        self.expect(repr(process), STOPPED_DUE_TO_BREAKPOINT, exe=False,
4790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen            substrs = ["a.out",
488e468594632a43f2062d5a364224ac15fddfdef2Johnny Chen                       "Stopped"])
4990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
5054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # Disassemble the functions on the call stack.
5154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        self.runCmd("thread backtrace")
5254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        thread = process.GetThreadAtIndex(0)
5354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        depth = thread.GetNumFrames()
5454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        for i in range(depth - 1):
5554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen            frame = thread.GetFrameAtIndex(i)
5654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen            function = frame.GetFunction()
5754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen            self.runCmd("disassemble -n '%s'" % function.GetName())
5854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen
5990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        # Iterate through the available modules, looking for stdc++ library...
6090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        for i in range(target.GetNumModules()):
6190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen            module = target.GetModuleAtIndex(i)
6290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen            fs = module.GetFileSpec()
6390d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen            if (fs.GetFilename().startswith("libstdc++")):
6490d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen                lib_stdcxx = repr(fs)
6590d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen                break
6690d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
6790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        # At this point, lib_stdcxx is the full path to the stdc++ library and
6890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        # module is the corresponding SBModule.
6990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
7090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen        self.expect(fs.GetFilename(), "Libraray StdC++ is located", exe=False,
7190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen            substrs = ["libstdc++"])
7290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
7354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        self.runCmd("image dump symtab %s" % repr(fs))
7454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        raw_output = self.res.GetOutput()
7554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # Now, look for every 'Code' symbol and feed its load address into the
7654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # command: 'disassemble -s load_address -e end_address', where the
7754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # end_address is taken from the next consecutive 'Code' symbol entry's
7854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # load address.
7954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        #
8054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # The load address column comes after the file address column, with both
8154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits.
8254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        codeRE = re.compile(r"""
8354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                             \ Code\ {9}      # ' Code' followed by 9 SPCs,
8454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                             0x[0-9a-f]{16}   # the file address column, and
8554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                             \                # a SPC, and
8654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                             (0x[0-9a-f]{16}) # the load address column, and
8754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                             .*               # the rest.
8854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                             """, re.VERBOSE)
8954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # Maintain a start address variable; if we arrive at a consecutive Code
9054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # entry, then the load address of the that entry is fed as the end
9154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        # address to the 'disassemble -s SA -e LA' command.
9254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        SA = None
9354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen        for line in raw_output.split(os.linesep):
9454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen            match = codeRE.search(line)
9554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen            if match:
9654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                LA = match.group(1)
9754e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                print "line:", line
9854e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                print "load address:", LA
9954e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                print "SA:", SA
10054e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                if SA and LA:
10154e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                    self.runCmd("disassemble -s %s -e %s" % (SA, LA))
10254e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                SA = LA
10354e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen            else:
10454e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                # This entry is not a Code entry.  Reset SA = None.
10554e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen                SA = None
10654e1ea473d083dc3d2b4a0363448f45f9faabea0Johnny Chen
10790d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen
10890d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chenif __name__ == '__main__':
10990d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen    import atexit
11090d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen    lldb.SBDebugger.Initialize()
11190d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
11290d73bc3549f1b1c64446bb3b43f5676e52ee707Johnny Chen    unittest2.main()
113