Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / test / API / tools / lldb-server / TestGdbRemoteAuxvSupport.py
blob999d8ce9d467cfe35d80e59fc88a9e20b32ce502
1 import gdbremote_testcase
2 from lldbsuite.test.decorators import *
3 from lldbsuite.test.lldbtest import *
4 from lldbsuite.test import lldbutil
7 class TestGdbRemoteAuxvSupport(gdbremote_testcase.GdbRemoteTestCaseBase):
8 AUXV_SUPPORT_FEATURE_NAME = "qXfer:auxv:read"
10 def has_auxv_support(self):
11 procs = self.prep_debug_monitor_and_inferior()
13 self.add_qSupported_packets()
14 context = self.expect_gdbremote_sequence()
15 self.assertIsNotNone(context)
17 features = self.parse_qSupported_response(context)
18 return (
19 self.AUXV_SUPPORT_FEATURE_NAME in features
20 and features[self.AUXV_SUPPORT_FEATURE_NAME] == "+"
23 def get_raw_auxv_data(self):
24 # Start up llgs and inferior, and check for auxv support.
25 if not self.has_auxv_support():
26 self.skipTest("auxv data not supported")
28 # Grab pointer size for target. We'll assume that is equivalent to an unsigned long on the target.
29 # Auxv is specified in terms of pairs of unsigned longs.
30 self.reset_test_sequence()
31 self.add_process_info_collection_packets()
33 context = self.expect_gdbremote_sequence()
34 self.assertIsNotNone(context)
36 proc_info = self.parse_process_info_response(context)
37 self.assertIsNotNone(proc_info)
38 self.assertIn("ptrsize", proc_info)
39 word_size = int(proc_info["ptrsize"])
41 OFFSET = 0
42 LENGTH = 0x400
44 # Grab the auxv data.
45 self.reset_test_sequence()
46 self.test_sequence.add_log_lines(
48 "read packet: $qXfer:auxv:read::{:x},{:x}:#00".format(OFFSET, LENGTH),
50 "direction": "send",
51 "regex": re.compile(
52 r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL
54 "capture": {1: "response_type", 2: "content_raw"},
57 True,
60 context = self.expect_gdbremote_sequence()
61 self.assertIsNotNone(context)
63 # Ensure we end up with all auxv data in one packet.
64 # FIXME don't assume it all comes back in one packet.
65 self.assertEqual(context.get("response_type"), "l")
67 # Decode binary data.
68 content_raw = context.get("content_raw")
69 self.assertIsNotNone(content_raw)
70 return (word_size, self.decode_gdbremote_binary(content_raw))
72 @skipIfWindows # no auxv support.
73 @skipIfDarwin
74 def test_supports_auxv(self):
75 self.build()
76 self.set_inferior_startup_launch()
77 self.assertTrue(self.has_auxv_support())
79 @skipIfWindows
80 @expectedFailureNetBSD
81 def test_auxv_data_is_correct_size(self):
82 self.build()
83 self.set_inferior_startup_launch()
85 (word_size, auxv_data) = self.get_raw_auxv_data()
86 self.assertIsNotNone(auxv_data)
88 # Ensure auxv data is a multiple of 2*word_size (there should be two
89 # unsigned long fields per auxv entry).
90 self.assertEqual(len(auxv_data) % (2 * word_size), 0)
91 self.trace("auxv contains {} entries".format(len(auxv_data) / (2 * word_size)))
93 @skipIfWindows
94 @expectedFailureNetBSD
95 def test_auxv_keys_look_valid(self):
96 self.build()
97 self.set_inferior_startup_launch()
99 (word_size, auxv_data) = self.get_raw_auxv_data()
100 self.assertIsNotNone(auxv_data)
102 # Grab endian.
103 self.reset_test_sequence()
104 self.add_process_info_collection_packets()
105 context = self.expect_gdbremote_sequence()
106 self.assertIsNotNone(context)
108 process_info = self.parse_process_info_response(context)
109 self.assertIsNotNone(process_info)
110 endian = process_info.get("endian")
111 self.assertIsNotNone(endian)
113 auxv_dict = self.build_auxv_dict(endian, word_size, auxv_data)
114 self.assertIsNotNone(auxv_dict)
116 # Verify keys look reasonable. While AUX values are most commonly
117 # small (usually smaller than 50), they can sometimes be larger.
118 self.trace("auxv dict: {}".format(auxv_dict))
119 for auxv_key in auxv_dict:
120 self.assertTrue(auxv_key >= 1)
121 self.assertTrue(auxv_key <= 2500)
123 @skipIfWindows
124 @expectedFailureNetBSD
125 def test_auxv_chunked_reads_work(self):
126 self.build()
127 self.set_inferior_startup_launch()
129 # Verify that multiple smaller offset,length reads of auxv data
130 # return the same data as a single larger read.
132 # Grab the auxv data with a single large read here.
133 (word_size, auxv_data) = self.get_raw_auxv_data()
134 self.assertIsNotNone(auxv_data)
136 # Grab endian.
137 self.reset_test_sequence()
138 self.add_process_info_collection_packets()
139 context = self.expect_gdbremote_sequence()
140 self.assertIsNotNone(context)
142 process_info = self.parse_process_info_response(context)
143 self.assertIsNotNone(process_info)
144 endian = process_info.get("endian")
145 self.assertIsNotNone(endian)
147 auxv_dict = self.build_auxv_dict(endian, word_size, auxv_data)
148 self.assertIsNotNone(auxv_dict)
150 iterated_auxv_data = self.read_binary_data_in_chunks(
151 "qXfer:auxv:read::", 2 * word_size
153 self.assertIsNotNone(iterated_auxv_data)
155 auxv_dict_iterated = self.build_auxv_dict(endian, word_size, iterated_auxv_data)
156 self.assertIsNotNone(auxv_dict_iterated)
158 # Verify both types of data collection returned same content.
159 self.assertEqual(auxv_dict_iterated, auxv_dict)