xref: /llvm-project/lldb/test/API/python_api/sbdata/TestSBData.py (revision 72e25978f93f0bf7577593aba9591c727526423c)
1"""Test the SBData APIs."""
2
3
4
5from math import fabs
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class SBDataAPICase(TestBase):
13
14    mydir = TestBase.compute_mydir(__file__)
15    NO_DEBUG_INFO_TESTCASE = True
16
17    def setUp(self):
18        # Call super's setUp().
19        TestBase.setUp(self)
20        # Find the line number to break on inside main.cpp.
21        self.line = line_number('main.cpp', '// set breakpoint here')
22
23    def test_byte_order_and_address_byte_size(self):
24        """Test the SBData::SetData() to ensure the byte order and address
25        byte size are obeyed"""
26        addr_data = b'\x11\x22\x33\x44\x55\x66\x77\x88'
27        error = lldb.SBError()
28        data = lldb.SBData()
29        data.SetData(error, addr_data, lldb.eByteOrderBig, 4)
30        addr = data.GetAddress(error, 0)
31        self.assertEqual(addr, 0x11223344);
32        data.SetData(error, addr_data, lldb.eByteOrderBig, 8)
33        addr = data.GetAddress(error, 0)
34        self.assertEqual(addr, 0x1122334455667788);
35        data.SetData(error, addr_data, lldb.eByteOrderLittle, 4)
36        addr = data.GetAddress(error, 0)
37        self.assertEqual(addr, 0x44332211);
38        data.SetData(error, addr_data, lldb.eByteOrderLittle, 8)
39        addr = data.GetAddress(error, 0)
40        self.assertEqual(addr, 0x8877665544332211);
41
42    def test_byte_order_and_address_byte_size_with_ownership(self):
43        """Test the SBData::SetDataWithOwnership() to ensure the byte order
44        and address byte size are obeyed even when source date is released"""
45        addr_data = b'\x11\x22\x33\x44\x55\x66\x77\x88'
46        error = lldb.SBError()
47        data = lldb.SBData()
48        data.SetDataWithOwnership(error, addr_data, lldb.eByteOrderBig, 8)
49        del addr_data
50        addr = data.GetAddress(error, 0)
51        self.assertEqual(addr, 0x1122334455667788);
52
53    def test_with_run_command(self):
54        """Test the SBData APIs."""
55        self.build()
56        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
57
58        lldbutil.run_break_set_by_file_and_line(
59            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
60
61        self.runCmd("run", RUN_SUCCEEDED)
62
63        # The stop reason of the thread should be breakpoint.
64        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
65                    substrs=['stopped',
66                             'stop reason = breakpoint'])
67
68        target = self.dbg.GetSelectedTarget()
69
70        process = target.GetProcess()
71
72        thread = lldbutil.get_stopped_thread(
73            process, lldb.eStopReasonBreakpoint)
74        self.assertIsNotNone(thread)
75
76        frame = thread.GetSelectedFrame()
77        foobar = frame.FindVariable('foobar')
78        self.assertTrue(foobar.IsValid())
79        data = foobar.GetPointeeData(0, 2)
80        offset = 0
81        error = lldb.SBError()
82
83        self.assert_data(data.GetUnsignedInt32, offset, 1)
84        offset += 4
85        low = data.GetSignedInt16(error, offset)
86        self.assertTrue(error.Success())
87        offset += 2
88        high = data.GetSignedInt16(error, offset)
89        self.assertTrue(error.Success())
90        offset += 2
91        self.assertTrue(
92            (low == 9 and high == 0) or (
93                low == 0 and high == 9),
94            'foo[0].b == 9')
95        self.assertTrue(
96            fabs(
97                data.GetFloat(
98                    error,
99                    offset) -
100                3.14) < 1,
101            'foo[0].c == 3.14')
102        self.assertTrue(error.Success())
103        offset += 4
104        self.assert_data(data.GetUnsignedInt32, offset, 8)
105        offset += 4
106        self.assert_data(data.GetUnsignedInt32, offset, 5)
107        offset += 4
108
109        self.runCmd("n")
110
111        offset = 16
112
113        self.assert_data(data.GetUnsignedInt32, offset, 5)
114
115        data = foobar.GetPointeeData(1, 1)
116
117        offset = 0
118
119        self.assert_data(data.GetSignedInt32, offset, 8)
120        offset += 4
121        self.assert_data(data.GetSignedInt32, offset, 7)
122        offset += 8
123        self.assertTrue(
124            data.GetUnsignedInt32(
125                error,
126                offset) == 0,
127            'do not read beyond end')
128        self.assertTrue(not error.Success())
129        error.Clear()  # clear the error for the next test
130
131        star_foobar = foobar.Dereference()
132        self.assertTrue(star_foobar.IsValid())
133
134        data = star_foobar.GetData()
135
136        offset = 0
137        self.assert_data(data.GetUnsignedInt32, offset, 1)
138        offset += 4
139        self.assert_data(data.GetUnsignedInt32, offset, 9)
140
141        foobar_addr = star_foobar.GetLoadAddress()
142        foobar_addr += 12
143
144        # http://llvm.org/bugs/show_bug.cgi?id=11579
145        # lldb::SBValue::CreateValueFromAddress does not verify SBType::GetPointerType succeeds
146        # This should not crash LLDB.
147        nothing = foobar.CreateValueFromAddress(
148            "nothing", foobar_addr, star_foobar.GetType().GetBasicType(
149                lldb.eBasicTypeInvalid))
150
151        new_foobar = foobar.CreateValueFromAddress(
152            "f00", foobar_addr, star_foobar.GetType())
153        self.assertTrue(new_foobar.IsValid())
154        data = new_foobar.GetData()
155
156        self.assertEqual(data.uint32[0], 8, 'then foo[1].a == 8')
157        self.assertEqual(data.uint32[1], 7, 'then foo[1].b == 7')
158        # exploiting that sizeof(uint32) == sizeof(float)
159        self.assertTrue(fabs(data.float[2] - 3.14) < 1, 'foo[1].c == 3.14')
160
161        self.runCmd("n")
162
163        offset = 0
164        self.assert_data(data.GetUnsignedInt32, offset, 8)
165        offset += 4
166        self.assert_data(data.GetUnsignedInt32, offset, 7)
167        offset += 4
168        self.assertTrue(
169            fabs(
170                data.GetFloat(
171                    error,
172                    offset) -
173                3.14) < 1,
174            'foo[1].c == 3.14')
175        self.assertTrue(error.Success())
176
177        data = new_foobar.GetData()
178
179        offset = 0
180        self.assert_data(data.GetUnsignedInt32, offset, 8)
181        offset += 4
182        self.assert_data(data.GetUnsignedInt32, offset, 7)
183        offset += 4
184        self.assertTrue(
185            fabs(
186                data.GetFloat(
187                    error,
188                    offset) -
189                6.28) < 1,
190            'foo[1].c == 6.28')
191        self.assertTrue(error.Success())
192
193        self.runCmd("n")
194
195        barfoo = frame.FindVariable('barfoo')
196
197        data = barfoo.GetData()
198        offset = 0
199        self.assert_data(data.GetUnsignedInt32, offset, 1)
200        offset += 4
201        self.assert_data(data.GetUnsignedInt32, offset, 2)
202        offset += 4
203        self.assertTrue(
204            fabs(
205                data.GetFloat(
206                    error,
207                    offset) -
208                3) < 1,
209            'barfoo[0].c == 3')
210        self.assertTrue(error.Success())
211        offset += 4
212        self.assert_data(data.GetUnsignedInt32, offset, 4)
213        offset += 4
214        self.assert_data(data.GetUnsignedInt32, offset, 5)
215        offset += 4
216        self.assertTrue(
217            fabs(
218                data.GetFloat(
219                    error,
220                    offset) -
221                6) < 1,
222            'barfoo[1].c == 6')
223        self.assertTrue(error.Success())
224
225        new_object = barfoo.CreateValueFromData(
226            "new_object", data, barfoo.GetType().GetBasicType(
227                lldb.eBasicTypeInt))
228        self.assertEqual(new_object.GetValue(), "1", 'new_object == 1')
229
230        if data.GetByteOrder() == lldb.eByteOrderBig:
231            data.SetData(
232                error,
233                '\0\0\0A',
234                data.GetByteOrder(),
235                data.GetAddressByteSize())
236        else:
237            data.SetData(
238                error,
239                'A\0\0\0',
240                data.GetByteOrder(),
241                data.GetAddressByteSize())
242        self.assertTrue(error.Success())
243
244        data2 = lldb.SBData()
245        data2.SetData(
246            error,
247            'BCD',
248            data.GetByteOrder(),
249            data.GetAddressByteSize())
250        self.assertTrue(error.Success())
251
252        data.Append(data2)
253
254        # this breaks on EBCDIC
255        offset = 0
256        self.assert_data(data.GetUnsignedInt32, offset, 65)
257        offset += 4
258        self.assert_data(data.GetUnsignedInt8, offset, 66)
259        offset += 1
260        self.assert_data(data.GetUnsignedInt8, offset, 67)
261        offset += 1
262        self.assert_data(data.GetUnsignedInt8, offset, 68)
263        offset += 1
264
265        # check the new API calls introduced per LLVM llvm.org/prenhancement request
266        # 11619 (Allow creating SBData values from arrays or primitives in
267        # Python)
268
269        hello_str = "hello!"
270        data2 = lldb.SBData.CreateDataFromCString(
271            process.GetByteOrder(), process.GetAddressByteSize(), hello_str)
272        self.assertEqual(len(data2.uint8), len(hello_str))
273        self.assertEqual(data2.uint8[0], 104, 'h == 104')
274        self.assertEqual(data2.uint8[1], 101, 'e == 101')
275        self.assertEqual(data2.uint8[2], 108, 'l == 108')
276        self.assert_data(data2.GetUnsignedInt8, 3, 108)  # l
277        self.assertEqual(data2.uint8[4], 111, 'o == 111')
278        self.assert_data(data2.GetUnsignedInt8, 5, 33)  # !
279
280        uint_lists = [[1, 2, 3, 4, 5], [int(i) for i in [1, 2, 3, 4, 5]]]
281        int_lists = [[2, -2], [int(i) for i in [2, -2]]]
282
283        for l in uint_lists:
284            data2 = lldb.SBData.CreateDataFromUInt64Array(
285                process.GetByteOrder(), process.GetAddressByteSize(), l)
286            self.assert_data(data2.GetUnsignedInt64, 0, 1)
287            self.assert_data(data2.GetUnsignedInt64, 8, 2)
288            self.assert_data(data2.GetUnsignedInt64, 16, 3)
289            self.assert_data(data2.GetUnsignedInt64, 24, 4)
290            self.assert_data(data2.GetUnsignedInt64, 32, 5)
291
292            self.assertTrue(
293                data2.uint64s == [
294                    1,
295                    2,
296                    3,
297                    4,
298                    5],
299                'read_data_helper failure: data2 == [1,2,3,4,5]')
300
301        for l in int_lists:
302            data2 = lldb.SBData.CreateDataFromSInt32Array(
303                process.GetByteOrder(), process.GetAddressByteSize(), l)
304            self.assertTrue(
305                data2.sint32[
306                    0:2] == [
307                    2, -2], 'signed32 data2 = [2,-2]')
308
309        data2.Append(
310            lldb.SBData.CreateDataFromSInt64Array(
311                process.GetByteOrder(),
312                process.GetAddressByteSize(),
313                int_lists[0]))
314        self.assert_data(data2.GetSignedInt32, 0, 2)
315        self.assert_data(data2.GetSignedInt32, 4, -2)
316        self.assertTrue(
317            data2.sint64[
318                1:3] == [
319                2, -2], 'signed64 data2 = [2,-2]')
320
321        for l in int_lists:
322            data2 = lldb.SBData.CreateDataFromSInt64Array(
323                process.GetByteOrder(), process.GetAddressByteSize(), l)
324            self.assert_data(data2.GetSignedInt64, 0, 2)
325            self.assert_data(data2.GetSignedInt64, 8, -2)
326            self.assertTrue(
327                data2.sint64[
328                    0:2] == [
329                    2, -2], 'signed64 data2 = [2,-2]')
330
331        for l in uint_lists:
332            data2 = lldb.SBData.CreateDataFromUInt32Array(
333                process.GetByteOrder(), process.GetAddressByteSize(), l)
334            self.assert_data(data2.GetUnsignedInt32, 0, 1)
335            self.assert_data(data2.GetUnsignedInt32, 4, 2)
336            self.assert_data(data2.GetUnsignedInt32, 8, 3)
337            self.assert_data(data2.GetUnsignedInt32, 12, 4)
338            self.assert_data(data2.GetUnsignedInt32, 16, 5)
339
340        bool_list = [True, True, False, False, True, False]
341
342        data2 = lldb.SBData.CreateDataFromSInt32Array(
343            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
344        self.assertTrue(
345            data2.sint32[
346                0:6] == [
347                1,
348                1,
349                0,
350                0,
351                1,
352                0],
353            'signed32 data2 = [1, 1, 0, 0, 1, 0]')
354
355        data2 = lldb.SBData.CreateDataFromUInt32Array(
356            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
357        self.assertTrue(
358            data2.uint32[
359                0:6] == [
360                1,
361                1,
362                0,
363                0,
364                1,
365                0],
366            'unsigned32 data2 = [1, 1, 0, 0, 1, 0]')
367
368        data2 = lldb.SBData.CreateDataFromSInt64Array(
369            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
370        self.assertTrue(
371            data2.sint64[
372                0:6] == [
373                1,
374                1,
375                0,
376                0,
377                1,
378                0],
379            'signed64 data2 = [1, 1, 0, 0, 1, 0]')
380
381        data2 = lldb.SBData.CreateDataFromUInt64Array(
382            process.GetByteOrder(), process.GetAddressByteSize(), bool_list)
383        self.assertTrue(
384            data2.uint64[
385                0:6] == [
386                1,
387                1,
388                0,
389                0,
390                1,
391                0],
392            'signed64 data2 = [1, 1, 0, 0, 1, 0]')
393
394        data2 = lldb.SBData.CreateDataFromDoubleArray(
395            process.GetByteOrder(), process.GetAddressByteSize(), [
396                3.14, 6.28, 2.71])
397        self.assertTrue(
398            fabs(
399                data2.GetDouble(
400                    error,
401                    0) -
402                3.14) < 0.5,
403            'double data2[0] = 3.14')
404        self.assertTrue(error.Success())
405        self.assertTrue(
406            fabs(
407                data2.GetDouble(
408                    error,
409                    8) -
410                6.28) < 0.5,
411            'double data2[1] = 6.28')
412        self.assertTrue(error.Success())
413        self.assertTrue(
414            fabs(
415                data2.GetDouble(
416                    error,
417                    16) -
418                2.71) < 0.5,
419            'double data2[2] = 2.71')
420        self.assertTrue(error.Success())
421
422        data2 = lldb.SBData()
423
424        data2.SetDataFromCString(hello_str)
425        self.assertEqual(len(data2.uint8), len(hello_str))
426        self.assert_data(data2.GetUnsignedInt8, 0, 104)
427        self.assert_data(data2.GetUnsignedInt8, 1, 101)
428        self.assert_data(data2.GetUnsignedInt8, 2, 108)
429        self.assert_data(data2.GetUnsignedInt8, 3, 108)
430        self.assert_data(data2.GetUnsignedInt8, 4, 111)
431        self.assert_data(data2.GetUnsignedInt8, 5, 33)
432
433        data2.SetDataFromUInt64Array([1, 2, 3, 4, 5])
434        self.assert_data(data2.GetUnsignedInt64, 0, 1)
435        self.assert_data(data2.GetUnsignedInt64, 8, 2)
436        self.assert_data(data2.GetUnsignedInt64, 16, 3)
437        self.assert_data(data2.GetUnsignedInt64, 24, 4)
438        self.assert_data(data2.GetUnsignedInt64, 32, 5)
439
440        self.assertEqual(
441            data2.uint64[0], 1,
442            'read_data_helper failure: set data2[0] = 1')
443        self.assertEqual(
444            data2.uint64[1], 2,
445            'read_data_helper failure: set data2[1] = 2')
446        self.assertEqual(
447            data2.uint64[2], 3,
448            'read_data_helper failure: set data2[2] = 3')
449        self.assertEqual(
450            data2.uint64[3], 4,
451            'read_data_helper failure: set data2[3] = 4')
452        self.assertEqual(
453            data2.uint64[4], 5,
454            'read_data_helper failure: set data2[4] = 5')
455
456        self.assertTrue(
457            data2.uint64[
458                0:2] == [
459                1,
460                2],
461            'read_data_helper failure: set data2[0:2] = [1,2]')
462
463        data2.SetDataFromSInt32Array([2, -2])
464        self.assert_data(data2.GetSignedInt32, 0, 2)
465        self.assert_data(data2.GetSignedInt32, 4, -2)
466
467        data2.SetDataFromSInt64Array([2, -2])
468        self.assert_data(data2.GetSignedInt64, 0, 2)
469        self.assert_data(data2.GetSignedInt64, 8, -2)
470
471        data2.SetDataFromUInt32Array([1, 2, 3, 4, 5])
472        self.assert_data(data2.GetUnsignedInt32, 0, 1)
473        self.assert_data(data2.GetUnsignedInt32, 4, 2)
474        self.assert_data(data2.GetUnsignedInt32, 8, 3)
475        self.assert_data(data2.GetUnsignedInt32, 12, 4)
476        self.assert_data(data2.GetUnsignedInt32, 16, 5)
477
478        self.assertEqual(
479            data2.uint32[0], 1,
480            'read_data_helper failure: set 32-bit data2[0] = 1')
481        self.assertEqual(
482            data2.uint32[1], 2,
483            'read_data_helper failure: set 32-bit data2[1] = 2')
484        self.assertEqual(
485            data2.uint32[2], 3,
486            'read_data_helper failure: set 32-bit data2[2] = 3')
487        self.assertEqual(
488            data2.uint32[3], 4,
489            'read_data_helper failure: set 32-bit data2[3] = 4')
490        self.assertEqual(
491            data2.uint32[4], 5,
492            'read_data_helper failure: set 32-bit data2[4] = 5')
493
494        data2.SetDataFromDoubleArray([3.14, 6.28, 2.71])
495        self.assertTrue(fabs(data2.GetDouble(error, 0) - 3.14)
496                        < 0.5, 'set double data2[0] = 3.14')
497        self.assertTrue(fabs(data2.GetDouble(error, 8) - 6.28)
498                        < 0.5, 'set double data2[1] = 6.28')
499        self.assertTrue(fabs(data2.GetDouble(error, 16) - 2.71)
500                        < 0.5, 'set double data2[2] = 2.71')
501
502        self.assertTrue(
503            fabs(
504                data2.double[0] -
505                3.14) < 0.5,
506            'read_data_helper failure: set double data2[0] = 3.14')
507        self.assertTrue(
508            fabs(
509                data2.double[1] -
510                6.28) < 0.5,
511            'read_data_helper failure: set double data2[1] = 6.28')
512        self.assertTrue(
513            fabs(
514                data2.double[2] -
515                2.71) < 0.5,
516            'read_data_helper failure: set double data2[2] = 2.71')
517
518    def assert_data(self, func, arg, expected):
519        """ Asserts func(SBError error, arg) == expected. """
520        error = lldb.SBError()
521        result = func(error, arg)
522        if not error.Success():
523            stream = lldb.SBStream()
524            error.GetDescription(stream)
525            self.assertTrue(
526                error.Success(), "%s(error, %s) did not succeed: %s" %
527                (func.__name__, arg, stream.GetData()))
528        self.assertTrue(
529            expected == result, "%s(error, %s) == %s != %s" %
530            (func.__name__, arg, result, expected))
531