2 Test case for testing the gdbremote protocol.
4 Tests run against debugserver and lldb-server (llgs).
5 lldb-server tests run where the lldb-server exe is
8 This class will be broken into smaller test case classes by
9 gdb remote packet functional areas. For now it contains
10 the initial set of tests implemented.
13 from __future__ import print_function
17 import gdbremote_testcase
18 import lldbgdbserverutils
21 from lldbsuite.test.decorators import *
22 from lldbsuite.test.lldbtest import *
23 from lldbsuite.test.lldbdwarf import *
24 from lldbsuite.test import lldbutil
27 class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcodeParser):
29 mydir = TestBase.compute_mydir(__file__)
32 def test_exe_starts_debugserver(self):
33 self.init_debugserver_test()
34 server = self.connect_to_debug_monitor()
37 def test_exe_starts_llgs(self):
39 server = self.connect_to_debug_monitor()
41 def start_no_ack_mode(self):
42 server = self.connect_to_debug_monitor()
43 self.assertIsNotNone(server)
45 self.add_no_ack_remote_stream()
46 self.expect_gdbremote_sequence()
49 def test_start_no_ack_mode_debugserver(self):
50 self.init_debugserver_test()
51 self.start_no_ack_mode()
54 def test_start_no_ack_mode_llgs(self):
56 self.start_no_ack_mode()
58 def thread_suffix_supported(self):
59 server = self.connect_to_debug_monitor()
60 self.assertIsNotNone(server)
62 self.add_no_ack_remote_stream()
63 self.test_sequence.add_log_lines(
64 ["lldb-server < 26> read packet: $QThreadSuffixSupported#e4",
65 "lldb-server < 6> send packet: $OK#9a"],
68 self.expect_gdbremote_sequence()
71 def test_thread_suffix_supported_debugserver(self):
72 self.init_debugserver_test()
73 self.thread_suffix_supported()
76 def test_thread_suffix_supported_llgs(self):
78 self.thread_suffix_supported()
80 def list_threads_in_stop_reply_supported(self):
81 server = self.connect_to_debug_monitor()
82 self.assertIsNotNone(server)
84 self.add_no_ack_remote_stream()
85 self.test_sequence.add_log_lines(
86 ["lldb-server < 27> read packet: $QListThreadsInStopReply#21",
87 "lldb-server < 6> send packet: $OK#9a"],
89 self.expect_gdbremote_sequence()
92 def test_list_threads_in_stop_reply_supported_debugserver(self):
93 self.init_debugserver_test()
94 self.list_threads_in_stop_reply_supported()
97 def test_list_threads_in_stop_reply_supported_llgs(self):
99 self.list_threads_in_stop_reply_supported()
101 def c_packet_works(self):
102 launch_args = self.install_and_create_launch_args()
104 server = self.connect_to_debug_monitor()
105 self.assertIsNotNone(server)
107 self.add_no_ack_remote_stream()
108 self.add_verified_launch_packets(launch_args)
109 self.test_sequence.add_log_lines(
110 ["read packet: $c#63",
111 "send packet: $W00#00"],
114 self.expect_gdbremote_sequence()
117 def test_c_packet_works_debugserver(self):
118 self.init_debugserver_test()
120 self.c_packet_works()
123 def test_c_packet_works_llgs(self):
124 self.init_llgs_test()
126 self.c_packet_works()
128 def inferior_print_exit(self):
129 launch_args = self.install_and_create_launch_args()
131 server = self.connect_to_debug_monitor()
132 self.assertIsNotNone(server)
135 launch_args += ["hello, world"]
137 self.add_no_ack_remote_stream()
138 self.add_verified_launch_packets(launch_args)
139 self.test_sequence.add_log_lines(
140 ["read packet: $vCont;c#a8",
141 {"type": "output_match", "regex": self.maybe_strict_output_regex(r"hello, world\r\n")},
142 "send packet: $W00#00"],
145 context = self.expect_gdbremote_sequence()
146 self.assertIsNotNone(context)
149 def test_inferior_print_exit_debugserver(self):
150 self.init_debugserver_test()
152 self.inferior_print_exit()
155 @expectedFlakeyLinux("llvm.org/pr25652")
156 def test_inferior_print_exit_llgs(self):
157 self.init_llgs_test()
159 self.inferior_print_exit()
161 def first_launch_stop_reply_thread_matches_first_qC(self):
162 launch_args = self.install_and_create_launch_args()
164 server = self.connect_to_debug_monitor()
165 self.assertIsNotNone(server)
168 launch_args += ["hello, world"]
170 self.add_no_ack_remote_stream()
171 self.add_verified_launch_packets(launch_args)
172 self.test_sequence.add_log_lines(["read packet: $qC#00",
173 {"direction": "send",
174 "regex": r"^\$QC([0-9a-fA-F]+)#",
175 "capture": {1: "thread_id"}},
176 "read packet: $?#00",
177 {"direction": "send",
178 "regex": r"^\$T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+)",
179 "expect_captures": {1: "thread_id"}}],
181 self.expect_gdbremote_sequence()
184 def test_first_launch_stop_reply_thread_matches_first_qC_debugserver(self):
185 self.init_debugserver_test()
187 self.first_launch_stop_reply_thread_matches_first_qC()
190 def test_first_launch_stop_reply_thread_matches_first_qC_llgs(self):
191 self.init_llgs_test()
193 self.first_launch_stop_reply_thread_matches_first_qC()
195 def attach_commandline_continue_app_exits(self):
196 procs = self.prep_debug_monitor_and_inferior()
197 self.test_sequence.add_log_lines(
198 ["read packet: $vCont;c#a8",
199 "send packet: $W00#00"],
201 self.expect_gdbremote_sequence()
203 # Wait a moment for completed and now-detached inferior process to
207 if not lldb.remote_platform:
208 # Process should be dead now. Reap results.
209 poll_result = procs["inferior"].poll()
210 self.assertIsNotNone(poll_result)
212 # Where possible, verify at the system level that the process is not
215 lldbgdbserverutils.process_is_running(
216 procs["inferior"].pid, False))
219 def test_attach_commandline_continue_app_exits_debugserver(self):
220 self.init_debugserver_test()
222 self.set_inferior_startup_attach()
223 self.attach_commandline_continue_app_exits()
226 def test_attach_commandline_continue_app_exits_llgs(self):
227 self.init_llgs_test()
229 self.set_inferior_startup_attach()
230 self.attach_commandline_continue_app_exits()
232 def qRegisterInfo_returns_one_valid_result(self):
233 launch_args = self.install_and_create_launch_args()
235 server = self.connect_to_debug_monitor()
236 self.assertIsNotNone(server)
238 # Build the expected protocol stream
239 self.add_no_ack_remote_stream()
240 self.add_verified_launch_packets(launch_args)
241 self.test_sequence.add_log_lines(
242 ["read packet: $qRegisterInfo0#00",
243 {"direction": "send", "regex": r"^\$(.+);#[0-9A-Fa-f]{2}", "capture": {1: "reginfo_0"}}],
247 context = self.expect_gdbremote_sequence()
248 self.assertIsNotNone(context)
250 reg_info_packet = context.get("reginfo_0")
251 self.assertIsNotNone(reg_info_packet)
252 self.assert_valid_reg_info(
253 lldbgdbserverutils.parse_reg_info_response(reg_info_packet))
256 @expectedFailureDarwin("llvm.org/pr25486")
257 def test_qRegisterInfo_returns_one_valid_result_debugserver(self):
258 self.init_debugserver_test()
260 self.qRegisterInfo_returns_one_valid_result()
263 def test_qRegisterInfo_returns_one_valid_result_llgs(self):
264 self.init_llgs_test()
266 self.qRegisterInfo_returns_one_valid_result()
268 def qRegisterInfo_returns_all_valid_results(self):
269 launch_args = self.install_and_create_launch_args()
271 server = self.connect_to_debug_monitor()
272 self.assertIsNotNone(server)
274 # Build the expected protocol stream.
275 self.add_no_ack_remote_stream()
276 self.add_verified_launch_packets(launch_args)
277 self.add_register_info_collection_packets()
280 context = self.expect_gdbremote_sequence()
281 self.assertIsNotNone(context)
283 # Validate that each register info returned validates.
284 for reg_info in self.parse_register_info_packets(context):
285 self.assert_valid_reg_info(reg_info)
288 @expectedFailureDarwin("llvm.org/pr25486")
289 def test_qRegisterInfo_returns_all_valid_results_debugserver(self):
290 self.init_debugserver_test()
292 self.qRegisterInfo_returns_all_valid_results()
295 def test_qRegisterInfo_returns_all_valid_results_llgs(self):
296 self.init_llgs_test()
298 self.qRegisterInfo_returns_all_valid_results()
300 def qRegisterInfo_contains_required_generics(self):
301 launch_args = self.install_and_create_launch_args()
303 server = self.connect_to_debug_monitor()
304 self.assertIsNotNone(server)
306 # Build the expected protocol stream
307 self.add_no_ack_remote_stream()
308 self.add_verified_launch_packets(launch_args)
309 self.add_register_info_collection_packets()
311 # Run the packet stream.
312 context = self.expect_gdbremote_sequence()
313 self.assertIsNotNone(context)
315 # Gather register info entries.
316 reg_infos = self.parse_register_info_packets(context)
318 # Collect all generic registers found.
320 reg_info['generic']: 1 for reg_info in reg_infos if 'generic' in reg_info}
322 # Ensure we have a program counter register.
323 self.assertTrue('pc' in generic_regs)
325 # Ensure we have a frame pointer register.
326 self.assertTrue('fp' in generic_regs)
328 # Ensure we have a stack pointer register.
329 self.assertTrue('sp' in generic_regs)
331 # Ensure we have a flags register.
332 self.assertTrue('flags' in generic_regs)
335 def test_qRegisterInfo_contains_required_generics_debugserver(self):
336 self.init_debugserver_test()
338 self.qRegisterInfo_contains_required_generics()
341 def test_qRegisterInfo_contains_required_generics_llgs(self):
342 self.init_llgs_test()
344 self.qRegisterInfo_contains_required_generics()
346 def qRegisterInfo_contains_at_least_one_register_set(self):
347 launch_args = self.install_and_create_launch_args()
349 server = self.connect_to_debug_monitor()
350 self.assertIsNotNone(server)
352 # Build the expected protocol stream
353 self.add_no_ack_remote_stream()
354 self.add_verified_launch_packets(launch_args)
355 self.add_register_info_collection_packets()
357 # Run the packet stream.
358 context = self.expect_gdbremote_sequence()
359 self.assertIsNotNone(context)
361 # Gather register info entries.
362 reg_infos = self.parse_register_info_packets(context)
364 # Collect all register sets found.
366 reg_info['set']: 1 for reg_info in reg_infos if 'set' in reg_info}
367 self.assertTrue(len(register_sets) >= 1)
370 def test_qRegisterInfo_contains_at_least_one_register_set_debugserver(
372 self.init_debugserver_test()
374 self.qRegisterInfo_contains_at_least_one_register_set()
377 def test_qRegisterInfo_contains_at_least_one_register_set_llgs(self):
378 self.init_llgs_test()
380 self.qRegisterInfo_contains_at_least_one_register_set()
382 def targetHasAVX(self):
383 triple = self.dbg.GetSelectedPlatform().GetTriple()
385 # TODO other platforms, please implement this function
386 if not re.match(".*-.*-linux", triple):
389 # Need to do something different for non-Linux/Android targets
390 if lldb.remote_platform:
391 self.runCmd('platform get-file "/proc/cpuinfo" "cpuinfo"')
392 cpuinfo_path = "cpuinfo"
393 self.addTearDownHook(lambda: os.unlink("cpuinfo"))
395 cpuinfo_path = "/proc/cpuinfo"
397 f = open(cpuinfo_path, 'r')
400 return " avx " in cpuinfo
402 def qRegisterInfo_contains_avx_registers(self):
403 launch_args = self.install_and_create_launch_args()
405 server = self.connect_to_debug_monitor()
406 self.assertIsNotNone(server)
408 # Build the expected protocol stream
409 self.add_no_ack_remote_stream()
410 self.add_verified_launch_packets(launch_args)
411 self.add_register_info_collection_packets()
413 # Run the packet stream.
414 context = self.expect_gdbremote_sequence()
415 self.assertIsNotNone(context)
417 # Gather register info entries.
418 reg_infos = self.parse_register_info_packets(context)
420 # Collect all generics found.
422 reg_info['set']: 1 for reg_info in reg_infos if 'set' in reg_info}
425 "Advanced Vector Extensions" in register_sets)
428 def test_qRegisterInfo_contains_avx_registers_llgs(self):
429 self.init_llgs_test()
431 self.qRegisterInfo_contains_avx_registers()
433 def qThreadInfo_contains_thread(self):
434 procs = self.prep_debug_monitor_and_inferior()
435 self.add_threadinfo_collection_packets()
437 # Run the packet stream.
438 context = self.expect_gdbremote_sequence()
439 self.assertIsNotNone(context)
441 # Gather threadinfo entries.
442 threads = self.parse_threadinfo_packets(context)
443 self.assertIsNotNone(threads)
445 # We should have exactly one thread.
446 self.assertEqual(len(threads), 1)
449 def test_qThreadInfo_contains_thread_launch_debugserver(self):
450 self.init_debugserver_test()
452 self.set_inferior_startup_launch()
453 self.qThreadInfo_contains_thread()
456 def test_qThreadInfo_contains_thread_launch_llgs(self):
457 self.init_llgs_test()
459 self.set_inferior_startup_launch()
460 self.qThreadInfo_contains_thread()
463 def test_qThreadInfo_contains_thread_attach_debugserver(self):
464 self.init_debugserver_test()
466 self.set_inferior_startup_attach()
467 self.qThreadInfo_contains_thread()
470 def test_qThreadInfo_contains_thread_attach_llgs(self):
471 self.init_llgs_test()
473 self.set_inferior_startup_attach()
474 self.qThreadInfo_contains_thread()
476 def qThreadInfo_matches_qC(self):
477 procs = self.prep_debug_monitor_and_inferior()
479 self.add_threadinfo_collection_packets()
480 self.test_sequence.add_log_lines(
481 ["read packet: $qC#00",
482 {"direction": "send", "regex": r"^\$QC([0-9a-fA-F]+)#", "capture": {1: "thread_id"}}
485 # Run the packet stream.
486 context = self.expect_gdbremote_sequence()
487 self.assertIsNotNone(context)
489 # Gather threadinfo entries.
490 threads = self.parse_threadinfo_packets(context)
491 self.assertIsNotNone(threads)
493 # We should have exactly one thread from threadinfo.
494 self.assertEqual(len(threads), 1)
496 # We should have a valid thread_id from $QC.
497 QC_thread_id_hex = context.get("thread_id")
498 self.assertIsNotNone(QC_thread_id_hex)
499 QC_thread_id = int(QC_thread_id_hex, 16)
501 # Those two should be the same.
502 self.assertEqual(threads[0], QC_thread_id)
505 def test_qThreadInfo_matches_qC_launch_debugserver(self):
506 self.init_debugserver_test()
508 self.set_inferior_startup_launch()
509 self.qThreadInfo_matches_qC()
512 def test_qThreadInfo_matches_qC_launch_llgs(self):
513 self.init_llgs_test()
515 self.set_inferior_startup_launch()
516 self.qThreadInfo_matches_qC()
519 def test_qThreadInfo_matches_qC_attach_debugserver(self):
520 self.init_debugserver_test()
522 self.set_inferior_startup_attach()
523 self.qThreadInfo_matches_qC()
526 def test_qThreadInfo_matches_qC_attach_llgs(self):
527 self.init_llgs_test()
529 self.set_inferior_startup_attach()
530 self.qThreadInfo_matches_qC()
532 def p_returns_correct_data_size_for_each_qRegisterInfo(self):
533 procs = self.prep_debug_monitor_and_inferior()
534 self.add_register_info_collection_packets()
536 # Run the packet stream.
537 context = self.expect_gdbremote_sequence()
538 self.assertIsNotNone(context)
540 # Gather register info entries.
541 reg_infos = self.parse_register_info_packets(context)
542 self.assertIsNotNone(reg_infos)
543 self.assertTrue(len(reg_infos) > 0)
545 inferior_exe_path = os.path.abspath("a.out")
546 Target = self.dbg.CreateTarget(inferior_exe_path)
547 byte_order = Target.GetByteOrder()
549 # Read value for each register.
551 for reg_info in reg_infos:
552 # Skip registers that don't have a register set. For x86, these are
553 # the DRx registers, which have no LLDB-kind register number and thus
554 # cannot be read via normal
555 # NativeRegisterContext::ReadRegister(reg_info,...) calls.
556 if not "set" in reg_info:
559 # Clear existing packet expectations.
560 self.reset_test_sequence()
562 # Run the register query
563 self.test_sequence.add_log_lines(
564 ["read packet: $p{0:x}#00".format(reg_index),
565 {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#", "capture": {1: "p_response"}}],
567 context = self.expect_gdbremote_sequence()
568 self.assertIsNotNone(context)
570 # Verify the response length.
571 p_response = context.get("p_response")
572 self.assertIsNotNone(p_response)
574 if "dynamic_size_dwarf_expr_bytes" in reg_info:
575 self.updateRegInfoBitsize(reg_info, byte_order)
576 self.assertEqual(len(p_response), 2 * int(reg_info["bitsize"]) / 8)
582 def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch_debugserver(
584 self.init_debugserver_test()
586 self.set_inferior_startup_launch()
587 self.p_returns_correct_data_size_for_each_qRegisterInfo()
590 def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch_llgs(
592 self.init_llgs_test()
594 self.set_inferior_startup_launch()
595 self.p_returns_correct_data_size_for_each_qRegisterInfo()
598 def test_p_returns_correct_data_size_for_each_qRegisterInfo_attach_debugserver(
600 self.init_debugserver_test()
602 self.set_inferior_startup_attach()
603 self.p_returns_correct_data_size_for_each_qRegisterInfo()
606 def test_p_returns_correct_data_size_for_each_qRegisterInfo_attach_llgs(
608 self.init_llgs_test()
610 self.set_inferior_startup_attach()
611 self.p_returns_correct_data_size_for_each_qRegisterInfo()
613 def Hg_switches_to_3_threads(self):
614 # Startup the inferior with three threads (main + 2 new ones).
615 procs = self.prep_debug_monitor_and_inferior(
616 inferior_args=["thread:new", "thread:new"])
618 # Let the inferior process have a few moments to start up the thread
619 # when launched. (The launch scenario has no time to run, so threads
620 # won't be there yet.)
621 self.run_process_then_stop(run_seconds=1)
623 # Wait at most x seconds for 3 threads to be present.
624 threads = self.wait_for_thread_count(3, timeout_seconds=5)
625 self.assertEqual(len(threads), 3)
627 # verify we can $H to each thead, and $qC matches the thread we set.
628 for thread in threads:
629 # Change to each thread, verify current thread id.
630 self.reset_test_sequence()
631 self.test_sequence.add_log_lines(
632 ["read packet: $Hg{0:x}#00".format(thread), # Set current thread.
633 "send packet: $OK#00",
634 "read packet: $qC#00",
635 {"direction": "send", "regex": r"^\$QC([0-9a-fA-F]+)#", "capture": {1: "thread_id"}}],
638 context = self.expect_gdbremote_sequence()
639 self.assertIsNotNone(context)
641 # Verify the thread id.
642 self.assertIsNotNone(context.get("thread_id"))
643 self.assertEqual(int(context.get("thread_id"), 16), thread)
646 def test_Hg_switches_to_3_threads_launch_debugserver(self):
647 self.init_debugserver_test()
649 self.set_inferior_startup_launch()
650 self.Hg_switches_to_3_threads()
653 def test_Hg_switches_to_3_threads_launch_llgs(self):
654 self.init_llgs_test()
656 self.set_inferior_startup_launch()
657 self.Hg_switches_to_3_threads()
660 def test_Hg_switches_to_3_threads_attach_debugserver(self):
661 self.init_debugserver_test()
663 self.set_inferior_startup_attach()
664 self.Hg_switches_to_3_threads()
667 def test_Hg_switches_to_3_threads_attach_llgs(self):
668 self.init_llgs_test()
670 self.set_inferior_startup_attach()
671 self.Hg_switches_to_3_threads()
673 def Hc_then_Csignal_signals_correct_thread(self, segfault_signo):
674 # NOTE only run this one in inferior-launched mode: we can't grab inferior stdout when running attached,
675 # and the test requires getting stdout from the exe.
679 # Startup the inferior with three threads (main + NUM_THREADS-1 worker threads).
680 # inferior_args=["thread:print-ids"]
681 inferior_args = ["thread:segfault"]
682 for i in range(NUM_THREADS - 1):
684 # Give time between thread creation/segfaulting for the handler to work.
685 # inferior_args.append("sleep:1")
686 inferior_args.append("thread:new")
687 inferior_args.append("sleep:10")
689 # Launch/attach. (In our case, this should only ever be launched since
690 # we need inferior stdout/stderr).
691 procs = self.prep_debug_monitor_and_inferior(
692 inferior_args=inferior_args)
693 self.test_sequence.add_log_lines(["read packet: $c#63"], True)
694 context = self.expect_gdbremote_sequence()
696 # Let the inferior process have a few moments to start up the thread when launched.
697 # context = self.run_process_then_stop(run_seconds=1)
699 # Wait at most x seconds for all threads to be present.
700 # threads = self.wait_for_thread_count(NUM_THREADS, timeout_seconds=5)
701 # self.assertEquals(len(threads), NUM_THREADS)
704 print_thread_ids = {}
706 # Switch to each thread, deliver a signal, and verify signal delivery
707 for i in range(NUM_THREADS - 1):
708 # Run until SIGSEGV comes in.
709 self.reset_test_sequence()
710 self.test_sequence.add_log_lines([{"direction": "send",
711 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
712 "capture": {1: "signo",
716 context = self.expect_gdbremote_sequence(timeout_seconds=10)
717 self.assertIsNotNone(context)
718 signo = context.get("signo")
719 self.assertEqual(int(signo, 16), segfault_signo)
721 # Ensure we haven't seen this tid yet.
722 thread_id = int(context.get("thread_id"), 16)
723 self.assertFalse(thread_id in signaled_tids)
724 signaled_tids[thread_id] = 1
726 # Send SIGUSR1 to the thread that signaled the SIGSEGV.
727 self.reset_test_sequence()
728 self.test_sequence.add_log_lines(
730 # Set the continue thread.
731 # Set current thread.
732 "read packet: $Hc{0:x}#00".format(thread_id),
733 "send packet: $OK#00",
735 # Continue sending the signal number to the continue thread.
736 # The commented out packet is a way to do this same operation without using
737 # a $Hc (but this test is testing $Hc, so we'll stick with the former).
738 "read packet: $C{0:x}#00".format(lldbutil.get_signal_number('SIGUSR1')),
739 # "read packet: $vCont;C{0:x}:{1:x};c#00".format(lldbutil.get_signal_number('SIGUSR1'), thread_id),
741 # FIXME: Linux does not report the thread stop on the delivered signal (SIGUSR1 here). MacOSX debugserver does.
742 # But MacOSX debugserver isn't guaranteeing the thread the signal handler runs on, so currently its an XFAIL.
743 # Need to rectify behavior here. The linux behavior is more intuitive to me since we're essentially swapping out
744 # an about-to-be-delivered signal (for which we already sent a stop packet) to a different signal.
745 # {"direction":"send", "regex":r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture":{1:"stop_signo", 2:"stop_thread_id"} },
746 # "read packet: $c#63",
747 {"type": "output_match", "regex": r"^received SIGUSR1 on thread id: ([0-9a-fA-F]+)\r\nthread ([0-9a-fA-F]+): past SIGSEGV\r\n", "capture": {1: "print_thread_id", 2: "post_handle_thread_id"}},
752 context = self.expect_gdbremote_sequence(timeout_seconds=10)
753 self.assertIsNotNone(context)
755 # Ensure the stop signal is the signal we delivered.
756 # stop_signo = context.get("stop_signo")
757 # self.assertIsNotNone(stop_signo)
758 # self.assertEquals(int(stop_signo,16), lldbutil.get_signal_number('SIGUSR1'))
760 # Ensure the stop thread is the thread to which we delivered the signal.
761 # stop_thread_id = context.get("stop_thread_id")
762 # self.assertIsNotNone(stop_thread_id)
763 # self.assertEquals(int(stop_thread_id,16), thread_id)
765 # Ensure we haven't seen this thread id yet. The inferior's
766 # self-obtained thread ids are not guaranteed to match the stub
767 # tids (at least on MacOSX).
768 print_thread_id = context.get("print_thread_id")
769 self.assertIsNotNone(print_thread_id)
770 print_thread_id = int(print_thread_id, 16)
771 self.assertFalse(print_thread_id in print_thread_ids)
773 # Now remember this print (i.e. inferior-reflected) thread id and
774 # ensure we don't hit it again.
775 print_thread_ids[print_thread_id] = 1
777 # Ensure post signal-handle thread id matches the thread that
778 # initially raised the SIGSEGV.
779 post_handle_thread_id = context.get("post_handle_thread_id")
780 self.assertIsNotNone(post_handle_thread_id)
781 post_handle_thread_id = int(post_handle_thread_id, 16)
782 self.assertEqual(post_handle_thread_id, print_thread_id)
784 @unittest2.expectedFailure()
786 def test_Hc_then_Csignal_signals_correct_thread_launch_debugserver(self):
787 self.init_debugserver_test()
789 self.set_inferior_startup_launch()
790 # Darwin debugserver translates some signals like SIGSEGV into some gdb
791 # expectations about fixed signal numbers.
792 self.Hc_then_Csignal_signals_correct_thread(self.TARGET_EXC_BAD_ACCESS)
795 def test_Hc_then_Csignal_signals_correct_thread_launch_llgs(self):
796 self.init_llgs_test()
798 self.set_inferior_startup_launch()
799 self.Hc_then_Csignal_signals_correct_thread(
800 lldbutil.get_signal_number('SIGSEGV'))
802 def m_packet_reads_memory(self):
803 # This is the memory we will write into the inferior and then ensure we
804 # can read back with $m.
805 MEMORY_CONTENTS = "Test contents 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"
807 # Start up the inferior.
808 procs = self.prep_debug_monitor_and_inferior(
812 "get-data-address-hex:g_message",
816 self.test_sequence.add_log_lines(
818 # Start running after initial stop.
819 "read packet: $c#63",
820 # Match output line that prints the memory address of the message buffer within the inferior.
821 # Note we require launch-only testing so we can get inferior otuput.
822 {"type": "output_match", "regex": self.maybe_strict_output_regex(r"data address: 0x([0-9a-fA-F]+)\r\n"),
823 "capture": {1: "message_address"}},
824 # Now stop the inferior.
825 "read packet: {}".format(chr(3)),
826 # And wait for the stop notification.
827 {"direction": "send", "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture": {1: "stop_signo", 2: "stop_thread_id"}}],
830 # Run the packet stream.
831 context = self.expect_gdbremote_sequence()
832 self.assertIsNotNone(context)
834 # Grab the message address.
835 self.assertIsNotNone(context.get("message_address"))
836 message_address = int(context.get("message_address"), 16)
838 # Grab contents from the inferior.
839 self.reset_test_sequence()
840 self.test_sequence.add_log_lines(
841 ["read packet: $m{0:x},{1:x}#00".format(message_address, len(MEMORY_CONTENTS)),
842 {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$", "capture": {1: "read_contents"}}],
845 # Run the packet stream.
846 context = self.expect_gdbremote_sequence()
847 self.assertIsNotNone(context)
849 # Ensure what we read from inferior memory is what we wrote.
850 self.assertIsNotNone(context.get("read_contents"))
851 read_contents = context.get("read_contents").decode("hex")
852 self.assertEqual(read_contents, MEMORY_CONTENTS)
855 def test_m_packet_reads_memory_debugserver(self):
856 self.init_debugserver_test()
858 self.set_inferior_startup_launch()
859 self.m_packet_reads_memory()
862 def test_m_packet_reads_memory_llgs(self):
863 self.init_llgs_test()
865 self.set_inferior_startup_launch()
866 self.m_packet_reads_memory()
868 def qMemoryRegionInfo_is_supported(self):
869 # Start up the inferior.
870 procs = self.prep_debug_monitor_and_inferior()
872 # Ask if it supports $qMemoryRegionInfo.
873 self.test_sequence.add_log_lines(
874 ["read packet: $qMemoryRegionInfo#00",
875 "send packet: $OK#00"
877 self.expect_gdbremote_sequence()
880 def test_qMemoryRegionInfo_is_supported_debugserver(self):
881 self.init_debugserver_test()
883 self.set_inferior_startup_launch()
884 self.qMemoryRegionInfo_is_supported()
887 def test_qMemoryRegionInfo_is_supported_llgs(self):
888 self.init_llgs_test()
890 self.set_inferior_startup_launch()
891 self.qMemoryRegionInfo_is_supported()
893 def qMemoryRegionInfo_reports_code_address_as_executable(self):
894 # Start up the inferior.
895 procs = self.prep_debug_monitor_and_inferior(
896 inferior_args=["get-code-address-hex:hello", "sleep:5"])
899 self.test_sequence.add_log_lines(
901 # Start running after initial stop.
902 "read packet: $c#63",
903 # Match output line that prints the memory address of the message buffer within the inferior.
904 # Note we require launch-only testing so we can get inferior otuput.
905 {"type": "output_match", "regex": self.maybe_strict_output_regex(r"code address: 0x([0-9a-fA-F]+)\r\n"),
906 "capture": {1: "code_address"}},
907 # Now stop the inferior.
908 "read packet: {}".format(chr(3)),
909 # And wait for the stop notification.
910 {"direction": "send", "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture": {1: "stop_signo", 2: "stop_thread_id"}}],
913 # Run the packet stream.
914 context = self.expect_gdbremote_sequence()
915 self.assertIsNotNone(context)
917 # Grab the code address.
918 self.assertIsNotNone(context.get("code_address"))
919 code_address = int(context.get("code_address"), 16)
921 # Grab memory region info from the inferior.
922 self.reset_test_sequence()
923 self.add_query_memory_region_packets(code_address)
925 # Run the packet stream.
926 context = self.expect_gdbremote_sequence()
927 self.assertIsNotNone(context)
928 mem_region_dict = self.parse_memory_region_packet(context)
930 # Ensure there are no errors reported.
931 self.assertFalse("error" in mem_region_dict)
933 # Ensure code address is readable and executable.
934 self.assertTrue("permissions" in mem_region_dict)
935 self.assertTrue("r" in mem_region_dict["permissions"])
936 self.assertTrue("x" in mem_region_dict["permissions"])
938 # Ensure the start address and size encompass the address we queried.
939 self.assert_address_within_memory_region(code_address, mem_region_dict)
942 def test_qMemoryRegionInfo_reports_code_address_as_executable_debugserver(
944 self.init_debugserver_test()
946 self.set_inferior_startup_launch()
947 self.qMemoryRegionInfo_reports_code_address_as_executable()
950 def test_qMemoryRegionInfo_reports_code_address_as_executable_llgs(self):
951 self.init_llgs_test()
953 self.set_inferior_startup_launch()
954 self.qMemoryRegionInfo_reports_code_address_as_executable()
956 def qMemoryRegionInfo_reports_stack_address_as_readable_writeable(self):
957 # Start up the inferior.
958 procs = self.prep_debug_monitor_and_inferior(
959 inferior_args=["get-stack-address-hex:", "sleep:5"])
962 self.test_sequence.add_log_lines(
964 # Start running after initial stop.
965 "read packet: $c#63",
966 # Match output line that prints the memory address of the message buffer within the inferior.
967 # Note we require launch-only testing so we can get inferior otuput.
968 {"type": "output_match", "regex": self.maybe_strict_output_regex(r"stack address: 0x([0-9a-fA-F]+)\r\n"),
969 "capture": {1: "stack_address"}},
970 # Now stop the inferior.
971 "read packet: {}".format(chr(3)),
972 # And wait for the stop notification.
973 {"direction": "send", "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture": {1: "stop_signo", 2: "stop_thread_id"}}],
976 # Run the packet stream.
977 context = self.expect_gdbremote_sequence()
978 self.assertIsNotNone(context)
981 self.assertIsNotNone(context.get("stack_address"))
982 stack_address = int(context.get("stack_address"), 16)
984 # Grab memory region info from the inferior.
985 self.reset_test_sequence()
986 self.add_query_memory_region_packets(stack_address)
988 # Run the packet stream.
989 context = self.expect_gdbremote_sequence()
990 self.assertIsNotNone(context)
991 mem_region_dict = self.parse_memory_region_packet(context)
993 # Ensure there are no errors reported.
994 self.assertFalse("error" in mem_region_dict)
996 # Ensure address is readable and executable.
997 self.assertTrue("permissions" in mem_region_dict)
998 self.assertTrue("r" in mem_region_dict["permissions"])
999 self.assertTrue("w" in mem_region_dict["permissions"])
1001 # Ensure the start address and size encompass the address we queried.
1002 self.assert_address_within_memory_region(
1003 stack_address, mem_region_dict)
1006 def test_qMemoryRegionInfo_reports_stack_address_as_readable_writeable_debugserver(
1008 self.init_debugserver_test()
1010 self.set_inferior_startup_launch()
1011 self.qMemoryRegionInfo_reports_stack_address_as_readable_writeable()
1014 def test_qMemoryRegionInfo_reports_stack_address_as_readable_writeable_llgs(
1016 self.init_llgs_test()
1018 self.set_inferior_startup_launch()
1019 self.qMemoryRegionInfo_reports_stack_address_as_readable_writeable()
1021 def qMemoryRegionInfo_reports_heap_address_as_readable_writeable(self):
1022 # Start up the inferior.
1023 procs = self.prep_debug_monitor_and_inferior(
1024 inferior_args=["get-heap-address-hex:", "sleep:5"])
1027 self.test_sequence.add_log_lines(
1029 # Start running after initial stop.
1030 "read packet: $c#63",
1031 # Match output line that prints the memory address of the message buffer within the inferior.
1032 # Note we require launch-only testing so we can get inferior otuput.
1033 {"type": "output_match", "regex": self.maybe_strict_output_regex(r"heap address: 0x([0-9a-fA-F]+)\r\n"),
1034 "capture": {1: "heap_address"}},
1035 # Now stop the inferior.
1036 "read packet: {}".format(chr(3)),
1037 # And wait for the stop notification.
1038 {"direction": "send", "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture": {1: "stop_signo", 2: "stop_thread_id"}}],
1041 # Run the packet stream.
1042 context = self.expect_gdbremote_sequence()
1043 self.assertIsNotNone(context)
1046 self.assertIsNotNone(context.get("heap_address"))
1047 heap_address = int(context.get("heap_address"), 16)
1049 # Grab memory region info from the inferior.
1050 self.reset_test_sequence()
1051 self.add_query_memory_region_packets(heap_address)
1053 # Run the packet stream.
1054 context = self.expect_gdbremote_sequence()
1055 self.assertIsNotNone(context)
1056 mem_region_dict = self.parse_memory_region_packet(context)
1058 # Ensure there are no errors reported.
1059 self.assertFalse("error" in mem_region_dict)
1061 # Ensure address is readable and executable.
1062 self.assertTrue("permissions" in mem_region_dict)
1063 self.assertTrue("r" in mem_region_dict["permissions"])
1064 self.assertTrue("w" in mem_region_dict["permissions"])
1066 # Ensure the start address and size encompass the address we queried.
1067 self.assert_address_within_memory_region(heap_address, mem_region_dict)
1070 def test_qMemoryRegionInfo_reports_heap_address_as_readable_writeable_debugserver(
1072 self.init_debugserver_test()
1074 self.set_inferior_startup_launch()
1075 self.qMemoryRegionInfo_reports_heap_address_as_readable_writeable()
1078 def test_qMemoryRegionInfo_reports_heap_address_as_readable_writeable_llgs(
1080 self.init_llgs_test()
1082 self.set_inferior_startup_launch()
1083 self.qMemoryRegionInfo_reports_heap_address_as_readable_writeable()
1085 def software_breakpoint_set_and_remove_work(self):
1086 # Start up the inferior.
1087 procs = self.prep_debug_monitor_and_inferior(
1089 "get-code-address-hex:hello",
1091 "call-function:hello"])
1094 self.add_register_info_collection_packets()
1095 self.add_process_info_collection_packets()
1096 self.test_sequence.add_log_lines(
1097 [ # Start running after initial stop.
1098 "read packet: $c#63",
1099 # Match output line that prints the memory address of the function call entry point.
1100 # Note we require launch-only testing so we can get inferior otuput.
1101 {"type": "output_match", "regex": self.maybe_strict_output_regex(r"code address: 0x([0-9a-fA-F]+)\r\n"),
1102 "capture": {1: "function_address"}},
1103 # Now stop the inferior.
1104 "read packet: {}".format(chr(3)),
1105 # And wait for the stop notification.
1106 {"direction": "send", "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture": {1: "stop_signo", 2: "stop_thread_id"}}],
1109 # Run the packet stream.
1110 context = self.expect_gdbremote_sequence()
1111 self.assertIsNotNone(context)
1113 # Gather process info - we need endian of target to handle register
1114 # value conversions.
1115 process_info = self.parse_process_info_response(context)
1116 endian = process_info.get("endian")
1117 self.assertIsNotNone(endian)
1119 # Gather register info entries.
1120 reg_infos = self.parse_register_info_packets(context)
1121 (pc_lldb_reg_index, pc_reg_info) = self.find_pc_reg_info(reg_infos)
1122 self.assertIsNotNone(pc_lldb_reg_index)
1123 self.assertIsNotNone(pc_reg_info)
1125 # Grab the function address.
1126 self.assertIsNotNone(context.get("function_address"))
1127 function_address = int(context.get("function_address"), 16)
1129 # Set the breakpoint.
1130 if self.getArchitecture() == "arm":
1131 # TODO: Handle case when setting breakpoint in thumb code
1135 self.reset_test_sequence()
1136 self.add_set_breakpoint_packets(
1139 breakpoint_kind=BREAKPOINT_KIND)
1141 # Run the packet stream.
1142 context = self.expect_gdbremote_sequence()
1143 self.assertIsNotNone(context)
1145 # Verify the stop signal reported was the breakpoint signal number.
1146 stop_signo = context.get("stop_signo")
1147 self.assertIsNotNone(stop_signo)
1148 self.assertEqual(int(stop_signo, 16),
1149 lldbutil.get_signal_number('SIGTRAP'))
1151 # Ensure we did not receive any output. If the breakpoint was not set, we would
1152 # see output (from a launched process with captured stdio) printing a hello, world message.
1153 # That would indicate the breakpoint didn't take.
1154 self.assertEqual(len(context["O_content"]), 0)
1156 # Verify that the PC for the main thread is where we expect it - right at the breakpoint address.
1157 # This acts as a another validation on the register reading code.
1158 self.reset_test_sequence()
1159 self.test_sequence.add_log_lines(
1161 # Print the PC. This should match the breakpoint address.
1162 "read packet: $p{0:x}#00".format(pc_lldb_reg_index),
1163 # Capture $p results.
1164 {"direction": "send",
1165 "regex": r"^\$([0-9a-fA-F]+)#",
1166 "capture": {1: "p_response"}},
1169 context = self.expect_gdbremote_sequence()
1170 self.assertIsNotNone(context)
1172 # Verify the PC is where we expect. Note response is in endianness of
1174 p_response = context.get("p_response")
1175 self.assertIsNotNone(p_response)
1177 # Convert from target endian to int.
1178 returned_pc = lldbgdbserverutils.unpack_register_hex_unsigned(
1180 self.assertEqual(returned_pc, function_address)
1182 # Verify that a breakpoint remove and continue gets us the expected
1184 self.reset_test_sequence()
1185 self.test_sequence.add_log_lines(
1187 # Remove the breakpoint.
1188 "read packet: $z0,{0:x},{1}#00".format(
1189 function_address, BREAKPOINT_KIND),
1190 # Verify the stub could unset it.
1191 "send packet: $OK#00",
1193 "read packet: $c#63",
1194 # We should now receive the output from the call.
1195 {"type": "output_match", "regex": r"^hello, world\r\n$"},
1196 # And wait for program completion.
1197 {"direction": "send", "regex": r"^\$W00(.*)#[0-9a-fA-F]{2}$"},
1200 context = self.expect_gdbremote_sequence()
1201 self.assertIsNotNone(context)
1204 def test_software_breakpoint_set_and_remove_work_debugserver(self):
1205 self.init_debugserver_test()
1206 if self.getArchitecture() == "arm":
1207 # TODO: Handle case when setting breakpoint in thumb code
1208 self.build(dictionary={'CFLAGS_EXTRAS': '-marm'})
1211 self.set_inferior_startup_launch()
1212 self.software_breakpoint_set_and_remove_work()
1215 @expectedFlakeyLinux("llvm.org/pr25652")
1216 def test_software_breakpoint_set_and_remove_work_llgs(self):
1217 self.init_llgs_test()
1218 if self.getArchitecture() == "arm":
1219 # TODO: Handle case when setting breakpoint in thumb code
1220 self.build(dictionary={'CFLAGS_EXTRAS': '-marm'})
1223 self.set_inferior_startup_launch()
1224 self.software_breakpoint_set_and_remove_work()
1226 def qSupported_returns_known_stub_features(self):
1227 # Start up the stub and start/prep the inferior.
1228 procs = self.prep_debug_monitor_and_inferior()
1229 self.add_qSupported_packets()
1231 # Run the packet stream.
1232 context = self.expect_gdbremote_sequence()
1233 self.assertIsNotNone(context)
1235 # Retrieve the qSupported features.
1236 supported_dict = self.parse_qSupported_response(context)
1237 self.assertIsNotNone(supported_dict)
1238 self.assertTrue(len(supported_dict) > 0)
1241 def test_qSupported_returns_known_stub_features_debugserver(self):
1242 self.init_debugserver_test()
1244 self.set_inferior_startup_launch()
1245 self.qSupported_returns_known_stub_features()
1248 def test_qSupported_returns_known_stub_features_llgs(self):
1249 self.init_llgs_test()
1251 self.set_inferior_startup_launch()
1252 self.qSupported_returns_known_stub_features()
1254 def written_M_content_reads_back_correctly(self):
1255 TEST_MESSAGE = "Hello, memory"
1257 # Start up the stub and start/prep the inferior.
1258 procs = self.prep_debug_monitor_and_inferior(
1260 "set-message:xxxxxxxxxxxxxX",
1261 "get-data-address-hex:g_message",
1264 self.test_sequence.add_log_lines(
1266 # Start running after initial stop.
1267 "read packet: $c#63",
1268 # Match output line that prints the memory address of the message buffer within the inferior.
1269 # Note we require launch-only testing so we can get inferior otuput.
1270 {"type": "output_match", "regex": self.maybe_strict_output_regex(r"data address: 0x([0-9a-fA-F]+)\r\n"),
1271 "capture": {1: "message_address"}},
1272 # Now stop the inferior.
1273 "read packet: {}".format(chr(3)),
1274 # And wait for the stop notification.
1275 {"direction": "send", "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture": {1: "stop_signo", 2: "stop_thread_id"}}],
1277 context = self.expect_gdbremote_sequence()
1278 self.assertIsNotNone(context)
1280 # Grab the message address.
1281 self.assertIsNotNone(context.get("message_address"))
1282 message_address = int(context.get("message_address"), 16)
1284 # Hex-encode the test message, adding null termination.
1285 hex_encoded_message = TEST_MESSAGE.encode("hex")
1287 # Write the message to the inferior. Verify that we can read it with the hex-encoded (m)
1288 # and binary (x) memory read packets.
1289 self.reset_test_sequence()
1290 self.test_sequence.add_log_lines(
1291 ["read packet: $M{0:x},{1:x}:{2}#00".format(message_address, len(TEST_MESSAGE), hex_encoded_message),
1292 "send packet: $OK#00",
1293 "read packet: $m{0:x},{1:x}#00".format(message_address, len(TEST_MESSAGE)),
1294 "send packet: ${0}#00".format(hex_encoded_message),
1295 "read packet: $x{0:x},{1:x}#00".format(message_address, len(TEST_MESSAGE)),
1296 "send packet: ${0}#00".format(TEST_MESSAGE),
1297 "read packet: $m{0:x},4#00".format(message_address),
1298 "send packet: ${0}#00".format(hex_encoded_message[0:8]),
1299 "read packet: $x{0:x},4#00".format(message_address),
1300 "send packet: ${0}#00".format(TEST_MESSAGE[0:4]),
1301 "read packet: $c#63",
1302 {"type": "output_match", "regex": r"^message: (.+)\r\n$", "capture": {1: "printed_message"}},
1303 "send packet: $W00#00",
1305 context = self.expect_gdbremote_sequence()
1306 self.assertIsNotNone(context)
1308 # Ensure what we read from inferior memory is what we wrote.
1309 printed_message = context.get("printed_message")
1310 self.assertIsNotNone(printed_message)
1311 self.assertEqual(printed_message, TEST_MESSAGE + "X")
1314 def test_written_M_content_reads_back_correctly_debugserver(self):
1315 self.init_debugserver_test()
1317 self.set_inferior_startup_launch()
1318 self.written_M_content_reads_back_correctly()
1321 @expectedFlakeyLinux("llvm.org/pr25652")
1322 def test_written_M_content_reads_back_correctly_llgs(self):
1323 self.init_llgs_test()
1325 self.set_inferior_startup_launch()
1326 self.written_M_content_reads_back_correctly()
1328 def P_writes_all_gpr_registers(self):
1329 # Start inferior debug session, grab all register info.
1330 procs = self.prep_debug_monitor_and_inferior(inferior_args=["sleep:2"])
1331 self.add_register_info_collection_packets()
1332 self.add_process_info_collection_packets()
1334 context = self.expect_gdbremote_sequence()
1335 self.assertIsNotNone(context)
1337 # Process register infos.
1338 reg_infos = self.parse_register_info_packets(context)
1339 self.assertIsNotNone(reg_infos)
1340 self.add_lldb_register_index(reg_infos)
1343 process_info = self.parse_process_info_response(context)
1344 endian = process_info.get("endian")
1345 self.assertIsNotNone(endian)
1347 # Pull out the register infos that we think we can bit flip
1350 reg_info for reg_info in reg_infos if self.is_bit_flippable_register(reg_info)]
1351 self.assertTrue(len(gpr_reg_infos) > 0)
1353 # Write flipped bit pattern of existing value to each register.
1354 (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
1355 gpr_reg_infos, endian)
1356 # print("successful writes: {}, failed writes: {}".format(successful_writes, failed_writes))
1357 self.assertTrue(successful_writes > 0)
1359 # Note: as of this moment, a hefty number of the GPR writes are failing with E32 (everything except rax-rdx, rdi, rsi, rbp).
1360 # Come back to this. I have the test rigged to verify that at least some
1361 # of the bit-flip writes work.
1363 def test_P_writes_all_gpr_registers_debugserver(self):
1364 self.init_debugserver_test()
1366 self.set_inferior_startup_launch()
1367 self.P_writes_all_gpr_registers()
1370 def test_P_writes_all_gpr_registers_llgs(self):
1371 self.init_llgs_test()
1373 self.set_inferior_startup_launch()
1374 self.P_writes_all_gpr_registers()
1376 def P_and_p_thread_suffix_work(self):
1377 # Startup the inferior with three threads.
1378 procs = self.prep_debug_monitor_and_inferior(
1379 inferior_args=["thread:new", "thread:new"])
1380 self.add_thread_suffix_request_packets()
1381 self.add_register_info_collection_packets()
1382 self.add_process_info_collection_packets()
1384 context = self.expect_gdbremote_sequence()
1385 self.assertIsNotNone(context)
1387 process_info = self.parse_process_info_response(context)
1388 self.assertIsNotNone(process_info)
1389 endian = process_info.get("endian")
1390 self.assertIsNotNone(endian)
1392 reg_infos = self.parse_register_info_packets(context)
1393 self.assertIsNotNone(reg_infos)
1394 self.add_lldb_register_index(reg_infos)
1396 reg_index = self.select_modifiable_register(reg_infos)
1397 self.assertIsNotNone(reg_index)
1398 reg_byte_size = int(reg_infos[reg_index]["bitsize"]) / 8
1399 self.assertTrue(reg_byte_size > 0)
1401 # Run the process a bit so threads can start up, and collect register
1403 context = self.run_process_then_stop(run_seconds=1)
1404 self.assertIsNotNone(context)
1406 # Wait for 3 threads to be present.
1407 threads = self.wait_for_thread_count(3, timeout_seconds=5)
1408 self.assertEqual(len(threads), 3)
1410 expected_reg_values = []
1411 register_increment = 1
1414 # Set the same register in each of 3 threads to a different value.
1415 # Verify each one has the unique value.
1416 for thread in threads:
1417 # If we don't have a next value yet, start it with the initial read
1420 # Read pre-existing register value.
1421 self.reset_test_sequence()
1422 self.test_sequence.add_log_lines(
1423 ["read packet: $p{0:x};thread:{1:x}#00".format(reg_index, thread),
1424 {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#", "capture": {1: "p_response"}},
1426 context = self.expect_gdbremote_sequence()
1427 self.assertIsNotNone(context)
1429 # Set the next value to use for writing as the increment plus
1431 p_response = context.get("p_response")
1432 self.assertIsNotNone(p_response)
1433 next_value = lldbgdbserverutils.unpack_register_hex_unsigned(
1436 # Set new value using P and thread suffix.
1437 self.reset_test_sequence()
1438 self.test_sequence.add_log_lines(
1440 "read packet: $P{0:x}={1};thread:{2:x}#00".format(
1442 lldbgdbserverutils.pack_register_hex(
1445 byte_size=reg_byte_size),
1447 "send packet: $OK#00",
1450 context = self.expect_gdbremote_sequence()
1451 self.assertIsNotNone(context)
1453 # Save the value we set.
1454 expected_reg_values.append(next_value)
1456 # Increment value for next thread to use (we want them all
1457 # different so we can verify they wrote to each thread correctly
1459 next_value += register_increment
1461 # Revisit each thread and verify they have the expected value set for
1462 # the register we wrote.
1464 for thread in threads:
1465 # Read pre-existing register value.
1466 self.reset_test_sequence()
1467 self.test_sequence.add_log_lines(
1468 ["read packet: $p{0:x};thread:{1:x}#00".format(reg_index, thread),
1469 {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#", "capture": {1: "p_response"}},
1471 context = self.expect_gdbremote_sequence()
1472 self.assertIsNotNone(context)
1474 # Get the register value.
1475 p_response = context.get("p_response")
1476 self.assertIsNotNone(p_response)
1477 read_value = lldbgdbserverutils.unpack_register_hex_unsigned(
1480 # Make sure we read back what we wrote.
1481 self.assertEqual(read_value, expected_reg_values[thread_index])
1484 # Note: as of this moment, a hefty number of the GPR writes are failing
1485 # with E32 (everything except rax-rdx, rdi, rsi, rbp).
1487 def test_P_and_p_thread_suffix_work_debugserver(self):
1488 self.init_debugserver_test()
1490 self.set_inferior_startup_launch()
1491 self.P_and_p_thread_suffix_work()
1494 def test_P_and_p_thread_suffix_work_llgs(self):
1495 self.init_llgs_test()
1497 self.set_inferior_startup_launch()
1498 self.P_and_p_thread_suffix_work()