Home | History | Annotate | Download | only in class_static
      1 """
      2 Test display and Python APIs on file and class static variables.
      3 """
      4 
      5 import os, time
      6 import unittest2
      7 import lldb
      8 from lldbtest import *
      9 import lldbutil
     10 
     11 class StaticVariableTestCase(TestBase):
     12 
     13     mydir = os.path.join("lang", "cpp", "class_static")
     14     failing_compilers = ['clang', 'gcc']
     15 
     16     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     17     @dsym_test
     18     def test_with_dsym_and_run_command(self):
     19         """Test that file and class static variables display correctly."""
     20         self.buildDsym()
     21         self.static_variable_commands()
     22 
     23     @expectedFailureLinux('llvm.org/pr15261', failing_compilers) # lldb on Linux does not display the size of (class or file)static arrays
     24     @dwarf_test
     25     def test_with_dwarf_and_run_command(self):
     26         """Test that file and class static variables display correctly."""
     27         self.buildDwarf()
     28         self.static_variable_commands()
     29 
     30     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     31     @expectedFailureClang(9980907)
     32     @expectedFailureGcc(9980907)
     33     @python_api_test
     34     @dsym_test
     35     def test_with_dsym_and_python_api(self):
     36         """Test Python APIs on file and class static variables."""
     37         self.buildDsym()
     38         self.static_variable_python()
     39 
     40     @expectedFailureClang(9980907)
     41     @python_api_test
     42     @dwarf_test
     43     def test_with_dwarf_and_python_api(self):
     44         """Test Python APIs on file and class static variables."""
     45         self.buildDwarf()
     46         self.static_variable_python()
     47 
     48     def setUp(self):
     49         # Call super's setUp().
     50         TestBase.setUp(self)
     51         # Find the line number to break at.
     52         self.line = line_number('main.cpp', '// Set break point at this line.')
     53 
     54     def static_variable_commands(self):
     55         """Test that that file and class static variables display correctly."""
     56         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
     57 
     58         lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
     59 
     60         self.runCmd("run", RUN_SUCCEEDED)
     61 
     62         # The stop reason of the thread should be breakpoint.
     63         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
     64             substrs = ['stopped',
     65                        'stop reason = breakpoint'])
     66 
     67         # global variables are no longer displayed with the "frame variable" command. 
     68         self.expect('target variable A::g_points', VARIABLES_DISPLAYED_CORRECTLY,
     69             substrs = ['(PointType [2]) A::g_points'])
     70         self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY,
     71             substrs = ['(PointType [2]) g_points'])
     72 
     73         # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points.
     74         # A::g_points is an array of two elements.
     75         if sys.platform.startswith("darwin") and self.getCompiler() in ['clang', 'llvm-gcc']:
     76             self.expect("target variable A::g_points[1].x", VARIABLES_DISPLAYED_CORRECTLY,
     77                 startstr = "(int) A::g_points[1].x = 11")
     78 
     79     def static_variable_python(self):
     80         """Test Python APIs on file and class static variables."""
     81         exe = os.path.join(os.getcwd(), "a.out")
     82 
     83         target = self.dbg.CreateTarget(exe)
     84         self.assertTrue(target, VALID_TARGET)
     85 
     86         breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
     87         self.assertTrue(breakpoint, VALID_BREAKPOINT)
     88 
     89         # Now launch the process, and do not stop at entry point.
     90         process = target.LaunchSimple(None, None, os.getcwd())
     91         self.assertTrue(process, PROCESS_IS_VALID)
     92 
     93         # The stop reason of the thread should be breakpoint.
     94         thread = process.GetThreadAtIndex(0)
     95         if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
     96             from lldbutil import stop_reason_to_str
     97             self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
     98                       stop_reason_to_str(thread.GetStopReason()))
     99 
    100         # Get the SBValue of 'A::g_points' and 'g_points'.
    101         frame = thread.GetFrameAtIndex(0)
    102 
    103         # arguments =>     False
    104         # locals =>        False
    105         # statics =>       True
    106         # in_scope_only => False
    107         valList = frame.GetVariables(False, False, True, False)
    108 
    109         for val in valList:
    110             self.DebugSBValue(val)
    111             name = val.GetName()
    112             self.assertTrue(name in ['g_points', 'A::g_points'])
    113             if name == 'g_points':
    114                 self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableStatic)
    115                 self.assertTrue(val.GetNumChildren() == 2)
    116             elif name == 'A::g_points' and self.getCompiler() in ['clang', 'llvm-gcc']:
    117                 # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points.        
    118                 self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableGlobal)
    119                 self.assertTrue(val.GetNumChildren() == 2)
    120                 child1 = val.GetChildAtIndex(1)
    121                 self.DebugSBValue(child1)
    122                 child1_x = child1.GetChildAtIndex(0)
    123                 self.DebugSBValue(child1_x)
    124                 self.assertTrue(child1_x.GetTypeName() == 'int' and
    125                                 child1_x.GetValue() == '11')
    126 
    127         # SBFrame.FindValue() should also work.
    128         val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal)
    129         self.DebugSBValue(val)
    130         self.assertTrue(val.GetName() == 'A::g_points')
    131 
    132         # Also exercise the "parameter" and "local" scopes while we are at it.
    133         val = frame.FindValue("argc", lldb.eValueTypeVariableArgument)
    134         self.DebugSBValue(val)
    135         self.assertTrue(val.GetName() == 'argc')
    136 
    137         val = frame.FindValue("argv", lldb.eValueTypeVariableArgument)
    138         self.DebugSBValue(val)
    139         self.assertTrue(val.GetName() == 'argv')
    140 
    141         val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal)
    142         self.DebugSBValue(val)
    143         self.assertTrue(val.GetName() == 'hello_world')
    144 
    145 
    146 if __name__ == '__main__':
    147     import atexit
    148     lldb.SBDebugger.Initialize()
    149     atexit.register(lambda: lldb.SBDebugger.Terminate())
    150     unittest2.main()
    151