1from lldbsuite.test.decorators import * 2from lldbsuite.test.lldbtest import * 3 4import gdbremote_testcase 5 6 7class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): 8 9 @skipIfWindows # no SIGSEGV support 10 @add_test_categories(["llgs"]) 11 def test_run(self): 12 self.build() 13 self.set_inferior_startup_launch() 14 thread_num = 3 15 procs = self.prep_debug_monitor_and_inferior( 16 inferior_args=["thread:segfault"] + thread_num * ["thread:new"]) 17 self.test_sequence.add_log_lines( 18 ["read packet: $QNonStop:1#00", 19 "send packet: $OK#00", 20 "read packet: $c#63", 21 "send packet: $OK#00", 22 ], True) 23 self.expect_gdbremote_sequence() 24 25 segv_signo = lldbutil.get_signal_number('SIGSEGV') 26 all_threads = set() 27 all_segv_threads = [] 28 29 # we should get segfaults from all the threads 30 for segv_no in range(thread_num): 31 # first wait for the notification event 32 self.reset_test_sequence() 33 self.test_sequence.add_log_lines( 34 [{"direction": "send", 35 "regex": r"^%Stop:(T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);)", 36 "capture": {1: "packet", 2: "signo", 3: "thread_id"}, 37 }, 38 ], True) 39 m = self.expect_gdbremote_sequence() 40 del m["O_content"] 41 threads = [m] 42 43 # then we may get events for the remaining threads 44 # (but note that not all threads may have been started yet) 45 while True: 46 self.reset_test_sequence() 47 self.test_sequence.add_log_lines( 48 ["read packet: $vStopped#00", 49 {"direction": "send", 50 "regex": r"^\$(OK|T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);)", 51 "capture": {1: "packet", 2: "signo", 3: "thread_id"}, 52 }, 53 ], True) 54 m = self.expect_gdbremote_sequence() 55 if m["packet"] == "OK": 56 break 57 del m["O_content"] 58 threads.append(m) 59 60 segv_threads = [] 61 other_threads = [] 62 for t in threads: 63 signo = int(t["signo"], 16) 64 if signo == segv_signo: 65 segv_threads.append(t["thread_id"]) 66 else: 67 self.assertEqual(signo, 0) 68 other_threads.append(t["thread_id"]) 69 70 # verify that exactly one thread segfaulted 71 self.assertEqual(len(segv_threads), 1) 72 # we should get only one segv from every thread 73 self.assertNotIn(segv_threads[0], all_segv_threads) 74 all_segv_threads.extend(segv_threads) 75 # segv_threads + other_threads should always be a superset 76 # of all_threads, i.e. we should get states for all threads 77 # already started 78 self.assertFalse( 79 all_threads.difference(other_threads + segv_threads)) 80 all_threads.update(other_threads + segv_threads) 81 82 # verify that `?` returns the same result 83 self.reset_test_sequence() 84 self.test_sequence.add_log_lines( 85 ["read packet: $?#00", 86 ], True) 87 threads_verify = [] 88 while True: 89 self.test_sequence.add_log_lines( 90 [{"direction": "send", 91 "regex": r"^\$(OK|T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);)", 92 "capture": {1: "packet", 2: "signo", 3: "thread_id"}, 93 }, 94 ], True) 95 m = self.expect_gdbremote_sequence() 96 if m["packet"] == "OK": 97 break 98 del m["O_content"] 99 threads_verify.append(m) 100 self.reset_test_sequence() 101 self.test_sequence.add_log_lines( 102 ["read packet: $vStopped#00", 103 ], True) 104 105 self.assertEqual(threads, threads_verify) 106 107 self.reset_test_sequence() 108 self.test_sequence.add_log_lines( 109 ["read packet: $vCont;C{:02x}:{};c#00" 110 .format(segv_signo, segv_threads[0]), 111 "send packet: $OK#00", 112 ], True) 113 self.expect_gdbremote_sequence() 114 115 # finally, verify that all threads have started 116 self.assertEqual(len(all_threads), thread_num + 1) 117 118 @add_test_categories(["llgs"]) 119 def test_vCtrlC(self): 120 self.build() 121 self.set_inferior_startup_launch() 122 procs = self.prep_debug_monitor_and_inferior( 123 inferior_args=["thread:new"]) 124 self.test_sequence.add_log_lines( 125 ["read packet: $QNonStop:1#00", 126 "send packet: $OK#00", 127 "read packet: $c#63", 128 "send packet: $OK#00", 129 "read packet: $vCtrlC#00", 130 "send packet: $OK#00", 131 {"direction": "send", 132 "regex": r"^%Stop:T", 133 }, 134 ], True) 135 self.expect_gdbremote_sequence() 136 137 @add_test_categories(["llgs"]) 138 def test_exit(self): 139 self.build() 140 self.set_inferior_startup_launch() 141 procs = self.prep_debug_monitor_and_inferior() 142 self.test_sequence.add_log_lines( 143 ["read packet: $QNonStop:1#00", 144 "send packet: $OK#00", 145 "read packet: $c#63", 146 "send packet: $OK#00", 147 "send packet: %Stop:W00#00", 148 "read packet: $vStopped#00", 149 "send packet: $OK#00", 150 ], True) 151 self.expect_gdbremote_sequence() 152 153 @skipIfWindows # no clue, the result makes zero sense 154 @add_test_categories(["llgs"]) 155 def test_exit_query(self): 156 self.build() 157 self.set_inferior_startup_launch() 158 procs = self.prep_debug_monitor_and_inferior() 159 self.test_sequence.add_log_lines( 160 ["read packet: $QNonStop:1#00", 161 "send packet: $OK#00", 162 "read packet: $c#63", 163 "send packet: $OK#00", 164 "send packet: %Stop:W00#00", 165 "read packet: $?#00", 166 "send packet: $W00#00", 167 "read packet: $vStopped#00", 168 "send packet: $OK#00", 169 ], True) 170 self.expect_gdbremote_sequence() 171 172 def multiple_resume_test(self, second_command): 173 self.build() 174 self.set_inferior_startup_launch() 175 procs = self.prep_debug_monitor_and_inferior( 176 inferior_args=["sleep:15"]) 177 self.test_sequence.add_log_lines( 178 ["read packet: $QNonStop:1#00", 179 "send packet: $OK#00", 180 "read packet: $c#63", 181 "send packet: $OK#00", 182 "read packet: ${}#00".format(second_command), 183 "send packet: $E37#00", 184 ], True) 185 self.expect_gdbremote_sequence() 186 187 @add_test_categories(["llgs"]) 188 def test_multiple_C(self): 189 self.multiple_resume_test("C05") 190 191 @add_test_categories(["llgs"]) 192 def test_multiple_c(self): 193 self.multiple_resume_test("c") 194 195 @add_test_categories(["llgs"]) 196 def test_multiple_s(self): 197 self.multiple_resume_test("s") 198 199 @skipIfWindows 200 @add_test_categories(["llgs"]) 201 def test_multiple_vCont(self): 202 self.build() 203 self.set_inferior_startup_launch() 204 procs = self.prep_debug_monitor_and_inferior( 205 inferior_args=["thread:new", "stop", "sleep:15"]) 206 self.test_sequence.add_log_lines( 207 ["read packet: $QNonStop:1#00", 208 "send packet: $OK#00", 209 "read packet: $c#63", 210 "send packet: $OK#00", 211 {"direction": "send", 212 "regex": r"^%Stop:T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+);", 213 "capture": {1: "tid1"}, 214 }, 215 "read packet: $vStopped#63", 216 {"direction": "send", 217 "regex": r"^[$]T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+);", 218 "capture": {1: "tid2"}, 219 }, 220 "read packet: $vStopped#63", 221 "send packet: $OK#00", 222 ], True) 223 ret = self.expect_gdbremote_sequence() 224 225 self.reset_test_sequence() 226 self.test_sequence.add_log_lines( 227 ["read packet: $vCont;c:{}#00".format(ret["tid1"]), 228 "send packet: $OK#00", 229 "read packet: $vCont;c:{}#00".format(ret["tid2"]), 230 "send packet: $E37#00", 231 ], True) 232 self.expect_gdbremote_sequence() 233 234 @add_test_categories(["llgs"]) 235 def test_vCont_then_stop(self): 236 self.build() 237 self.set_inferior_startup_launch() 238 procs = self.prep_debug_monitor_and_inferior( 239 inferior_args=["sleep:15"]) 240 self.test_sequence.add_log_lines( 241 ["read packet: $QNonStop:1#00", 242 "send packet: $OK#00", 243 "read packet: $c#63", 244 "send packet: $OK#00", 245 "read packet: $vCont;t#00", 246 "send packet: $OK#00", 247 ], True) 248 self.expect_gdbremote_sequence() 249 250 def vCont_then_partial_stop_test(self, run_both): 251 self.build() 252 self.set_inferior_startup_launch() 253 procs = self.prep_debug_monitor_and_inferior( 254 inferior_args=["thread:new", "stop", "sleep:15"]) 255 self.test_sequence.add_log_lines( 256 ["read packet: $QNonStop:1#00", 257 "send packet: $OK#00", 258 "read packet: $c#63", 259 "send packet: $OK#00", 260 {"direction": "send", 261 "regex": r"^%Stop:T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+);", 262 "capture": {1: "tid1"}, 263 }, 264 "read packet: $vStopped#63", 265 {"direction": "send", 266 "regex": r"^[$]T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+);", 267 "capture": {1: "tid2"}, 268 }, 269 "read packet: $vStopped#63", 270 "send packet: $OK#00", 271 ], True) 272 ret = self.expect_gdbremote_sequence() 273 274 self.reset_test_sequence() 275 if run_both: 276 self.test_sequence.add_log_lines( 277 ["read packet: $vCont;c#00", 278 ], True) 279 else: 280 self.test_sequence.add_log_lines( 281 ["read packet: $vCont;c:{}#00".format(ret["tid1"]), 282 ], True) 283 self.test_sequence.add_log_lines( 284 ["send packet: $OK#00", 285 "read packet: $vCont;t:{}#00".format(ret["tid2"]), 286 "send packet: $E03#00", 287 ], True) 288 self.expect_gdbremote_sequence() 289 290 @skipIfWindows 291 @add_test_categories(["llgs"]) 292 def test_vCont_then_partial_stop(self): 293 self.vCont_then_partial_stop_test(False) 294 295 @skipIfWindows 296 @add_test_categories(["llgs"]) 297 def test_vCont_then_partial_stop_run_both(self): 298 self.vCont_then_partial_stop_test(True) 299 300 @skipIfWindows 301 @add_test_categories(["llgs"]) 302 def test_stdio(self): 303 self.build() 304 self.set_inferior_startup_launch() 305 # Since we can't easily ensure that lldb will send output in two parts, 306 # just put a stop in the middle. Since we don't clear vStdio, 307 # the second message won't be delivered immediately. 308 self.prep_debug_monitor_and_inferior( 309 inferior_args=["message 1", "stop", "message 2"]) 310 self.test_sequence.add_log_lines( 311 ["read packet: $QNonStop:1#00", 312 "send packet: $OK#00", 313 "read packet: $c#63", 314 "send packet: $OK#00", 315 {"direction": "send", "regex": r"^%Stop:T.*"}, 316 "read packet: $vStopped#00", 317 "send packet: $OK#00", 318 "read packet: $c#63", 319 "send packet: $OK#00", 320 "send packet: %Stop:W00#00", 321 ], True) 322 ret = self.expect_gdbremote_sequence() 323 324 # We know there will be at least two messages, but there may be more. 325 # Loop until we have everything. The first message waiting for us in the 326 # packet queue. 327 count = 1 328 output = self._server.get_raw_output_packet() 329 while not (b"message 2\r\n" in output): 330 self._server.send_packet(b"vStdio") 331 output += self._server.get_raw_output_packet() 332 count += 1 333 self.assertGreaterEqual(count, 2) 334 335 self.reset_test_sequence() 336 self.test_sequence.add_log_lines( 337 ["read packet: $vStdio#00", 338 "send packet: $OK#00", 339 "read packet: $vStopped#00", 340 "send packet: $OK#00", 341 ], True) 342 self.expect_gdbremote_sequence() 343 344 @skipIfWindows 345 @add_test_categories(["llgs"]) 346 def test_stop_reason_while_running(self): 347 self.build() 348 self.set_inferior_startup_launch() 349 procs = self.prep_debug_monitor_and_inferior( 350 inferior_args=["thread:new", "thread:new", "stop", "sleep:15"]) 351 self.test_sequence.add_log_lines( 352 ["read packet: $QNonStop:1#00", 353 "send packet: $OK#00", 354 # stop is used to synchronize starting threads 355 "read packet: $c#63", 356 "send packet: $OK#00", 357 {"direction": "send", "regex": "%Stop:T.*"}, 358 "read packet: $c#63", 359 "send packet: $OK#00", 360 "read packet: $?#00", 361 "send packet: $OK#00", 362 ], True) 363 self.expect_gdbremote_sequence() 364 365 @skipIfWindows 366 @add_test_categories(["llgs"]) 367 def test_leave_nonstop(self): 368 self.build() 369 self.set_inferior_startup_launch() 370 procs = self.prep_debug_monitor_and_inferior( 371 inferior_args=["thread:new", "thread:new", "stop", "sleep:15"]) 372 self.test_sequence.add_log_lines( 373 ["read packet: $QNonStop:1#00", 374 "send packet: $OK#00", 375 # stop is used to synchronize starting threads 376 "read packet: $c#63", 377 "send packet: $OK#00", 378 {"direction": "send", "regex": "%Stop:T.*"}, 379 "read packet: $c#63", 380 "send packet: $OK#00", 381 # verify that the threads are running now 382 "read packet: $?#00", 383 "send packet: $OK#00", 384 "read packet: $QNonStop:0#00", 385 "send packet: $OK#00", 386 # we should issue some random request now to verify that the stub 387 # did not send stop reasons -- we may verify whether notification 388 # queue was cleared while at it 389 "read packet: $vStopped#00", 390 "send packet: $Eff#00", 391 "read packet: $?#00", 392 {"direction": "send", "regex": "[$]T.*"}, 393 ], True) 394 self.expect_gdbremote_sequence() 395