[C++20] [Modules] Fix may-be incorrect ADL for module local entities (#123931)
[llvm-project.git] / lldb / test / API / tools / lldb-server / TestLldbGdbServer.py
blob592037db502aafc5068f4aebf4d4175f65dfd19d
1 """
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
6 available.
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.
11 """
13 import binascii
14 import itertools
15 import struct
17 import gdbremote_testcase
18 import lldbgdbserverutils
19 from lldbsuite.support import seven
20 from lldbsuite.test.decorators import *
21 from lldbsuite.test.lldbtest import *
22 from lldbsuite.test.lldbdwarf import *
23 from lldbsuite.test import lldbutil, lldbplatformutil
26 class LldbGdbServerTestCase(
27 gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcodeParser
29 def test_thread_suffix_supported(self):
30 server = self.connect_to_debug_monitor()
31 self.assertIsNotNone(server)
33 self.do_handshake()
34 self.test_sequence.add_log_lines(
36 "lldb-server < 26> read packet: $QThreadSuffixSupported#e4",
37 "lldb-server < 6> send packet: $OK#9a",
39 True,
42 self.expect_gdbremote_sequence()
44 def test_list_threads_in_stop_reply_supported(self):
45 server = self.connect_to_debug_monitor()
46 self.assertIsNotNone(server)
48 self.do_handshake()
49 self.test_sequence.add_log_lines(
51 "lldb-server < 27> read packet: $QListThreadsInStopReply#21",
52 "lldb-server < 6> send packet: $OK#9a",
54 True,
56 self.expect_gdbremote_sequence()
58 def test_c_packet_works(self):
59 self.build()
60 procs = self.prep_debug_monitor_and_inferior()
61 self.test_sequence.add_log_lines(
62 ["read packet: $c#63", "send packet: $W00#00"], True
65 self.expect_gdbremote_sequence()
67 @skipIfWindows # No pty support to test any inferior output
68 def test_inferior_print_exit(self):
69 self.build()
70 procs = self.prep_debug_monitor_and_inferior(inferior_args=["hello, world"])
71 self.test_sequence.add_log_lines(
73 "read packet: $vCont;c#a8",
75 "type": "output_match",
76 "regex": self.maybe_strict_output_regex(r"hello, world\r\n"),
78 "send packet: $W00#00",
80 True,
83 context = self.expect_gdbremote_sequence()
84 self.assertIsNotNone(context)
86 def test_first_launch_stop_reply_thread_matches_first_qC(self):
87 self.build()
88 procs = self.prep_debug_monitor_and_inferior()
89 self.test_sequence.add_log_lines(
91 "read packet: $qC#00",
93 "direction": "send",
94 "regex": r"^\$QC([0-9a-fA-F]+)#",
95 "capture": {1: "thread_id_QC"},
97 "read packet: $?#00",
99 "direction": "send",
100 "regex": r"^\$T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+)",
101 "capture": {1: "thread_id_?"},
104 True,
106 context = self.expect_gdbremote_sequence()
107 self.assertEqual(context.get("thread_id_QC"), context.get("thread_id_?"))
109 def test_attach_commandline_continue_app_exits(self):
110 self.build()
111 self.set_inferior_startup_attach()
112 procs = self.prep_debug_monitor_and_inferior()
113 self.test_sequence.add_log_lines(
114 ["read packet: $vCont;c#a8", "send packet: $W00#00"], True
116 self.expect_gdbremote_sequence()
118 # Wait a moment for completed and now-detached inferior process to
119 # clear.
120 time.sleep(1)
122 if not lldb.remote_platform:
123 # Process should be dead now. Reap results.
124 poll_result = procs["inferior"].poll()
125 self.assertIsNotNone(poll_result)
127 # Where possible, verify at the system level that the process is not
128 # running.
129 self.assertFalse(
130 lldbgdbserverutils.process_is_running(procs["inferior"].pid, False)
133 def test_qRegisterInfo_returns_one_valid_result(self):
134 self.build()
135 self.prep_debug_monitor_and_inferior()
136 self.test_sequence.add_log_lines(
138 "read packet: $qRegisterInfo0#00",
140 "direction": "send",
141 "regex": r"^\$(.+);#[0-9A-Fa-f]{2}",
142 "capture": {1: "reginfo_0"},
145 True,
148 # Run the stream
149 context = self.expect_gdbremote_sequence()
150 self.assertIsNotNone(context)
152 reg_info_packet = context.get("reginfo_0")
153 self.assertIsNotNone(reg_info_packet)
154 self.assert_valid_reg_info(
155 lldbgdbserverutils.parse_reg_info_response(reg_info_packet)
158 def test_qRegisterInfo_returns_all_valid_results(self):
159 self.build()
160 self.prep_debug_monitor_and_inferior()
161 self.add_register_info_collection_packets()
163 # Run the stream.
164 context = self.expect_gdbremote_sequence()
165 self.assertIsNotNone(context)
167 # Validate that each register info returned validates.
168 for reg_info in self.parse_register_info_packets(context):
169 self.assert_valid_reg_info(reg_info)
171 def test_qRegisterInfo_contains_required_generics_debugserver(self):
172 self.build()
173 self.prep_debug_monitor_and_inferior()
174 self.add_register_info_collection_packets()
176 # Run the packet stream.
177 context = self.expect_gdbremote_sequence()
178 self.assertIsNotNone(context)
180 # Gather register info entries.
181 reg_infos = self.parse_register_info_packets(context)
183 # Collect all generic registers found.
184 generic_regs = {
185 reg_info["generic"]: 1 for reg_info in reg_infos if "generic" in reg_info
188 # Ensure we have a program counter register.
189 self.assertIn("pc", generic_regs)
191 # Ensure we have a frame pointer register. PPC64le's FP is the same as SP
192 if self.getArchitecture() != "powerpc64le":
193 self.assertIn("fp", generic_regs)
195 # Ensure we have a stack pointer register.
196 self.assertIn("sp", generic_regs)
198 # Ensure we have a flags register.
199 self.assertIn("flags", generic_regs)
201 def test_qRegisterInfo_contains_at_least_one_register_set(self):
202 self.build()
203 self.prep_debug_monitor_and_inferior()
204 self.add_register_info_collection_packets()
206 # Run the packet stream.
207 context = self.expect_gdbremote_sequence()
208 self.assertIsNotNone(context)
210 # Gather register info entries.
211 reg_infos = self.parse_register_info_packets(context)
213 # Collect all register sets found.
214 register_sets = {
215 reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info
217 self.assertGreaterEqual(len(register_sets), 1)
219 def targetHasAVX(self):
220 triple = self.dbg.GetSelectedPlatform().GetTriple()
222 # TODO other platforms, please implement this function
223 if not re.match(".*-.*-linux", triple):
224 return True
226 # Need to do something different for non-Linux/Android targets
227 if lldb.remote_platform:
228 self.runCmd('platform get-file "/proc/cpuinfo" "cpuinfo"')
229 cpuinfo_path = "cpuinfo"
230 self.addTearDownHook(lambda: os.unlink("cpuinfo"))
231 else:
232 cpuinfo_path = "/proc/cpuinfo"
234 f = open(cpuinfo_path, "r")
235 cpuinfo = f.read()
236 f.close()
237 return " avx " in cpuinfo
239 @expectedFailureAll(oslist=["windows"]) # no avx for now.
240 @skipIf(archs=no_match(["amd64", "i386", "x86_64"]))
241 @add_test_categories(["llgs"])
242 def test_qRegisterInfo_contains_avx_registers(self):
243 self.build()
244 self.prep_debug_monitor_and_inferior()
245 self.add_register_info_collection_packets()
247 # Run the packet stream.
248 context = self.expect_gdbremote_sequence()
249 self.assertIsNotNone(context)
251 # Gather register info entries.
252 reg_infos = self.parse_register_info_packets(context)
254 # Collect all generics found.
255 register_sets = {
256 reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info
258 self.assertEqual(
259 self.targetHasAVX(), "Advanced Vector Extensions" in register_sets
262 def qThreadInfo_contains_thread(self):
263 procs = self.prep_debug_monitor_and_inferior()
264 self.add_threadinfo_collection_packets()
266 # Run the packet stream.
267 context = self.expect_gdbremote_sequence()
268 self.assertIsNotNone(context)
270 # Gather threadinfo entries.
271 threads = self.parse_threadinfo_packets(context)
272 self.assertIsNotNone(threads)
274 # We should have exactly one thread.
275 self.assertEqual(len(threads), 1)
277 def test_qThreadInfo_contains_thread_launch(self):
278 self.build()
279 self.set_inferior_startup_launch()
280 self.qThreadInfo_contains_thread()
282 @expectedFailureAll(oslist=["windows"]) # expect one more thread stopped
283 def test_qThreadInfo_contains_thread_attach(self):
284 self.build()
285 self.set_inferior_startup_attach()
286 self.qThreadInfo_contains_thread()
288 def qThreadInfo_matches_qC(self):
289 procs = self.prep_debug_monitor_and_inferior()
291 self.add_threadinfo_collection_packets()
292 self.test_sequence.add_log_lines(
294 "read packet: $qC#00",
296 "direction": "send",
297 "regex": r"^\$QC([0-9a-fA-F]+)#",
298 "capture": {1: "thread_id"},
301 True,
304 # Run the packet stream.
305 context = self.expect_gdbremote_sequence()
306 self.assertIsNotNone(context)
308 # Gather threadinfo entries.
309 threads = self.parse_threadinfo_packets(context)
310 self.assertIsNotNone(threads)
312 # We should have exactly one thread from threadinfo.
313 self.assertEqual(len(threads), 1)
315 # We should have a valid thread_id from $QC.
316 QC_thread_id_hex = context.get("thread_id")
317 self.assertIsNotNone(QC_thread_id_hex)
318 QC_thread_id = int(QC_thread_id_hex, 16)
320 # Those two should be the same.
321 self.assertEqual(threads[0], QC_thread_id)
323 def test_qThreadInfo_matches_qC_launch(self):
324 self.build()
325 self.set_inferior_startup_launch()
326 self.qThreadInfo_matches_qC()
328 @expectedFailureAll(oslist=["windows"]) # expect one more thread stopped
329 def test_qThreadInfo_matches_qC_attach(self):
330 self.build()
331 self.set_inferior_startup_attach()
332 self.qThreadInfo_matches_qC()
334 def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch(self):
335 self.build()
336 self.set_inferior_startup_launch()
337 procs = self.prep_debug_monitor_and_inferior()
338 self.add_register_info_collection_packets()
340 # Run the packet stream.
341 context = self.expect_gdbremote_sequence()
342 self.assertIsNotNone(context)
344 # Gather register info entries.
345 reg_infos = self.parse_register_info_packets(context)
346 self.assertIsNotNone(reg_infos)
347 self.assertGreater(len(reg_infos), 0)
349 byte_order = self.get_target_byte_order()
351 # Read value for each register.
352 reg_index = 0
353 for reg_info in reg_infos:
354 # Skip registers that don't have a register set. For x86, these are
355 # the DRx registers, which have no LLDB-kind register number and thus
356 # cannot be read via normal
357 # NativeRegisterContext::ReadRegister(reg_info,...) calls.
358 if not "set" in reg_info:
359 continue
361 # Clear existing packet expectations.
362 self.reset_test_sequence()
364 # Run the register query
365 self.test_sequence.add_log_lines(
367 "read packet: $p{0:x}#00".format(reg_index),
369 "direction": "send",
370 "regex": r"^\$([0-9a-fA-F]+)#",
371 "capture": {1: "p_response"},
374 True,
376 context = self.expect_gdbremote_sequence()
377 self.assertIsNotNone(context)
379 # Verify the response length.
380 p_response = context.get("p_response")
381 self.assertIsNotNone(p_response)
383 # Skip erraneous (unsupported) registers.
384 # TODO: remove this once we make unsupported registers disappear.
385 if p_response.startswith("E") and len(p_response) == 3:
386 continue
388 if "dynamic_size_dwarf_expr_bytes" in reg_info:
389 self.updateRegInfoBitsize(reg_info, byte_order)
390 self.assertEqual(
391 len(p_response), 2 * int(reg_info["bitsize"]) / 8, reg_info
394 # Increment loop
395 reg_index += 1
397 def Hg_switches_to_3_threads(self, pass_pid=False):
398 _, threads = self.launch_with_threads(3)
400 pid_str = ""
401 if pass_pid:
402 pid_str = "p{0:x}.".format(procs["inferior"].pid)
404 # verify we can $H to each thead, and $qC matches the thread we set.
405 for thread in threads:
406 # Change to each thread, verify current thread id.
407 self.reset_test_sequence()
408 self.test_sequence.add_log_lines(
410 "read packet: $Hg{0}{1:x}#00".format(
411 pid_str, thread
412 ), # Set current thread.
413 "send packet: $OK#00",
414 "read packet: $qC#00",
416 "direction": "send",
417 "regex": r"^\$QC([0-9a-fA-F]+)#",
418 "capture": {1: "thread_id"},
421 True,
424 context = self.expect_gdbremote_sequence()
425 self.assertIsNotNone(context)
427 # Verify the thread id.
428 self.assertIsNotNone(context.get("thread_id"))
429 self.assertEqual(int(context.get("thread_id"), 16), thread)
431 @skipIf(compiler="clang", compiler_version=["<", "11.0"])
432 def test_Hg_switches_to_3_threads_launch(self):
433 self.build()
434 self.set_inferior_startup_launch()
435 self.Hg_switches_to_3_threads()
437 def Hg_fails_on_pid(self, pass_pid):
438 _, threads = self.launch_with_threads(2)
440 if pass_pid == -1:
441 pid_str = "p-1."
442 else:
443 pid_str = "p{0:x}.".format(pass_pid)
444 thread = threads[1]
446 self.test_sequence.add_log_lines(
448 "read packet: $Hg{0}{1:x}#00".format(
449 pid_str, thread
450 ), # Set current thread.
451 "send packet: $Eff#00",
453 True,
456 self.expect_gdbremote_sequence()
458 @add_test_categories(["llgs"])
459 def test_Hg_fails_on_another_pid(self):
460 self.build()
461 self.set_inferior_startup_launch()
462 self.Hg_fails_on_pid(1)
464 @add_test_categories(["llgs"])
465 def test_Hg_fails_on_zero_pid(self):
466 self.build()
467 self.set_inferior_startup_launch()
468 self.Hg_fails_on_pid(0)
470 @add_test_categories(["llgs"])
471 @skipIfWindows # Sometimes returns '$E37'.
472 def test_Hg_fails_on_minus_one_pid(self):
473 self.build()
474 self.set_inferior_startup_launch()
475 self.Hg_fails_on_pid(-1)
477 def Hc_then_Csignal_signals_correct_thread(self, segfault_signo):
478 # NOTE only run this one in inferior-launched mode: we can't grab inferior stdout when running attached,
479 # and the test requires getting stdout from the exe.
481 NUM_THREADS = 3
483 # Startup the inferior with three threads (main + NUM_THREADS-1 worker threads).
484 # inferior_args=["thread:print-ids"]
485 inferior_args = ["thread:segfault"]
486 for i in range(NUM_THREADS - 1):
487 # if i > 0:
488 # Give time between thread creation/segfaulting for the handler to work.
489 # inferior_args.append("sleep:1")
490 inferior_args.append("thread:new")
491 inferior_args.append("sleep:10")
493 # Launch/attach. (In our case, this should only ever be launched since
494 # we need inferior stdout/stderr).
495 procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args)
496 self.test_sequence.add_log_lines(["read packet: $c#63"], True)
497 context = self.expect_gdbremote_sequence()
499 signaled_tids = {}
500 print_thread_ids = {}
502 # Switch to each thread, deliver a signal, and verify signal delivery
503 for i in range(NUM_THREADS - 1):
504 # Run until SIGSEGV comes in.
505 self.reset_test_sequence()
506 self.test_sequence.add_log_lines(
509 "direction": "send",
510 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
511 "capture": {1: "signo", 2: "thread_id"},
514 True,
517 context = self.expect_gdbremote_sequence()
518 self.assertIsNotNone(context)
519 signo = context.get("signo")
520 self.assertEqual(int(signo, 16), segfault_signo)
522 # Ensure we haven't seen this tid yet.
523 thread_id = int(context.get("thread_id"), 16)
524 self.assertNotIn(thread_id, signaled_tids)
525 signaled_tids[thread_id] = 1
527 # Send SIGUSR1 to the thread that signaled the SIGSEGV.
528 self.reset_test_sequence()
529 self.test_sequence.add_log_lines(
531 # Set the continue thread.
532 # Set current thread.
533 "read packet: $Hc{0:x}#00".format(thread_id),
534 "send packet: $OK#00",
535 # Continue sending the signal number to the continue thread.
536 # The commented out packet is a way to do this same operation without using
537 # a $Hc (but this test is testing $Hc, so we'll stick with the former).
538 "read packet: $C{0:x}#00".format(
539 lldbutil.get_signal_number("SIGUSR1")
541 # "read packet: $vCont;C{0:x}:{1:x};c#00".format(lldbutil.get_signal_number('SIGUSR1'), thread_id),
542 # FIXME: Linux does not report the thread stop on the delivered signal (SIGUSR1 here). MacOSX debugserver does.
543 # But MacOSX debugserver isn't guaranteeing the thread the signal handler runs on, so currently its an XFAIL.
544 # Need to rectify behavior here. The linux behavior is more intuitive to me since we're essentially swapping out
545 # an about-to-be-delivered signal (for which we already sent a stop packet) to a different signal.
546 # {"direction":"send", "regex":r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture":{1:"stop_signo", 2:"stop_thread_id"} },
547 # "read packet: $c#63",
549 "type": "output_match",
550 "regex": r"^received SIGUSR1 on thread id: ([0-9a-fA-F]+)\r\nthread ([0-9a-fA-F]+): past SIGSEGV\r\n",
551 "capture": {1: "print_thread_id", 2: "post_handle_thread_id"},
554 True,
557 # Run the sequence.
558 context = self.expect_gdbremote_sequence()
559 self.assertIsNotNone(context)
561 # Ensure the stop signal is the signal we delivered.
562 # stop_signo = context.get("stop_signo")
563 # self.assertIsNotNone(stop_signo)
564 # self.assertEqual(int(stop_signo,16), lldbutil.get_signal_number('SIGUSR1'))
566 # Ensure the stop thread is the thread to which we delivered the signal.
567 # stop_thread_id = context.get("stop_thread_id")
568 # self.assertIsNotNone(stop_thread_id)
569 # self.assertEqual(int(stop_thread_id,16), thread_id)
571 # Ensure we haven't seen this thread id yet. The inferior's
572 # self-obtained thread ids are not guaranteed to match the stub
573 # tids (at least on MacOSX).
574 print_thread_id = context.get("print_thread_id")
575 self.assertIsNotNone(print_thread_id)
576 print_thread_id = int(print_thread_id, 16)
577 self.assertNotIn(print_thread_id, print_thread_ids)
579 # Now remember this print (i.e. inferior-reflected) thread id and
580 # ensure we don't hit it again.
581 print_thread_ids[print_thread_id] = 1
583 # Ensure post signal-handle thread id matches the thread that
584 # initially raised the SIGSEGV.
585 post_handle_thread_id = context.get("post_handle_thread_id")
586 self.assertIsNotNone(post_handle_thread_id)
587 post_handle_thread_id = int(post_handle_thread_id, 16)
588 self.assertEqual(post_handle_thread_id, print_thread_id)
590 @expectedFailureDarwin
591 @skipIfWindows # no SIGSEGV support
592 @expectedFailureNetBSD
593 def test_Hc_then_Csignal_signals_correct_thread_launch(self):
594 self.build()
595 self.set_inferior_startup_launch()
597 if self.platformIsDarwin():
598 # Darwin debugserver translates some signals like SIGSEGV into some gdb
599 # expectations about fixed signal numbers.
600 self.Hc_then_Csignal_signals_correct_thread(self.TARGET_EXC_BAD_ACCESS)
601 else:
602 self.Hc_then_Csignal_signals_correct_thread(
603 lldbutil.get_signal_number("SIGSEGV")
606 @skipIfWindows # No pty support to test any inferior output
607 def test_m_packet_reads_memory(self):
608 self.build()
609 self.set_inferior_startup_launch()
610 # This is the memory we will write into the inferior and then ensure we
611 # can read back with $m.
612 MEMORY_CONTENTS = "Test contents 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"
614 # Start up the inferior.
615 procs = self.prep_debug_monitor_and_inferior(
616 inferior_args=[
617 "set-message:%s" % MEMORY_CONTENTS,
618 "get-data-address-hex:g_message",
619 "sleep:5",
623 # Run the process
624 self.test_sequence.add_log_lines(
626 # Start running after initial stop.
627 "read packet: $c#63",
628 # Match output line that prints the memory address of the message buffer within the inferior.
629 # Note we require launch-only testing so we can get inferior otuput.
631 "type": "output_match",
632 "regex": self.maybe_strict_output_regex(
633 r"data address: 0x([0-9a-fA-F]+)\r\n"
635 "capture": {1: "message_address"},
637 # Now stop the inferior.
638 "read packet: {}".format(chr(3)),
639 # And wait for the stop notification.
641 "direction": "send",
642 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
643 "capture": {1: "stop_signo", 2: "stop_thread_id"},
646 True,
649 # Run the packet stream.
650 context = self.expect_gdbremote_sequence()
651 self.assertIsNotNone(context)
653 # Grab the message address.
654 self.assertIsNotNone(context.get("message_address"))
655 message_address = int(context.get("message_address"), 16)
657 # Grab contents from the inferior.
658 self.reset_test_sequence()
659 self.test_sequence.add_log_lines(
661 "read packet: $m{0:x},{1:x}#00".format(
662 message_address, len(MEMORY_CONTENTS)
665 "direction": "send",
666 "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
667 "capture": {1: "read_contents"},
670 True,
673 # Run the packet stream.
674 context = self.expect_gdbremote_sequence()
675 self.assertIsNotNone(context)
677 # Ensure what we read from inferior memory is what we wrote.
678 self.assertIsNotNone(context.get("read_contents"))
679 read_contents = seven.unhexlify(context.get("read_contents"))
680 self.assertEqual(read_contents, MEMORY_CONTENTS)
682 def test_qMemoryRegionInfo_is_supported(self):
683 self.build()
684 self.set_inferior_startup_launch()
685 # Start up the inferior.
686 procs = self.prep_debug_monitor_and_inferior()
688 # Ask if it supports $qMemoryRegionInfo.
689 self.test_sequence.add_log_lines(
690 ["read packet: $qMemoryRegionInfo#00", "send packet: $OK#00"], True
692 self.expect_gdbremote_sequence()
694 @skipIfWindows # No pty support to test any inferior output
695 def test_qMemoryRegionInfo_reports_code_address_as_executable(self):
696 self.build()
697 self.set_inferior_startup_launch()
699 # Start up the inferior.
700 procs = self.prep_debug_monitor_and_inferior(
701 inferior_args=["get-code-address-hex:hello", "sleep:5"]
704 # Run the process
705 self.test_sequence.add_log_lines(
707 # Start running after initial stop.
708 "read packet: $c#63",
709 # Match output line that prints the memory address of the message buffer within the inferior.
710 # Note we require launch-only testing so we can get inferior otuput.
712 "type": "output_match",
713 "regex": self.maybe_strict_output_regex(
714 r"code address: 0x([0-9a-fA-F]+)\r\n"
716 "capture": {1: "code_address"},
718 # Now stop the inferior.
719 "read packet: {}".format(chr(3)),
720 # And wait for the stop notification.
722 "direction": "send",
723 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
724 "capture": {1: "stop_signo", 2: "stop_thread_id"},
727 True,
730 # Run the packet stream.
731 context = self.expect_gdbremote_sequence()
732 self.assertIsNotNone(context)
734 # Grab the code address.
735 self.assertIsNotNone(context.get("code_address"))
736 code_address = int(context.get("code_address"), 16)
738 # Grab memory region info from the inferior.
739 self.reset_test_sequence()
740 self.add_query_memory_region_packets(code_address)
742 # Run the packet stream.
743 context = self.expect_gdbremote_sequence()
744 self.assertIsNotNone(context)
745 mem_region_dict = self.parse_memory_region_packet(context)
747 # Ensure there are no errors reported.
748 self.assertNotIn("error", mem_region_dict)
750 # Ensure code address is readable and executable.
751 self.assertIn("permissions", mem_region_dict)
752 self.assertIn("r", mem_region_dict["permissions"])
753 self.assertIn("x", mem_region_dict["permissions"])
755 # Ensure the start address and size encompass the address we queried.
756 self.assert_address_within_memory_region(code_address, mem_region_dict)
758 @skipIfWindows # No pty support to test any inferior output
759 def test_qMemoryRegionInfo_reports_stack_address_as_rw(self):
760 self.build()
761 self.set_inferior_startup_launch()
763 # Start up the inferior.
764 procs = self.prep_debug_monitor_and_inferior(
765 inferior_args=["get-stack-address-hex:", "sleep:5"]
768 # Run the process
769 self.test_sequence.add_log_lines(
771 # Start running after initial stop.
772 "read packet: $c#63",
773 # Match output line that prints the memory address of the message buffer within the inferior.
774 # Note we require launch-only testing so we can get inferior otuput.
776 "type": "output_match",
777 "regex": self.maybe_strict_output_regex(
778 r"stack address: 0x([0-9a-fA-F]+)\r\n"
780 "capture": {1: "stack_address"},
782 # Now stop the inferior.
783 "read packet: {}".format(chr(3)),
784 # And wait for the stop notification.
786 "direction": "send",
787 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
788 "capture": {1: "stop_signo", 2: "stop_thread_id"},
791 True,
794 # Run the packet stream.
795 context = self.expect_gdbremote_sequence()
796 self.assertIsNotNone(context)
798 # Grab the address.
799 self.assertIsNotNone(context.get("stack_address"))
800 stack_address = int(context.get("stack_address"), 16)
802 # Grab memory region info from the inferior.
803 self.reset_test_sequence()
804 self.add_query_memory_region_packets(stack_address)
806 # Run the packet stream.
807 context = self.expect_gdbremote_sequence()
808 self.assertIsNotNone(context)
809 mem_region_dict = self.parse_memory_region_packet(context)
811 # Ensure there are no errors reported.
812 self.assertNotIn("error", mem_region_dict)
814 # Ensure address is readable and executable.
815 self.assertIn("permissions", mem_region_dict)
816 self.assertIn("r", mem_region_dict["permissions"])
817 self.assertIn("w", mem_region_dict["permissions"])
819 # Ensure the start address and size encompass the address we queried.
820 self.assert_address_within_memory_region(stack_address, mem_region_dict)
822 @skipIfWindows # No pty support to test any inferior output
823 def test_qMemoryRegionInfo_reports_heap_address_as_rw(self):
824 self.build()
825 self.set_inferior_startup_launch()
827 # Start up the inferior.
828 procs = self.prep_debug_monitor_and_inferior(
829 inferior_args=["get-heap-address-hex:", "sleep:5"]
832 # Run the process
833 self.test_sequence.add_log_lines(
835 # Start running after initial stop.
836 "read packet: $c#63",
837 # Match output line that prints the memory address of the message buffer within the inferior.
838 # Note we require launch-only testing so we can get inferior otuput.
840 "type": "output_match",
841 "regex": self.maybe_strict_output_regex(
842 r"heap address: 0x([0-9a-fA-F]+)\r\n"
844 "capture": {1: "heap_address"},
846 # Now stop the inferior.
847 "read packet: {}".format(chr(3)),
848 # And wait for the stop notification.
850 "direction": "send",
851 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
852 "capture": {1: "stop_signo", 2: "stop_thread_id"},
855 True,
858 # Run the packet stream.
859 context = self.expect_gdbremote_sequence()
860 self.assertIsNotNone(context)
862 # Grab the address.
863 self.assertIsNotNone(context.get("heap_address"))
864 heap_address = int(context.get("heap_address"), 16)
866 # Grab memory region info from the inferior.
867 self.reset_test_sequence()
868 self.add_query_memory_region_packets(heap_address)
870 # Run the packet stream.
871 context = self.expect_gdbremote_sequence()
872 self.assertIsNotNone(context)
873 mem_region_dict = self.parse_memory_region_packet(context)
875 # Ensure there are no errors reported.
876 self.assertNotIn("error", mem_region_dict)
878 # Ensure address is readable and executable.
879 self.assertIn("permissions", mem_region_dict)
880 self.assertIn("r", mem_region_dict["permissions"])
881 self.assertIn("w", mem_region_dict["permissions"])
883 # Ensure the start address and size encompass the address we queried.
884 self.assert_address_within_memory_region(heap_address, mem_region_dict)
886 def breakpoint_set_and_remove_work(self, want_hardware):
887 # Start up the inferior.
888 procs = self.prep_debug_monitor_and_inferior(
889 inferior_args=[
890 "get-code-address-hex:hello",
891 "sleep:1",
892 "call-function:hello",
896 # Run the process
897 self.add_register_info_collection_packets()
898 self.add_process_info_collection_packets()
899 self.test_sequence.add_log_lines(
900 [ # Start running after initial stop.
901 "read packet: $c#63",
902 # Match output line that prints the memory address of the function call entry point.
903 # Note we require launch-only testing so we can get inferior otuput.
905 "type": "output_match",
906 "regex": self.maybe_strict_output_regex(
907 r"code address: 0x([0-9a-fA-F]+)\r\n"
909 "capture": {1: "function_address"},
911 # Now stop the inferior.
912 "read packet: {}".format(chr(3)),
913 # And wait for the stop notification.
915 "direction": "send",
916 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
917 "capture": {1: "stop_signo", 2: "stop_thread_id"},
920 True,
923 # Run the packet stream.
924 context = self.expect_gdbremote_sequence()
925 self.assertIsNotNone(context)
927 # Gather process info - we need endian of target to handle register
928 # value conversions.
929 process_info = self.parse_process_info_response(context)
930 endian = process_info.get("endian")
931 self.assertIsNotNone(endian)
933 # Gather register info entries.
934 reg_infos = self.parse_register_info_packets(context)
935 (pc_lldb_reg_index, pc_reg_info) = self.find_pc_reg_info(reg_infos)
936 self.assertIsNotNone(pc_lldb_reg_index)
937 self.assertIsNotNone(pc_reg_info)
939 # Grab the function address.
940 self.assertIsNotNone(context.get("function_address"))
941 function_address = int(context.get("function_address"), 16)
943 # Get current target architecture
944 target_arch = self.getArchitecture()
946 # Set the breakpoint.
947 if target_arch in ["arm", "arm64", "aarch64"]:
948 # TODO: Handle case when setting breakpoint in thumb code
949 BREAKPOINT_KIND = 4
950 else:
951 BREAKPOINT_KIND = 1
953 # Set default packet type to Z0 (software breakpoint)
954 z_packet_type = 0
956 # If hardware breakpoint is requested set packet type to Z1
957 if want_hardware:
958 z_packet_type = 1
960 self.reset_test_sequence()
961 self.add_set_breakpoint_packets(
962 function_address,
963 z_packet_type,
964 do_continue=True,
965 breakpoint_kind=BREAKPOINT_KIND,
968 # Run the packet stream.
969 context = self.expect_gdbremote_sequence()
970 self.assertIsNotNone(context)
972 # Verify the stop signal reported was the breakpoint signal number.
973 stop_signo = context.get("stop_signo")
974 self.assertIsNotNone(stop_signo)
975 self.assertEqual(int(stop_signo, 16), lldbutil.get_signal_number("SIGTRAP"))
977 # Ensure we did not receive any output. If the breakpoint was not set, we would
978 # see output (from a launched process with captured stdio) printing a hello, world message.
979 # That would indicate the breakpoint didn't take.
980 self.assertEqual(len(context["O_content"]), 0)
982 # Verify that the PC for the main thread is where we expect it - right at the breakpoint address.
983 # This acts as a another validation on the register reading code.
984 self.reset_test_sequence()
985 self.test_sequence.add_log_lines(
987 # Print the PC. This should match the breakpoint address.
988 "read packet: $p{0:x}#00".format(pc_lldb_reg_index),
989 # Capture $p results.
991 "direction": "send",
992 "regex": r"^\$([0-9a-fA-F]+)#",
993 "capture": {1: "p_response"},
996 True,
999 context = self.expect_gdbremote_sequence()
1000 self.assertIsNotNone(context)
1002 # Verify the PC is where we expect. Note response is in endianness of
1003 # the inferior.
1004 p_response = context.get("p_response")
1005 self.assertIsNotNone(p_response)
1007 # Convert from target endian to int.
1008 returned_pc = lldbgdbserverutils.unpack_register_hex_unsigned(
1009 endian, p_response
1011 self.assertEqual(returned_pc, function_address)
1013 # Verify that a breakpoint remove and continue gets us the expected
1014 # output.
1015 self.reset_test_sequence()
1017 # Add breakpoint remove packets
1018 self.add_remove_breakpoint_packets(
1019 function_address, z_packet_type, breakpoint_kind=BREAKPOINT_KIND
1022 self.test_sequence.add_log_lines(
1024 # Continue running.
1025 "read packet: $c#63",
1026 # We should now receive the output from the call.
1027 {"type": "output_match", "regex": r"^hello, world\r\n$"},
1028 # And wait for program completion.
1029 {"direction": "send", "regex": r"^\$W00(.*)#[0-9a-fA-F]{2}$"},
1031 True,
1034 context = self.expect_gdbremote_sequence()
1035 self.assertIsNotNone(context)
1037 @skipIfWindows # No pty support to test any inferior output
1038 def test_software_breakpoint_set_and_remove_work(self):
1039 if self.getArchitecture() == "arm":
1040 # TODO: Handle case when setting breakpoint in thumb code
1041 self.build(dictionary={"CFLAGS_EXTRAS": "-marm"})
1042 else:
1043 self.build()
1044 self.set_inferior_startup_launch()
1045 self.breakpoint_set_and_remove_work(want_hardware=False)
1047 @skipUnlessPlatform(oslist=["linux"])
1048 @skipIf(archs=no_match(["arm", "aarch64"]))
1049 def test_hardware_breakpoint_set_and_remove_work(self):
1050 if self.getArchitecture() == "arm":
1051 # TODO: Handle case when setting breakpoint in thumb code
1052 self.build(dictionary={"CFLAGS_EXTRAS": "-marm"})
1053 else:
1054 self.build()
1055 self.set_inferior_startup_launch()
1056 self.breakpoint_set_and_remove_work(want_hardware=True)
1058 def get_qSupported_dict(self, features=[]):
1059 self.build()
1060 self.set_inferior_startup_launch()
1062 # Start up the stub and start/prep the inferior.
1063 procs = self.prep_debug_monitor_and_inferior()
1064 self.add_qSupported_packets(features)
1066 # Run the packet stream.
1067 context = self.expect_gdbremote_sequence()
1068 self.assertIsNotNone(context)
1070 # Retrieve the qSupported features.
1071 return self.parse_qSupported_response(context)
1073 def test_qSupported_returns_known_stub_features(self):
1074 supported_dict = self.get_qSupported_dict()
1075 self.assertIsNotNone(supported_dict)
1076 self.assertGreater(len(supported_dict), 0)
1078 def test_qSupported_auvx(self):
1079 expected = (
1081 if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
1082 else "-"
1084 supported_dict = self.get_qSupported_dict()
1085 self.assertEqual(supported_dict.get("qXfer:auxv:read", "-"), expected)
1087 def test_qSupported_libraries_svr4(self):
1088 expected = (
1090 if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
1091 else "-"
1093 supported_dict = self.get_qSupported_dict()
1094 self.assertEqual(supported_dict.get("qXfer:libraries-svr4:read", "-"), expected)
1096 def test_qSupported_siginfo_read(self):
1097 expected = (
1098 "+" if lldbplatformutil.getPlatform() in ["freebsd", "linux"] else "-"
1100 supported_dict = self.get_qSupported_dict()
1101 self.assertEqual(supported_dict.get("qXfer:siginfo:read", "-"), expected)
1103 def test_qSupported_QPassSignals(self):
1104 expected = (
1106 if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
1107 else "-"
1109 supported_dict = self.get_qSupported_dict()
1110 self.assertEqual(supported_dict.get("QPassSignals", "-"), expected)
1112 @add_test_categories(["fork"])
1113 def test_qSupported_fork_events(self):
1114 supported_dict = self.get_qSupported_dict(["multiprocess+", "fork-events+"])
1115 self.assertEqual(supported_dict.get("multiprocess", "-"), "+")
1116 self.assertEqual(supported_dict.get("fork-events", "-"), "+")
1117 self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
1119 @add_test_categories(["fork"])
1120 def test_qSupported_fork_events_without_multiprocess(self):
1121 supported_dict = self.get_qSupported_dict(["fork-events+"])
1122 self.assertEqual(supported_dict.get("multiprocess", "-"), "-")
1123 self.assertEqual(supported_dict.get("fork-events", "-"), "-")
1124 self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
1126 @add_test_categories(["fork"])
1127 def test_qSupported_vfork_events(self):
1128 supported_dict = self.get_qSupported_dict(["multiprocess+", "vfork-events+"])
1129 self.assertEqual(supported_dict.get("multiprocess", "-"), "+")
1130 self.assertEqual(supported_dict.get("fork-events", "-"), "-")
1131 self.assertEqual(supported_dict.get("vfork-events", "-"), "+")
1133 @add_test_categories(["fork"])
1134 def test_qSupported_vfork_events_without_multiprocess(self):
1135 supported_dict = self.get_qSupported_dict(["vfork-events+"])
1136 self.assertEqual(supported_dict.get("multiprocess", "-"), "-")
1137 self.assertEqual(supported_dict.get("fork-events", "-"), "-")
1138 self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
1140 # We need to be able to self.runCmd to get cpuinfo,
1141 # which is not possible when using a remote platform.
1142 @skipIfRemote
1143 def test_qSupported_memory_tagging(self):
1144 supported_dict = self.get_qSupported_dict()
1145 self.assertEqual(
1146 supported_dict.get("memory-tagging", "-"),
1147 "+" if self.isAArch64MTE() else "-",
1150 @skipIfWindows # No pty support to test any inferior output
1151 def test_written_M_content_reads_back_correctly(self):
1152 self.build()
1153 self.set_inferior_startup_launch()
1155 TEST_MESSAGE = "Hello, memory"
1157 # Start up the stub and start/prep the inferior.
1158 procs = self.prep_debug_monitor_and_inferior(
1159 inferior_args=[
1160 "set-message:xxxxxxxxxxxxxX",
1161 "get-data-address-hex:g_message",
1162 "sleep:1",
1163 "print-message:",
1166 self.test_sequence.add_log_lines(
1168 # Start running after initial stop.
1169 "read packet: $c#63",
1170 # Match output line that prints the memory address of the message buffer within the inferior.
1171 # Note we require launch-only testing so we can get inferior otuput.
1173 "type": "output_match",
1174 "regex": self.maybe_strict_output_regex(
1175 r"data address: 0x([0-9a-fA-F]+)\r\n"
1177 "capture": {1: "message_address"},
1179 # Now stop the inferior.
1180 "read packet: {}".format(chr(3)),
1181 # And wait for the stop notification.
1183 "direction": "send",
1184 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
1185 "capture": {1: "stop_signo", 2: "stop_thread_id"},
1188 True,
1190 context = self.expect_gdbremote_sequence()
1191 self.assertIsNotNone(context)
1193 # Grab the message address.
1194 self.assertIsNotNone(context.get("message_address"))
1195 message_address = int(context.get("message_address"), 16)
1197 # Hex-encode the test message, adding null termination.
1198 hex_encoded_message = seven.hexlify(TEST_MESSAGE)
1200 # Write the message to the inferior. Verify that we can read it with the hex-encoded (m)
1201 # and binary (x) memory read packets.
1202 self.reset_test_sequence()
1203 self.test_sequence.add_log_lines(
1205 "read packet: $M{0:x},{1:x}:{2}#00".format(
1206 message_address, len(TEST_MESSAGE), hex_encoded_message
1208 "send packet: $OK#00",
1209 "read packet: $m{0:x},{1:x}#00".format(
1210 message_address, len(TEST_MESSAGE)
1212 "send packet: ${0}#00".format(hex_encoded_message),
1213 "read packet: $x{0:x},{1:x}#00".format(
1214 message_address, len(TEST_MESSAGE)
1216 "send packet: ${0}#00".format(TEST_MESSAGE),
1217 "read packet: $m{0:x},4#00".format(message_address),
1218 "send packet: ${0}#00".format(hex_encoded_message[0:8]),
1219 "read packet: $x{0:x},4#00".format(message_address),
1220 "send packet: ${0}#00".format(TEST_MESSAGE[0:4]),
1221 "read packet: $c#63",
1223 "type": "output_match",
1224 "regex": r"^message: (.+)\r\n$",
1225 "capture": {1: "printed_message"},
1227 "send packet: $W00#00",
1229 True,
1231 context = self.expect_gdbremote_sequence()
1232 self.assertIsNotNone(context)
1234 # Ensure what we read from inferior memory is what we wrote.
1235 printed_message = context.get("printed_message")
1236 self.assertIsNotNone(printed_message)
1237 self.assertEqual(printed_message, TEST_MESSAGE + "X")
1239 # Note: as of this moment, a hefty number of the GPR writes are failing with E32 (everything except rax-rdx, rdi, rsi, rbp).
1240 # Come back to this. I have the test rigged to verify that at least some
1241 # of the bit-flip writes work.
1242 def test_P_writes_all_gpr_registers(self):
1243 self.build()
1244 self.set_inferior_startup_launch()
1246 # Start inferior debug session, grab all register info.
1247 procs = self.prep_debug_monitor_and_inferior(inferior_args=["sleep:2"])
1248 self.add_register_info_collection_packets()
1249 self.add_process_info_collection_packets()
1251 context = self.expect_gdbremote_sequence()
1252 self.assertIsNotNone(context)
1254 # Process register infos.
1255 reg_infos = self.parse_register_info_packets(context)
1256 self.assertIsNotNone(reg_infos)
1257 self.add_lldb_register_index(reg_infos)
1259 # Process endian.
1260 process_info = self.parse_process_info_response(context)
1261 endian = process_info.get("endian")
1262 self.assertIsNotNone(endian)
1264 # Pull out the register infos that we think we can bit flip
1265 # successfully,.
1266 gpr_reg_infos = [
1267 reg_info
1268 for reg_info in reg_infos
1269 if self.is_bit_flippable_register(reg_info)
1271 self.assertGreater(len(gpr_reg_infos), 0)
1273 # Write flipped bit pattern of existing value to each register.
1274 (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
1275 gpr_reg_infos, endian
1277 self.trace(
1278 "successful writes: {}, failed writes: {}".format(
1279 successful_writes, failed_writes
1282 self.assertGreater(successful_writes, 0)
1284 # Note: as of this moment, a hefty number of the GPR writes are failing
1285 # with E32 (everything except rax-rdx, rdi, rsi, rbp).
1286 @skipIfWindows
1287 def test_P_and_p_thread_suffix_work(self):
1288 self.build()
1289 self.set_inferior_startup_launch()
1291 # Startup the inferior with three threads.
1292 _, threads = self.launch_with_threads(3)
1294 self.reset_test_sequence()
1295 self.add_thread_suffix_request_packets()
1296 self.add_register_info_collection_packets()
1297 self.add_process_info_collection_packets()
1299 context = self.expect_gdbremote_sequence()
1300 self.assertIsNotNone(context)
1302 process_info = self.parse_process_info_response(context)
1303 self.assertIsNotNone(process_info)
1304 endian = process_info.get("endian")
1305 self.assertIsNotNone(endian)
1307 reg_infos = self.parse_register_info_packets(context)
1308 self.assertIsNotNone(reg_infos)
1309 self.add_lldb_register_index(reg_infos)
1311 reg_index = self.select_modifiable_register(reg_infos)
1312 self.assertIsNotNone(reg_index)
1313 reg_byte_size = int(reg_infos[reg_index]["bitsize"]) // 8
1314 self.assertGreater(reg_byte_size, 0)
1316 expected_reg_values = []
1317 register_increment = 1
1318 next_value = None
1320 # Set the same register in each of 3 threads to a different value.
1321 # Verify each one has the unique value.
1322 for thread in threads:
1323 # If we don't have a next value yet, start it with the initial read
1324 # value + 1
1325 if not next_value:
1326 # Read pre-existing register value.
1327 self.reset_test_sequence()
1328 self.test_sequence.add_log_lines(
1330 "read packet: $p{0:x};thread:{1:x}#00".format(
1331 reg_index, thread
1334 "direction": "send",
1335 "regex": r"^\$([0-9a-fA-F]+)#",
1336 "capture": {1: "p_response"},
1339 True,
1341 context = self.expect_gdbremote_sequence()
1342 self.assertIsNotNone(context)
1344 # Set the next value to use for writing as the increment plus
1345 # current value.
1346 p_response = context.get("p_response")
1347 self.assertIsNotNone(p_response)
1348 next_value = lldbgdbserverutils.unpack_register_hex_unsigned(
1349 endian, p_response
1352 # Set new value using P and thread suffix.
1353 self.reset_test_sequence()
1354 self.test_sequence.add_log_lines(
1356 "read packet: $P{0:x}={1};thread:{2:x}#00".format(
1357 reg_index,
1358 lldbgdbserverutils.pack_register_hex(
1359 endian, next_value, byte_size=reg_byte_size
1361 thread,
1363 "send packet: $OK#00",
1365 True,
1367 context = self.expect_gdbremote_sequence()
1368 self.assertIsNotNone(context)
1370 # Save the value we set.
1371 expected_reg_values.append(next_value)
1373 # Increment value for next thread to use (we want them all
1374 # different so we can verify they wrote to each thread correctly
1375 # next.)
1376 next_value += register_increment
1378 # Revisit each thread and verify they have the expected value set for
1379 # the register we wrote.
1380 thread_index = 0
1381 for thread in threads:
1382 # Read pre-existing register value.
1383 self.reset_test_sequence()
1384 self.test_sequence.add_log_lines(
1386 "read packet: $p{0:x};thread:{1:x}#00".format(reg_index, thread),
1388 "direction": "send",
1389 "regex": r"^\$([0-9a-fA-F]+)#",
1390 "capture": {1: "p_response"},
1393 True,
1395 context = self.expect_gdbremote_sequence()
1396 self.assertIsNotNone(context)
1398 # Get the register value.
1399 p_response = context.get("p_response")
1400 self.assertIsNotNone(p_response)
1401 read_value = lldbgdbserverutils.unpack_register_hex_unsigned(
1402 endian, p_response
1405 # Make sure we read back what we wrote.
1406 self.assertEqual(read_value, expected_reg_values[thread_index])
1407 thread_index += 1
1409 @skipUnlessPlatform(oslist=["freebsd", "linux"])
1410 @add_test_categories(["llgs"])
1411 def test_qXfer_siginfo_read(self):
1412 self.build()
1413 self.set_inferior_startup_launch()
1414 procs = self.prep_debug_monitor_and_inferior(
1415 inferior_args=["thread:segfault", "thread:new", "sleep:10"]
1417 self.test_sequence.add_log_lines(["read packet: $c#63"], True)
1418 self.expect_gdbremote_sequence()
1420 # Run until SIGSEGV comes in.
1421 self.reset_test_sequence()
1422 self.test_sequence.add_log_lines(
1425 "direction": "send",
1426 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
1427 "capture": {1: "signo", 2: "thread_id"},
1430 True,
1433 # Figure out which thread crashed.
1434 context = self.expect_gdbremote_sequence()
1435 self.assertIsNotNone(context)
1436 self.assertEqual(
1437 int(context["signo"], 16), lldbutil.get_signal_number("SIGSEGV")
1439 crashing_thread = int(context["thread_id"], 16)
1441 # Grab siginfo for the crashing thread.
1442 self.reset_test_sequence()
1443 self.add_process_info_collection_packets()
1444 self.test_sequence.add_log_lines(
1446 "read packet: $Hg{:x}#00".format(crashing_thread),
1447 "send packet: $OK#00",
1448 "read packet: $qXfer:siginfo:read::0,80:#00",
1450 "direction": "send",
1451 "regex": re.compile(
1452 r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL
1454 "capture": {1: "response_type", 2: "content_raw"},
1457 True,
1459 context = self.expect_gdbremote_sequence()
1460 self.assertIsNotNone(context)
1462 # Ensure we end up with all data in one packet.
1463 self.assertEqual(context.get("response_type"), "l")
1465 # Decode binary data.
1466 content_raw = context.get("content_raw")
1467 self.assertIsNotNone(content_raw)
1468 content = self.decode_gdbremote_binary(content_raw).encode("latin1")
1470 # Decode siginfo_t.
1471 process_info = self.parse_process_info_response(context)
1472 pad = ""
1473 if process_info["ptrsize"] == "8":
1474 pad = "i"
1475 signo_idx = 0
1476 errno_idx = 1
1477 code_idx = 2
1478 addr_idx = -1
1479 SEGV_MAPERR = 1
1480 if process_info["ostype"] == "linux":
1481 # si_signo, si_errno, si_code, [pad], _sifields._sigfault.si_addr
1482 format_str = "iii{}P".format(pad)
1483 elif process_info["ostype"].startswith("freebsd"):
1484 # si_signo, si_errno, si_code, si_pid, si_uid, si_status, si_addr
1485 format_str = "iiiiiiP"
1486 elif process_info["ostype"].startswith("netbsd"):
1487 # _signo, _code, _errno, [pad], _reason._fault._addr
1488 format_str = "iii{}P".format(pad)
1489 errno_idx = 2
1490 code_idx = 1
1491 else:
1492 assert False, "unknown ostype"
1494 decoder = struct.Struct(format_str)
1495 decoded = decoder.unpack(content[: decoder.size])
1496 self.assertEqual(decoded[signo_idx], lldbutil.get_signal_number("SIGSEGV"))
1497 self.assertEqual(decoded[errno_idx], 0) # si_errno
1498 self.assertEqual(decoded[code_idx], SEGV_MAPERR) # si_code
1499 self.assertEqual(decoded[addr_idx], 0) # si_addr