Home | History | Annotate | Download | only in sbdata
      1 """Test the SBData APIs."""
      2 
      3 import os
      4 import unittest2
      5 import lldb
      6 import pexpect
      7 from lldbtest import *
      8 from math import fabs
      9 import lldbutil
     10 
     11 class SBDataAPICase(TestBase):
     12 
     13     mydir = os.path.join("python_api", "sbdata")
     14 
     15     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     16     @python_api_test
     17     @dsym_test
     18     def test_with_dsym_and_run_command(self):
     19         """Test the SBData APIs."""
     20         self.buildDsym()
     21         self.data_api()
     22 
     23     @python_api_test
     24     @dwarf_test
     25     def test_with_dwarf_and_run_command(self):
     26         """Test the SBData APIs."""
     27         self.buildDwarf()
     28         self.data_api()
     29 
     30     def setUp(self):
     31         # Call super's setUp().
     32         TestBase.setUp(self)
     33         # Find the line number to break on inside main.cpp.
     34         self.line = line_number('main.cpp', '// set breakpoint here')
     35 
     36     def assert_data(self, func, arg, expected):
     37         """ Asserts func(SBError error, arg) == expected. """
     38         error = lldb.SBError()
     39         result = func(error, arg)
     40         if not error.Success():
     41             stream = lldb.SBStream()
     42             error.GetDescription(stream)
     43             self.assertTrue(error.Success(),
     44                             "%s(error, %s) did not succeed: %s" % (func.__name__,
     45                                                                    arg,
     46                                                                    stream.GetData()))
     47         self.assertTrue(expected == result, "%s(error, %s) == %s != %s" % (func.__name__, arg, result, expected))
     48           
     49     def data_api(self):
     50         """Test the SBData APIs."""
     51         self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
     52         
     53         lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
     54         
     55         self.runCmd("run", RUN_SUCCEEDED)
     56         
     57         # The stop reason of the thread should be breakpoint.
     58         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
     59                     substrs = ['stopped',
     60                                'stop reason = breakpoint'])
     61         
     62         target = self.dbg.GetSelectedTarget()
     63         
     64         process = target.GetProcess()
     65         
     66         thread = process.GetThreadAtIndex(0)
     67 
     68         frame = thread.GetSelectedFrame()
     69         if self.TraceOn():
     70             print frame
     71         foobar = frame.FindVariable('foobar')
     72         self.assertTrue(foobar.IsValid())
     73         if self.TraceOn():
     74             print foobar
     75 
     76         data = foobar.GetPointeeData(0, 2)
     77 
     78         if self.TraceOn():
     79             print data
     80 
     81         offset = 0
     82         error = lldb.SBError()
     83 
     84         self.assert_data(data.GetUnsignedInt32, offset, 1)
     85         offset += 4
     86         low = data.GetSignedInt16(error, offset)
     87         self.assertTrue(error.Success())
     88         offset += 2
     89         high = data.GetSignedInt16(error, offset)
     90         self.assertTrue(error.Success())
     91         offset += 2
     92         self.assertTrue ((low == 9 and high == 0) or (low == 0 and high == 9), 'foo[0].b == 9')
     93         self.assertTrue( fabs(data.GetFloat(error, offset) - 3.14) < 1, 'foo[0].c == 3.14')
     94         self.assertTrue(error.Success())
     95         offset += 4
     96         self.assert_data(data.GetUnsignedInt32, offset, 8)
     97         offset += 4
     98         self.assert_data(data.GetUnsignedInt32, offset, 5)
     99         offset += 4
    100 
    101         self.runCmd("n")
    102 
    103         offset = 16
    104 
    105         self.assert_data(data.GetUnsignedInt32, offset, 5)
    106 
    107         data = foobar.GetPointeeData(1, 1)
    108 
    109         offset = 0
    110 
    111         self.assert_data(data.GetSignedInt32, offset, 8)
    112         offset += 4
    113         self.assert_data(data.GetSignedInt32, offset, 7)
    114         offset += 8
    115         self.assertTrue(data.GetUnsignedInt32(error, offset) == 0, 'do not read beyond end')
    116         self.assertTrue(not error.Success())
    117         error.Clear() # clear the error for the next test
    118 
    119         star_foobar = foobar.Dereference()
    120         self.assertTrue(star_foobar.IsValid())
    121         
    122         data = star_foobar.GetData()
    123 
    124         if self.TraceOn():
    125             print data
    126         
    127         offset = 0
    128         self.assert_data(data.GetUnsignedInt32, offset, 1)
    129         offset += 4
    130         self.assert_data(data.GetUnsignedInt32, offset, 9)
    131 
    132         foobar_addr = star_foobar.GetLoadAddress()
    133         foobar_addr += 12
    134 
    135         # http://llvm.org/bugs/show_bug.cgi?id=11579
    136         # lldb::SBValue::CreateValueFromAddress does not verify SBType::GetPointerType succeeds
    137         # This should not crash LLDB.
    138         nothing = foobar.CreateValueFromAddress("nothing", foobar_addr, star_foobar.GetType().GetBasicType(lldb.eBasicTypeInvalid))
    139 
    140         new_foobar = foobar.CreateValueFromAddress("f00", foobar_addr, star_foobar.GetType())
    141         self.assertTrue(new_foobar.IsValid())
    142         if self.TraceOn():
    143             print new_foobar
    144         
    145         data = new_foobar.GetData()
    146 
    147         if self.TraceOn():
    148             print data
    149 
    150         self.assertTrue(data.uint32[0] == 8, 'then foo[1].a == 8')
    151         self.assertTrue(data.uint32[1] == 7, 'then foo[1].b == 7')
    152         self.assertTrue(fabs(data.float[2] - 3.14) < 1, 'foo[1].c == 3.14') # exploiting that sizeof(uint32) == sizeof(float)
    153 
    154         self.runCmd("n")
    155 
    156         offset = 0
    157         self.assert_data(data.GetUnsignedInt32, offset, 8)
    158         offset += 4
    159         self.assert_data(data.GetUnsignedInt32, offset, 7)
    160         offset += 4
    161         self.assertTrue(fabs(data.GetFloat(error, offset) - 3.14) < 1, 'foo[1].c == 3.14')
    162         self.assertTrue(error.Success())
    163 
    164         data = new_foobar.GetData()
    165 
    166         if self.TraceOn():
    167             print data
    168 
    169         offset = 0
    170         self.assert_data(data.GetUnsignedInt32, offset, 8)
    171         offset += 4
    172         self.assert_data(data.GetUnsignedInt32, offset, 7)
    173         offset += 4
    174         self.assertTrue(fabs(data.GetFloat(error, offset) - 6.28) < 1, 'foo[1].c == 6.28')
    175         self.assertTrue(error.Success())
    176 
    177         self.runCmd("n")
    178 
    179         barfoo = frame.FindVariable('barfoo')
    180 
    181         data = barfoo.GetData()
    182 
    183         if self.TraceOn():
    184             print barfoo
    185 
    186         if self.TraceOn():
    187             print data
    188 
    189         offset = 0
    190         self.assert_data(data.GetUnsignedInt32, offset, 1)
    191         offset += 4
    192         self.assert_data(data.GetUnsignedInt32, offset, 2)
    193         offset += 4
    194         self.assertTrue(fabs(data.GetFloat(error, offset) - 3) < 1, 'barfoo[0].c == 3')
    195         self.assertTrue(error.Success())
    196         offset += 4
    197         self.assert_data(data.GetUnsignedInt32, offset, 4)
    198         offset += 4
    199         self.assert_data(data.GetUnsignedInt32, offset, 5)
    200         offset += 4
    201         self.assertTrue(fabs(data.GetFloat(error, offset) - 6) < 1, 'barfoo[1].c == 6')
    202         self.assertTrue(error.Success())
    203 
    204         new_object = barfoo.CreateValueFromData("new_object",data,barfoo.GetType().GetBasicType(lldb.eBasicTypeInt))
    205 
    206         if self.TraceOn():
    207             print new_object
    208         
    209         self.assertTrue(new_object.GetLoadAddress() == 0xFFFFFFFFFFFFFFFF, 'GetLoadAddress() == invalid')
    210         self.assertTrue(new_object.AddressOf().IsValid() == False, 'AddressOf() == invalid')
    211         self.assertTrue(new_object.GetAddress().IsValid() == False, 'GetAddress() == invalid')
    212 
    213         self.assertTrue(new_object.GetValue() == "1", 'new_object == 1')
    214 
    215         data.SetData(error, 'A\0\0\0', data.GetByteOrder(), data.GetAddressByteSize())
    216         self.assertTrue(error.Success())
    217         
    218         data2 = lldb.SBData()
    219         data2.SetData(error, 'BCD', data.GetByteOrder(), data.GetAddressByteSize())
    220         self.assertTrue(error.Success())
    221 
    222         data.Append(data2)
    223         
    224         if self.TraceOn():
    225             print data
    226 
    227         # this breaks on EBCDIC
    228         offset = 0
    229         self.assert_data(data.GetUnsignedInt32, offset, 65)
    230         offset += 4
    231         self.assert_data(data.GetUnsignedInt8, offset, 66)
    232         offset += 1
    233         self.assert_data(data.GetUnsignedInt8, offset, 67)
    234         offset += 1
    235         self.assert_data(data.GetUnsignedInt8, offset, 68)
    236         offset += 1
    237 
    238         # check the new API calls introduced per LLVM llvm.org/prenhancement request
    239         # 11619 (Allow creating SBData values from arrays or primitives in Python)
    240 
    241         hello_str = "hello!"
    242         data2 = lldb.SBData.CreateDataFromCString(process.GetByteOrder(),process.GetAddressByteSize(),hello_str)
    243         self.assertTrue(len(data2.uint8) == len(hello_str))
    244         self.assertTrue(data2.uint8[0] == 104, 'h == 104')
    245         self.assertTrue(data2.uint8[1] == 101, 'e == 101')
    246         self.assertTrue(data2.uint8[2] == 108, 'l == 108')
    247         self.assert_data(data2.GetUnsignedInt8, 3, 108) # l
    248         self.assertTrue(data2.uint8[4] == 111, 'o == 111')
    249         self.assert_data(data2.GetUnsignedInt8, 5, 33) # !
    250         
    251         data2 = lldb.SBData.CreateDataFromUInt64Array(process.GetByteOrder(),process.GetAddressByteSize(),[1,2,3,4,5])
    252         self.assert_data(data2.GetUnsignedInt64, 0, 1)
    253         self.assert_data(data2.GetUnsignedInt64, 8, 2)
    254         self.assert_data(data2.GetUnsignedInt64, 16, 3)
    255         self.assert_data(data2.GetUnsignedInt64, 24, 4)
    256         self.assert_data(data2.GetUnsignedInt64, 32, 5)
    257         
    258         self.assertTrue(data2.uint64s == [1,2,3,4,5], 'read_data_helper failure: data2 == [1,2,3,4,5]')
    259 
    260         data2 = lldb.SBData.CreateDataFromSInt32Array(process.GetByteOrder(),process.GetAddressByteSize(),[2, -2])
    261         self.assertTrue(data2.sint32[0:2] == [2,-2], 'signed32 data2 = [2,-2]')
    262         
    263         data2.Append(lldb.SBData.CreateDataFromSInt64Array(process.GetByteOrder(),process.GetAddressByteSize(),[2, -2]))
    264         self.assert_data(data2.GetSignedInt32, 0, 2)
    265         self.assert_data(data2.GetSignedInt32, 4, -2)
    266         self.assertTrue(data2.sint64[1:3] == [2,-2], 'signed64 data2 = [2,-2]')
    267         
    268         data2 = lldb.SBData.CreateDataFromUInt32Array(process.GetByteOrder(),process.GetAddressByteSize(),[1,2,3,4,5])
    269         self.assert_data(data2.GetUnsignedInt32,0, 1)
    270         self.assert_data(data2.GetUnsignedInt32,4, 2)
    271         self.assert_data(data2.GetUnsignedInt32,8, 3)
    272         self.assert_data(data2.GetUnsignedInt32,12, 4)
    273         self.assert_data(data2.GetUnsignedInt32,16, 5)
    274         
    275         data2 = lldb.SBData.CreateDataFromDoubleArray(process.GetByteOrder(),process.GetAddressByteSize(),[3.14,6.28,2.71])
    276         self.assertTrue( fabs(data2.GetDouble(error,0) - 3.14) < 0.5, 'double data2[0] = 3.14')
    277         self.assertTrue(error.Success())
    278         self.assertTrue( fabs(data2.GetDouble(error,8) - 6.28) < 0.5, 'double data2[1] = 6.28')
    279         self.assertTrue(error.Success())
    280         self.assertTrue( fabs(data2.GetDouble(error,16) - 2.71) < 0.5, 'double data2[2] = 2.71')
    281         self.assertTrue(error.Success())
    282 
    283         data2 = lldb.SBData()
    284 
    285         data2.SetDataFromCString(hello_str)
    286         self.assertTrue(len(data2.uint8) == len(hello_str))
    287         self.assert_data(data2.GetUnsignedInt8, 0, 104)
    288         self.assert_data(data2.GetUnsignedInt8, 1, 101)
    289         self.assert_data(data2.GetUnsignedInt8, 2, 108)
    290         self.assert_data(data2.GetUnsignedInt8, 3, 108)
    291         self.assert_data(data2.GetUnsignedInt8, 4, 111)
    292         self.assert_data(data2.GetUnsignedInt8, 5, 33)
    293 
    294         data2.SetDataFromUInt64Array([1,2,3,4,5])
    295         self.assert_data(data2.GetUnsignedInt64, 0, 1)
    296         self.assert_data(data2.GetUnsignedInt64, 8,  2)
    297         self.assert_data(data2.GetUnsignedInt64, 16, 3)
    298         self.assert_data(data2.GetUnsignedInt64, 24, 4)
    299         self.assert_data(data2.GetUnsignedInt64, 32, 5)
    300 
    301         self.assertTrue(data2.uint64[0] == 1, 'read_data_helper failure: set data2[0] = 1')
    302         self.assertTrue(data2.uint64[1] == 2, 'read_data_helper failure: set data2[1] = 2')
    303         self.assertTrue(data2.uint64[2] == 3, 'read_data_helper failure: set data2[2] = 3')
    304         self.assertTrue(data2.uint64[3] == 4, 'read_data_helper failure: set data2[3] = 4')
    305         self.assertTrue(data2.uint64[4] == 5, 'read_data_helper failure: set data2[4] = 5')
    306 
    307         self.assertTrue(data2.uint64[0:2] == [1,2], 'read_data_helper failure: set data2[0:2] = [1,2]')
    308 
    309         data2.SetDataFromSInt32Array([2, -2])
    310         self.assert_data(data2.GetSignedInt32, 0, 2)
    311         self.assert_data(data2.GetSignedInt32, 4, -2)
    312         
    313         data2.SetDataFromSInt64Array([2, -2])
    314         self.assert_data(data2.GetSignedInt32, 0, 2)
    315         self.assert_data(data2.GetSignedInt32, 8, -2)
    316         
    317         data2.SetDataFromUInt32Array([1,2,3,4,5])
    318         self.assert_data(data2.GetUnsignedInt32, 0, 1)
    319         self.assert_data(data2.GetUnsignedInt32, 4, 2)
    320         self.assert_data(data2.GetUnsignedInt32, 8, 3)
    321         self.assert_data(data2.GetUnsignedInt32, 12, 4)
    322         self.assert_data(data2.GetUnsignedInt32, 16, 5)
    323         
    324         self.assertTrue(data2.uint32[0] == 1, 'read_data_helper failure: set 32-bit data2[0] = 1')
    325         self.assertTrue(data2.uint32[1] == 2, 'read_data_helper failure: set 32-bit data2[1] = 2')
    326         self.assertTrue(data2.uint32[2] == 3, 'read_data_helper failure: set 32-bit data2[2] = 3')
    327         self.assertTrue(data2.uint32[3] == 4, 'read_data_helper failure: set 32-bit data2[3] = 4')
    328         self.assertTrue(data2.uint32[4] == 5, 'read_data_helper failure: set 32-bit data2[4] = 5')
    329 
    330         data2.SetDataFromDoubleArray([3.14,6.28,2.71])
    331         self.assertTrue( fabs(data2.GetDouble(error,0) - 3.14) < 0.5, 'set double data2[0] = 3.14')
    332         self.assertTrue( fabs(data2.GetDouble(error,8) - 6.28) < 0.5, 'set double data2[1] = 6.28')
    333         self.assertTrue( fabs(data2.GetDouble(error,16) - 2.71) < 0.5, 'set double data2[2] = 2.71')
    334 
    335         self.assertTrue( fabs(data2.double[0] - 3.14) < 0.5, 'read_data_helper failure: set double data2[0] = 3.14')
    336         self.assertTrue( fabs(data2.double[1] - 6.28) < 0.5, 'read_data_helper failure: set double data2[1] = 6.28')
    337         self.assertTrue( fabs(data2.double[2] - 2.71) < 0.5, 'read_data_helper failure: set double data2[2] = 2.71')
    338 
    339 if __name__ == '__main__':
    340     import atexit
    341     lldb.SBDebugger.Initialize()
    342     atexit.register(lambda: lldb.SBDebugger.Terminate())
    343     unittest2.main()
    344