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