Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / test / API / lang / cpp / stl / TestStdCXXDisassembly.py
blob1e1b0a4d621f040be79a8b4957e7bcbb6a8120ac
1 """
2 Test the lldb disassemble command on lib stdc++.
3 """
5 import os
6 import lldb
7 from lldbsuite.test.lldbtest import *
8 import lldbsuite.test.lldbutil as lldbutil
9 from lldbsuite.test.decorators import *
12 class StdCXXDisassembleTestCase(TestBase):
13 @skipIfWindows
14 def test_stdcxx_disasm(self):
15 """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib."""
16 self.build()
17 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
18 self, "// Set break point at this line", lldb.SBFileSpec("main.cpp")
21 # Disassemble the functions on the call stack.
22 self.runCmd("thread backtrace")
23 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
24 self.assertIsNotNone(thread)
25 depth = thread.GetNumFrames()
26 for i in range(depth - 1):
27 frame = thread.GetFrameAtIndex(i)
28 function = frame.GetFunction()
29 if function.GetName():
30 self.runCmd("disassemble -n '%s'" % function.GetName())
32 lib_stdcxx = "FAILHORRIBLYHERE"
33 # Iterate through the available modules, looking for stdc++ library...
34 for i in range(target.GetNumModules()):
35 module = target.GetModuleAtIndex(i)
36 fs = module.GetFileSpec()
37 if fs.GetFilename().startswith("libstdc++") or fs.GetFilename().startswith(
38 "libc++"
40 lib_stdcxx = str(fs)
41 break
43 # At this point, lib_stdcxx is the full path to the stdc++ library and
44 # module is the corresponding SBModule.
46 self.expect(
47 lib_stdcxx, "Libraray StdC++ is located", exe=False, substrs=["lib"]
50 self.runCmd("image dump symtab '%s'" % lib_stdcxx)
51 raw_output = self.res.GetOutput()
52 # Now, look for every 'Code' symbol and feed its load address into the
53 # command: 'disassemble -s load_address -e end_address', where the
54 # end_address is taken from the next consecutive 'Code' symbol entry's
55 # load address.
57 # The load address column comes after the file address column, with both
58 # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits.
59 codeRE = re.compile(
60 r"""
61 \ Code\ {9} # ' Code' followed by 9 SPCs,
62 0x[0-9a-f]{16} # the file address column, and
63 \ # a SPC, and
64 (0x[0-9a-f]{16}) # the load address column, and
65 .* # the rest.
66 """,
67 re.VERBOSE,
69 # Maintain a start address variable; if we arrive at a consecutive Code
70 # entry, then the load address of the that entry is fed as the end
71 # address to the 'disassemble -s SA -e LA' command.
72 SA = None
73 for line in raw_output.split(os.linesep):
74 match = codeRE.search(line)
75 if match:
76 LA = match.group(1)
77 if self.TraceOn():
78 print("line:", line)
79 print("load address:", LA)
80 print("SA:", SA)
81 if SA and LA:
82 if int(LA, 16) > int(SA, 16):
83 self.runCmd("disassemble -s %s -e %s" % (SA, LA))
84 SA = LA
85 else:
86 # This entry is not a Code entry. Reset SA = None.
87 SA = None