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