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