Home | History | Annotate | Download | only in blocks
      1 """Test printing ivars and ObjC objects captured in blocks that are made in methods of an ObjC class."""
      2 
      3 import os, time
      4 import unittest2
      5 import lldb
      6 from lldbtest import *
      7 import lldbutil
      8 
      9 class TestObjCIvarsInBlocks(TestBase):
     10 
     11     mydir = os.path.join("lang", "objc", "blocks")
     12 
     13     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     14     # This test requires the 2.0 runtime, so it will fail on i386.
     15     @expectedFailurei386
     16     @python_api_test
     17     @dsym_test
     18     def test_with_dsym_and_python_api(self):
     19         """Test printing the ivars of the self when captured in blocks"""
     20         self.buildDsym()
     21         self.ivars_in_blocks()
     22 
     23     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     24     @python_api_test
     25     # This test requires the 2.0 runtime, so it will fail on i386.
     26     @expectedFailurei386
     27     @dwarf_test
     28     def test_with_dwarf_and_python_api(self):
     29         """Test printing the ivars of the self when captured in blocks"""
     30         self.buildDwarf()
     31         self.ivars_in_blocks()
     32 
     33     def setUp(self):
     34         # Call super's setUp().
     35         TestBase.setUp(self)
     36         # Find the line numbers to break inside main().
     37         self.main_source = "main.m"
     38         self.class_source = "ivars-in-blocks.m"
     39         self.class_source_file_spec = lldb.SBFileSpec(self.class_source)
     40 
     41     def ivars_in_blocks (self):
     42         """Test printing the ivars of the self when captured in blocks"""
     43         exe = os.path.join(os.getcwd(), "a.out")
     44 
     45         target = self.dbg.CreateTarget(exe)
     46         self.assertTrue(target, VALID_TARGET)
     47 
     48         breakpoint = target.BreakpointCreateBySourceRegex ('// Break here inside the block.', self.class_source_file_spec)
     49         self.assertTrue(breakpoint, VALID_BREAKPOINT)
     50 
     51         breakpoint_two = target.BreakpointCreateBySourceRegex ('// Break here inside the class method block.', self.class_source_file_spec)
     52         self.assertTrue(breakpoint, VALID_BREAKPOINT)
     53 
     54         process = target.LaunchSimple (None, None, os.getcwd())
     55         self.assertTrue (process, "Created a process.")
     56         self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped it too.")
     57 
     58         thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
     59         self.assertTrue (len(thread_list) == 1)
     60         thread = thread_list[0]
     61         
     62         frame = thread.GetFrameAtIndex(0)
     63         self.assertTrue (frame, "frame 0 is valid")
     64         
     65         # First use the FindVariable API to see if we can find the ivar by undecorated name:
     66         direct_blocky = frame.GetValueForVariablePath ("blocky_ivar")
     67         self.assertTrue(direct_blocky, "Found direct access to blocky_ivar.")
     68         
     69         # Now get it as a member of "self" and make sure the two values are equal:
     70         self_var = frame.GetValueForVariablePath ("self")
     71         self.assertTrue (self_var, "Found self in block.")
     72         indirect_blocky = self_var.GetChildMemberWithName ("blocky_ivar")
     73         self.assertTrue (indirect_blocky, "Found blocky_ivar through self")
     74         
     75         error = lldb.SBError()
     76         direct_value = direct_blocky.GetValueAsSigned(error)
     77         self.assertTrue (error.Success(), "Got direct value for blocky_ivar")
     78 
     79         indirect_value = indirect_blocky.GetValueAsSigned (error)
     80         self.assertTrue (error.Success(), "Got indirect value for blocky_ivar")
     81         
     82         self.assertTrue (direct_value == indirect_value, "Direct and indirect values are equal.")
     83 
     84         # Now make sure that we can get at the captured ivar through the expression parser.
     85         # Doing a little trivial math will force this into the real expression parser:
     86         direct_expr = frame.EvaluateExpression ("blocky_ivar + 10")
     87         self.assertTrue (direct_expr, "Got blocky_ivar through the expression parser")
     88         
     89         # Again, get the value through self directly and make sure they are the same:
     90         indirect_expr = frame.EvaluateExpression ("self->blocky_ivar + 10")
     91         self.assertTrue (indirect_expr, "Got blocky ivar through expression parser using self.")
     92         
     93         direct_value = direct_expr.GetValueAsSigned (error)
     94         self.assertTrue (error.Success(), "Got value from direct use of expression parser")
     95 
     96         indirect_value = indirect_expr.GetValueAsSigned (error)
     97         self.assertTrue (error.Success(), "Got value from indirect access using the expression parser")
     98 
     99         self.assertTrue (direct_value == indirect_value, "Direct ivar access and indirect through expression parser produce same value.")
    100 
    101         process.Continue()
    102         self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped at the second breakpoint.")
    103 
    104         thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint_two)
    105         self.assertTrue (len(thread_list) == 1)
    106         thread = thread_list[0]
    107         
    108         frame = thread.GetFrameAtIndex(0)
    109         self.assertTrue (frame, "frame 0 is valid")
    110         
    111         expr = frame.EvaluateExpression("(ret)")
    112         self.assertTrue (expr, "Successfully got a local variable in a block in a class method.")
    113 
    114         ret_value_signed = expr.GetValueAsSigned (error)
    115         print 'ret_value_signed = %i' % (ret_value_signed)
    116         self.assertTrue (ret_value_signed == 5, "The local variable in the block was what we expected.")
    117         
    118 if __name__ == '__main__':
    119     import atexit
    120     lldb.SBDebugger.Initialize()
    121     atexit.register(lambda: lldb.SBDebugger.Terminate())
    122     unittest2.main()
    123