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