Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / test / API / tools / lldb-server / TestLldbGdbServer.py
blobb6366d7fd170f5e6c5bcefcb9d2fba50eefe4952
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.assertTrue(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.assertTrue(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 def test_Hg_fails_on_minus_one_pid(self):
472 self.build()
473 self.set_inferior_startup_launch()
474 self.Hg_fails_on_pid(-1)
476 def Hc_then_Csignal_signals_correct_thread(self, segfault_signo):
477 # NOTE only run this one in inferior-launched mode: we can't grab inferior stdout when running attached,
478 # and the test requires getting stdout from the exe.
480 NUM_THREADS = 3
482 # Startup the inferior with three threads (main + NUM_THREADS-1 worker threads).
483 # inferior_args=["thread:print-ids"]
484 inferior_args = ["thread:segfault"]
485 for i in range(NUM_THREADS - 1):
486 # if i > 0:
487 # Give time between thread creation/segfaulting for the handler to work.
488 # inferior_args.append("sleep:1")
489 inferior_args.append("thread:new")
490 inferior_args.append("sleep:10")
492 # Launch/attach. (In our case, this should only ever be launched since
493 # we need inferior stdout/stderr).
494 procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args)
495 self.test_sequence.add_log_lines(["read packet: $c#63"], True)
496 context = self.expect_gdbremote_sequence()
498 signaled_tids = {}
499 print_thread_ids = {}
501 # Switch to each thread, deliver a signal, and verify signal delivery
502 for i in range(NUM_THREADS - 1):
503 # Run until SIGSEGV comes in.
504 self.reset_test_sequence()
505 self.test_sequence.add_log_lines(
508 "direction": "send",
509 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
510 "capture": {1: "signo", 2: "thread_id"},
513 True,
516 context = self.expect_gdbremote_sequence()
517 self.assertIsNotNone(context)
518 signo = context.get("signo")
519 self.assertEqual(int(signo, 16), segfault_signo)
521 # Ensure we haven't seen this tid yet.
522 thread_id = int(context.get("thread_id"), 16)
523 self.assertNotIn(thread_id, signaled_tids)
524 signaled_tids[thread_id] = 1
526 # Send SIGUSR1 to the thread that signaled the SIGSEGV.
527 self.reset_test_sequence()
528 self.test_sequence.add_log_lines(
530 # Set the continue thread.
531 # Set current thread.
532 "read packet: $Hc{0:x}#00".format(thread_id),
533 "send packet: $OK#00",
534 # Continue sending the signal number to the continue thread.
535 # The commented out packet is a way to do this same operation without using
536 # a $Hc (but this test is testing $Hc, so we'll stick with the former).
537 "read packet: $C{0:x}#00".format(
538 lldbutil.get_signal_number("SIGUSR1")
540 # "read packet: $vCont;C{0:x}:{1:x};c#00".format(lldbutil.get_signal_number('SIGUSR1'), thread_id),
541 # FIXME: Linux does not report the thread stop on the delivered signal (SIGUSR1 here). MacOSX debugserver does.
542 # But MacOSX debugserver isn't guaranteeing the thread the signal handler runs on, so currently its an XFAIL.
543 # Need to rectify behavior here. The linux behavior is more intuitive to me since we're essentially swapping out
544 # an about-to-be-delivered signal (for which we already sent a stop packet) to a different signal.
545 # {"direction":"send", "regex":r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture":{1:"stop_signo", 2:"stop_thread_id"} },
546 # "read packet: $c#63",
548 "type": "output_match",
549 "regex": r"^received SIGUSR1 on thread id: ([0-9a-fA-F]+)\r\nthread ([0-9a-fA-F]+): past SIGSEGV\r\n",
550 "capture": {1: "print_thread_id", 2: "post_handle_thread_id"},
553 True,
556 # Run the sequence.
557 context = self.expect_gdbremote_sequence()
558 self.assertIsNotNone(context)
560 # Ensure the stop signal is the signal we delivered.
561 # stop_signo = context.get("stop_signo")
562 # self.assertIsNotNone(stop_signo)
563 # self.assertEquals(int(stop_signo,16), lldbutil.get_signal_number('SIGUSR1'))
565 # Ensure the stop thread is the thread to which we delivered the signal.
566 # stop_thread_id = context.get("stop_thread_id")
567 # self.assertIsNotNone(stop_thread_id)
568 # self.assertEquals(int(stop_thread_id,16), thread_id)
570 # Ensure we haven't seen this thread id yet. The inferior's
571 # self-obtained thread ids are not guaranteed to match the stub
572 # tids (at least on MacOSX).
573 print_thread_id = context.get("print_thread_id")
574 self.assertIsNotNone(print_thread_id)
575 print_thread_id = int(print_thread_id, 16)
576 self.assertNotIn(print_thread_id, print_thread_ids)
578 # Now remember this print (i.e. inferior-reflected) thread id and
579 # ensure we don't hit it again.
580 print_thread_ids[print_thread_id] = 1
582 # Ensure post signal-handle thread id matches the thread that
583 # initially raised the SIGSEGV.
584 post_handle_thread_id = context.get("post_handle_thread_id")
585 self.assertIsNotNone(post_handle_thread_id)
586 post_handle_thread_id = int(post_handle_thread_id, 16)
587 self.assertEqual(post_handle_thread_id, print_thread_id)
589 @expectedFailureDarwin
590 @skipIfWindows # no SIGSEGV support
591 @expectedFailureNetBSD
592 def test_Hc_then_Csignal_signals_correct_thread_launch(self):
593 self.build()
594 self.set_inferior_startup_launch()
596 if self.platformIsDarwin():
597 # Darwin debugserver translates some signals like SIGSEGV into some gdb
598 # expectations about fixed signal numbers.
599 self.Hc_then_Csignal_signals_correct_thread(self.TARGET_EXC_BAD_ACCESS)
600 else:
601 self.Hc_then_Csignal_signals_correct_thread(
602 lldbutil.get_signal_number("SIGSEGV")
605 @skipIfWindows # No pty support to test any inferior output
606 def test_m_packet_reads_memory(self):
607 self.build()
608 self.set_inferior_startup_launch()
609 # This is the memory we will write into the inferior and then ensure we
610 # can read back with $m.
611 MEMORY_CONTENTS = "Test contents 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"
613 # Start up the inferior.
614 procs = self.prep_debug_monitor_and_inferior(
615 inferior_args=[
616 "set-message:%s" % MEMORY_CONTENTS,
617 "get-data-address-hex:g_message",
618 "sleep:5",
622 # Run the process
623 self.test_sequence.add_log_lines(
625 # Start running after initial stop.
626 "read packet: $c#63",
627 # Match output line that prints the memory address of the message buffer within the inferior.
628 # Note we require launch-only testing so we can get inferior otuput.
630 "type": "output_match",
631 "regex": self.maybe_strict_output_regex(
632 r"data address: 0x([0-9a-fA-F]+)\r\n"
634 "capture": {1: "message_address"},
636 # Now stop the inferior.
637 "read packet: {}".format(chr(3)),
638 # And wait for the stop notification.
640 "direction": "send",
641 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
642 "capture": {1: "stop_signo", 2: "stop_thread_id"},
645 True,
648 # Run the packet stream.
649 context = self.expect_gdbremote_sequence()
650 self.assertIsNotNone(context)
652 # Grab the message address.
653 self.assertIsNotNone(context.get("message_address"))
654 message_address = int(context.get("message_address"), 16)
656 # Grab contents from the inferior.
657 self.reset_test_sequence()
658 self.test_sequence.add_log_lines(
660 "read packet: $m{0:x},{1:x}#00".format(
661 message_address, len(MEMORY_CONTENTS)
664 "direction": "send",
665 "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
666 "capture": {1: "read_contents"},
669 True,
672 # Run the packet stream.
673 context = self.expect_gdbremote_sequence()
674 self.assertIsNotNone(context)
676 # Ensure what we read from inferior memory is what we wrote.
677 self.assertIsNotNone(context.get("read_contents"))
678 read_contents = seven.unhexlify(context.get("read_contents"))
679 self.assertEqual(read_contents, MEMORY_CONTENTS)
681 def test_qMemoryRegionInfo_is_supported(self):
682 self.build()
683 self.set_inferior_startup_launch()
684 # Start up the inferior.
685 procs = self.prep_debug_monitor_and_inferior()
687 # Ask if it supports $qMemoryRegionInfo.
688 self.test_sequence.add_log_lines(
689 ["read packet: $qMemoryRegionInfo#00", "send packet: $OK#00"], True
691 self.expect_gdbremote_sequence()
693 @skipIfWindows # No pty support to test any inferior output
694 def test_qMemoryRegionInfo_reports_code_address_as_executable(self):
695 self.build()
696 self.set_inferior_startup_launch()
698 # Start up the inferior.
699 procs = self.prep_debug_monitor_and_inferior(
700 inferior_args=["get-code-address-hex:hello", "sleep:5"]
703 # Run the process
704 self.test_sequence.add_log_lines(
706 # Start running after initial stop.
707 "read packet: $c#63",
708 # Match output line that prints the memory address of the message buffer within the inferior.
709 # Note we require launch-only testing so we can get inferior otuput.
711 "type": "output_match",
712 "regex": self.maybe_strict_output_regex(
713 r"code address: 0x([0-9a-fA-F]+)\r\n"
715 "capture": {1: "code_address"},
717 # Now stop the inferior.
718 "read packet: {}".format(chr(3)),
719 # And wait for the stop notification.
721 "direction": "send",
722 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
723 "capture": {1: "stop_signo", 2: "stop_thread_id"},
726 True,
729 # Run the packet stream.
730 context = self.expect_gdbremote_sequence()
731 self.assertIsNotNone(context)
733 # Grab the code address.
734 self.assertIsNotNone(context.get("code_address"))
735 code_address = int(context.get("code_address"), 16)
737 # Grab memory region info from the inferior.
738 self.reset_test_sequence()
739 self.add_query_memory_region_packets(code_address)
741 # Run the packet stream.
742 context = self.expect_gdbremote_sequence()
743 self.assertIsNotNone(context)
744 mem_region_dict = self.parse_memory_region_packet(context)
746 # Ensure there are no errors reported.
747 self.assertNotIn("error", mem_region_dict)
749 # Ensure code address is readable and executable.
750 self.assertIn("permissions", mem_region_dict)
751 self.assertIn("r", mem_region_dict["permissions"])
752 self.assertIn("x", mem_region_dict["permissions"])
754 # Ensure the start address and size encompass the address we queried.
755 self.assert_address_within_memory_region(code_address, mem_region_dict)
757 @skipIfWindows # No pty support to test any inferior output
758 def test_qMemoryRegionInfo_reports_stack_address_as_rw(self):
759 self.build()
760 self.set_inferior_startup_launch()
762 # Start up the inferior.
763 procs = self.prep_debug_monitor_and_inferior(
764 inferior_args=["get-stack-address-hex:", "sleep:5"]
767 # Run the process
768 self.test_sequence.add_log_lines(
770 # Start running after initial stop.
771 "read packet: $c#63",
772 # Match output line that prints the memory address of the message buffer within the inferior.
773 # Note we require launch-only testing so we can get inferior otuput.
775 "type": "output_match",
776 "regex": self.maybe_strict_output_regex(
777 r"stack address: 0x([0-9a-fA-F]+)\r\n"
779 "capture": {1: "stack_address"},
781 # Now stop the inferior.
782 "read packet: {}".format(chr(3)),
783 # And wait for the stop notification.
785 "direction": "send",
786 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
787 "capture": {1: "stop_signo", 2: "stop_thread_id"},
790 True,
793 # Run the packet stream.
794 context = self.expect_gdbremote_sequence()
795 self.assertIsNotNone(context)
797 # Grab the address.
798 self.assertIsNotNone(context.get("stack_address"))
799 stack_address = int(context.get("stack_address"), 16)
801 # Grab memory region info from the inferior.
802 self.reset_test_sequence()
803 self.add_query_memory_region_packets(stack_address)
805 # Run the packet stream.
806 context = self.expect_gdbremote_sequence()
807 self.assertIsNotNone(context)
808 mem_region_dict = self.parse_memory_region_packet(context)
810 # Ensure there are no errors reported.
811 self.assertNotIn("error", mem_region_dict)
813 # Ensure address is readable and executable.
814 self.assertIn("permissions", mem_region_dict)
815 self.assertIn("r", mem_region_dict["permissions"])
816 self.assertIn("w", mem_region_dict["permissions"])
818 # Ensure the start address and size encompass the address we queried.
819 self.assert_address_within_memory_region(stack_address, mem_region_dict)
821 @skipIfWindows # No pty support to test any inferior output
822 def test_qMemoryRegionInfo_reports_heap_address_as_rw(self):
823 self.build()
824 self.set_inferior_startup_launch()
826 # Start up the inferior.
827 procs = self.prep_debug_monitor_and_inferior(
828 inferior_args=["get-heap-address-hex:", "sleep:5"]
831 # Run the process
832 self.test_sequence.add_log_lines(
834 # Start running after initial stop.
835 "read packet: $c#63",
836 # Match output line that prints the memory address of the message buffer within the inferior.
837 # Note we require launch-only testing so we can get inferior otuput.
839 "type": "output_match",
840 "regex": self.maybe_strict_output_regex(
841 r"heap address: 0x([0-9a-fA-F]+)\r\n"
843 "capture": {1: "heap_address"},
845 # Now stop the inferior.
846 "read packet: {}".format(chr(3)),
847 # And wait for the stop notification.
849 "direction": "send",
850 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
851 "capture": {1: "stop_signo", 2: "stop_thread_id"},
854 True,
857 # Run the packet stream.
858 context = self.expect_gdbremote_sequence()
859 self.assertIsNotNone(context)
861 # Grab the address.
862 self.assertIsNotNone(context.get("heap_address"))
863 heap_address = int(context.get("heap_address"), 16)
865 # Grab memory region info from the inferior.
866 self.reset_test_sequence()
867 self.add_query_memory_region_packets(heap_address)
869 # Run the packet stream.
870 context = self.expect_gdbremote_sequence()
871 self.assertIsNotNone(context)
872 mem_region_dict = self.parse_memory_region_packet(context)
874 # Ensure there are no errors reported.
875 self.assertNotIn("error", mem_region_dict)
877 # Ensure address is readable and executable.
878 self.assertIn("permissions", mem_region_dict)
879 self.assertIn("r", mem_region_dict["permissions"])
880 self.assertIn("w", mem_region_dict["permissions"])
882 # Ensure the start address and size encompass the address we queried.
883 self.assert_address_within_memory_region(heap_address, mem_region_dict)
885 def breakpoint_set_and_remove_work(self, want_hardware):
886 # Start up the inferior.
887 procs = self.prep_debug_monitor_and_inferior(
888 inferior_args=[
889 "get-code-address-hex:hello",
890 "sleep:1",
891 "call-function:hello",
895 # Run the process
896 self.add_register_info_collection_packets()
897 self.add_process_info_collection_packets()
898 self.test_sequence.add_log_lines(
899 [ # Start running after initial stop.
900 "read packet: $c#63",
901 # Match output line that prints the memory address of the function call entry point.
902 # Note we require launch-only testing so we can get inferior otuput.
904 "type": "output_match",
905 "regex": self.maybe_strict_output_regex(
906 r"code address: 0x([0-9a-fA-F]+)\r\n"
908 "capture": {1: "function_address"},
910 # Now stop the inferior.
911 "read packet: {}".format(chr(3)),
912 # And wait for the stop notification.
914 "direction": "send",
915 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
916 "capture": {1: "stop_signo", 2: "stop_thread_id"},
919 True,
922 # Run the packet stream.
923 context = self.expect_gdbremote_sequence()
924 self.assertIsNotNone(context)
926 # Gather process info - we need endian of target to handle register
927 # value conversions.
928 process_info = self.parse_process_info_response(context)
929 endian = process_info.get("endian")
930 self.assertIsNotNone(endian)
932 # Gather register info entries.
933 reg_infos = self.parse_register_info_packets(context)
934 (pc_lldb_reg_index, pc_reg_info) = self.find_pc_reg_info(reg_infos)
935 self.assertIsNotNone(pc_lldb_reg_index)
936 self.assertIsNotNone(pc_reg_info)
938 # Grab the function address.
939 self.assertIsNotNone(context.get("function_address"))
940 function_address = int(context.get("function_address"), 16)
942 # Get current target architecture
943 target_arch = self.getArchitecture()
945 # Set the breakpoint.
946 if target_arch in ["arm", "arm64", "aarch64"]:
947 # TODO: Handle case when setting breakpoint in thumb code
948 BREAKPOINT_KIND = 4
949 else:
950 BREAKPOINT_KIND = 1
952 # Set default packet type to Z0 (software breakpoint)
953 z_packet_type = 0
955 # If hardware breakpoint is requested set packet type to Z1
956 if want_hardware == True:
957 z_packet_type = 1
959 self.reset_test_sequence()
960 self.add_set_breakpoint_packets(
961 function_address,
962 z_packet_type,
963 do_continue=True,
964 breakpoint_kind=BREAKPOINT_KIND,
967 # Run the packet stream.
968 context = self.expect_gdbremote_sequence()
969 self.assertIsNotNone(context)
971 # Verify the stop signal reported was the breakpoint signal number.
972 stop_signo = context.get("stop_signo")
973 self.assertIsNotNone(stop_signo)
974 self.assertEqual(int(stop_signo, 16), lldbutil.get_signal_number("SIGTRAP"))
976 # Ensure we did not receive any output. If the breakpoint was not set, we would
977 # see output (from a launched process with captured stdio) printing a hello, world message.
978 # That would indicate the breakpoint didn't take.
979 self.assertEqual(len(context["O_content"]), 0)
981 # Verify that the PC for the main thread is where we expect it - right at the breakpoint address.
982 # This acts as a another validation on the register reading code.
983 self.reset_test_sequence()
984 self.test_sequence.add_log_lines(
986 # Print the PC. This should match the breakpoint address.
987 "read packet: $p{0:x}#00".format(pc_lldb_reg_index),
988 # Capture $p results.
990 "direction": "send",
991 "regex": r"^\$([0-9a-fA-F]+)#",
992 "capture": {1: "p_response"},
995 True,
998 context = self.expect_gdbremote_sequence()
999 self.assertIsNotNone(context)
1001 # Verify the PC is where we expect. Note response is in endianness of
1002 # the inferior.
1003 p_response = context.get("p_response")
1004 self.assertIsNotNone(p_response)
1006 # Convert from target endian to int.
1007 returned_pc = lldbgdbserverutils.unpack_register_hex_unsigned(
1008 endian, p_response
1010 self.assertEqual(returned_pc, function_address)
1012 # Verify that a breakpoint remove and continue gets us the expected
1013 # output.
1014 self.reset_test_sequence()
1016 # Add breakpoint remove packets
1017 self.add_remove_breakpoint_packets(
1018 function_address, z_packet_type, breakpoint_kind=BREAKPOINT_KIND
1021 self.test_sequence.add_log_lines(
1023 # Continue running.
1024 "read packet: $c#63",
1025 # We should now receive the output from the call.
1026 {"type": "output_match", "regex": r"^hello, world\r\n$"},
1027 # And wait for program completion.
1028 {"direction": "send", "regex": r"^\$W00(.*)#[0-9a-fA-F]{2}$"},
1030 True,
1033 context = self.expect_gdbremote_sequence()
1034 self.assertIsNotNone(context)
1036 @skipIfWindows # No pty support to test any inferior output
1037 def test_software_breakpoint_set_and_remove_work(self):
1038 if self.getArchitecture() == "arm":
1039 # TODO: Handle case when setting breakpoint in thumb code
1040 self.build(dictionary={"CFLAGS_EXTRAS": "-marm"})
1041 else:
1042 self.build()
1043 self.set_inferior_startup_launch()
1044 self.breakpoint_set_and_remove_work(want_hardware=False)
1046 @skipUnlessPlatform(oslist=["linux"])
1047 @skipIf(archs=no_match(["arm", "aarch64"]))
1048 def test_hardware_breakpoint_set_and_remove_work(self):
1049 if self.getArchitecture() == "arm":
1050 # TODO: Handle case when setting breakpoint in thumb code
1051 self.build(dictionary={"CFLAGS_EXTRAS": "-marm"})
1052 else:
1053 self.build()
1054 self.set_inferior_startup_launch()
1055 self.breakpoint_set_and_remove_work(want_hardware=True)
1057 def get_qSupported_dict(self, features=[]):
1058 self.build()
1059 self.set_inferior_startup_launch()
1061 # Start up the stub and start/prep the inferior.
1062 procs = self.prep_debug_monitor_and_inferior()
1063 self.add_qSupported_packets(features)
1065 # Run the packet stream.
1066 context = self.expect_gdbremote_sequence()
1067 self.assertIsNotNone(context)
1069 # Retrieve the qSupported features.
1070 return self.parse_qSupported_response(context)
1072 def test_qSupported_returns_known_stub_features(self):
1073 supported_dict = self.get_qSupported_dict()
1074 self.assertIsNotNone(supported_dict)
1075 self.assertTrue(len(supported_dict) > 0)
1077 def test_qSupported_auvx(self):
1078 expected = (
1080 if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
1081 else "-"
1083 supported_dict = self.get_qSupported_dict()
1084 self.assertEqual(supported_dict.get("qXfer:auxv:read", "-"), expected)
1086 def test_qSupported_libraries_svr4(self):
1087 expected = (
1089 if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
1090 else "-"
1092 supported_dict = self.get_qSupported_dict()
1093 self.assertEqual(supported_dict.get("qXfer:libraries-svr4:read", "-"), expected)
1095 def test_qSupported_siginfo_read(self):
1096 expected = (
1097 "+" if lldbplatformutil.getPlatform() in ["freebsd", "linux"] else "-"
1099 supported_dict = self.get_qSupported_dict()
1100 self.assertEqual(supported_dict.get("qXfer:siginfo:read", "-"), expected)
1102 def test_qSupported_QPassSignals(self):
1103 expected = (
1105 if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"]
1106 else "-"
1108 supported_dict = self.get_qSupported_dict()
1109 self.assertEqual(supported_dict.get("QPassSignals", "-"), expected)
1111 @add_test_categories(["fork"])
1112 def test_qSupported_fork_events(self):
1113 supported_dict = self.get_qSupported_dict(["multiprocess+", "fork-events+"])
1114 self.assertEqual(supported_dict.get("multiprocess", "-"), "+")
1115 self.assertEqual(supported_dict.get("fork-events", "-"), "+")
1116 self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
1118 @add_test_categories(["fork"])
1119 def test_qSupported_fork_events_without_multiprocess(self):
1120 supported_dict = self.get_qSupported_dict(["fork-events+"])
1121 self.assertEqual(supported_dict.get("multiprocess", "-"), "-")
1122 self.assertEqual(supported_dict.get("fork-events", "-"), "-")
1123 self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
1125 @add_test_categories(["fork"])
1126 def test_qSupported_vfork_events(self):
1127 supported_dict = self.get_qSupported_dict(["multiprocess+", "vfork-events+"])
1128 self.assertEqual(supported_dict.get("multiprocess", "-"), "+")
1129 self.assertEqual(supported_dict.get("fork-events", "-"), "-")
1130 self.assertEqual(supported_dict.get("vfork-events", "-"), "+")
1132 @add_test_categories(["fork"])
1133 def test_qSupported_vfork_events_without_multiprocess(self):
1134 supported_dict = self.get_qSupported_dict(["vfork-events+"])
1135 self.assertEqual(supported_dict.get("multiprocess", "-"), "-")
1136 self.assertEqual(supported_dict.get("fork-events", "-"), "-")
1137 self.assertEqual(supported_dict.get("vfork-events", "-"), "-")
1139 # We need to be able to self.runCmd to get cpuinfo,
1140 # which is not possible when using a remote platform.
1141 @skipIfRemote
1142 def test_qSupported_memory_tagging(self):
1143 supported_dict = self.get_qSupported_dict()
1144 self.assertEqual(
1145 supported_dict.get("memory-tagging", "-"),
1146 "+" if self.isAArch64MTE() else "-",
1149 @skipIfWindows # No pty support to test any inferior output
1150 def test_written_M_content_reads_back_correctly(self):
1151 self.build()
1152 self.set_inferior_startup_launch()
1154 TEST_MESSAGE = "Hello, memory"
1156 # Start up the stub and start/prep the inferior.
1157 procs = self.prep_debug_monitor_and_inferior(
1158 inferior_args=[
1159 "set-message:xxxxxxxxxxxxxX",
1160 "get-data-address-hex:g_message",
1161 "sleep:1",
1162 "print-message:",
1165 self.test_sequence.add_log_lines(
1167 # Start running after initial stop.
1168 "read packet: $c#63",
1169 # Match output line that prints the memory address of the message buffer within the inferior.
1170 # Note we require launch-only testing so we can get inferior otuput.
1172 "type": "output_match",
1173 "regex": self.maybe_strict_output_regex(
1174 r"data address: 0x([0-9a-fA-F]+)\r\n"
1176 "capture": {1: "message_address"},
1178 # Now stop the inferior.
1179 "read packet: {}".format(chr(3)),
1180 # And wait for the stop notification.
1182 "direction": "send",
1183 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
1184 "capture": {1: "stop_signo", 2: "stop_thread_id"},
1187 True,
1189 context = self.expect_gdbremote_sequence()
1190 self.assertIsNotNone(context)
1192 # Grab the message address.
1193 self.assertIsNotNone(context.get("message_address"))
1194 message_address = int(context.get("message_address"), 16)
1196 # Hex-encode the test message, adding null termination.
1197 hex_encoded_message = seven.hexlify(TEST_MESSAGE)
1199 # Write the message to the inferior. Verify that we can read it with the hex-encoded (m)
1200 # and binary (x) memory read packets.
1201 self.reset_test_sequence()
1202 self.test_sequence.add_log_lines(
1204 "read packet: $M{0:x},{1:x}:{2}#00".format(
1205 message_address, len(TEST_MESSAGE), hex_encoded_message
1207 "send packet: $OK#00",
1208 "read packet: $m{0:x},{1:x}#00".format(
1209 message_address, len(TEST_MESSAGE)
1211 "send packet: ${0}#00".format(hex_encoded_message),
1212 "read packet: $x{0:x},{1:x}#00".format(
1213 message_address, len(TEST_MESSAGE)
1215 "send packet: ${0}#00".format(TEST_MESSAGE),
1216 "read packet: $m{0:x},4#00".format(message_address),
1217 "send packet: ${0}#00".format(hex_encoded_message[0:8]),
1218 "read packet: $x{0:x},4#00".format(message_address),
1219 "send packet: ${0}#00".format(TEST_MESSAGE[0:4]),
1220 "read packet: $c#63",
1222 "type": "output_match",
1223 "regex": r"^message: (.+)\r\n$",
1224 "capture": {1: "printed_message"},
1226 "send packet: $W00#00",
1228 True,
1230 context = self.expect_gdbremote_sequence()
1231 self.assertIsNotNone(context)
1233 # Ensure what we read from inferior memory is what we wrote.
1234 printed_message = context.get("printed_message")
1235 self.assertIsNotNone(printed_message)
1236 self.assertEqual(printed_message, TEST_MESSAGE + "X")
1238 # Note: as of this moment, a hefty number of the GPR writes are failing with E32 (everything except rax-rdx, rdi, rsi, rbp).
1239 # Come back to this. I have the test rigged to verify that at least some
1240 # of the bit-flip writes work.
1241 def test_P_writes_all_gpr_registers(self):
1242 self.build()
1243 self.set_inferior_startup_launch()
1245 # Start inferior debug session, grab all register info.
1246 procs = self.prep_debug_monitor_and_inferior(inferior_args=["sleep:2"])
1247 self.add_register_info_collection_packets()
1248 self.add_process_info_collection_packets()
1250 context = self.expect_gdbremote_sequence()
1251 self.assertIsNotNone(context)
1253 # Process register infos.
1254 reg_infos = self.parse_register_info_packets(context)
1255 self.assertIsNotNone(reg_infos)
1256 self.add_lldb_register_index(reg_infos)
1258 # Process endian.
1259 process_info = self.parse_process_info_response(context)
1260 endian = process_info.get("endian")
1261 self.assertIsNotNone(endian)
1263 # Pull out the register infos that we think we can bit flip
1264 # successfully,.
1265 gpr_reg_infos = [
1266 reg_info
1267 for reg_info in reg_infos
1268 if self.is_bit_flippable_register(reg_info)
1270 self.assertTrue(len(gpr_reg_infos) > 0)
1272 # Write flipped bit pattern of existing value to each register.
1273 (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
1274 gpr_reg_infos, endian
1276 self.trace(
1277 "successful writes: {}, failed writes: {}".format(
1278 successful_writes, failed_writes
1281 self.assertTrue(successful_writes > 0)
1283 # Note: as of this moment, a hefty number of the GPR writes are failing
1284 # with E32 (everything except rax-rdx, rdi, rsi, rbp).
1285 @skipIfWindows
1286 def test_P_and_p_thread_suffix_work(self):
1287 self.build()
1288 self.set_inferior_startup_launch()
1290 # Startup the inferior with three threads.
1291 _, threads = self.launch_with_threads(3)
1293 self.reset_test_sequence()
1294 self.add_thread_suffix_request_packets()
1295 self.add_register_info_collection_packets()
1296 self.add_process_info_collection_packets()
1298 context = self.expect_gdbremote_sequence()
1299 self.assertIsNotNone(context)
1301 process_info = self.parse_process_info_response(context)
1302 self.assertIsNotNone(process_info)
1303 endian = process_info.get("endian")
1304 self.assertIsNotNone(endian)
1306 reg_infos = self.parse_register_info_packets(context)
1307 self.assertIsNotNone(reg_infos)
1308 self.add_lldb_register_index(reg_infos)
1310 reg_index = self.select_modifiable_register(reg_infos)
1311 self.assertIsNotNone(reg_index)
1312 reg_byte_size = int(reg_infos[reg_index]["bitsize"]) // 8
1313 self.assertTrue(reg_byte_size > 0)
1315 expected_reg_values = []
1316 register_increment = 1
1317 next_value = None
1319 # Set the same register in each of 3 threads to a different value.
1320 # Verify each one has the unique value.
1321 for thread in threads:
1322 # If we don't have a next value yet, start it with the initial read
1323 # value + 1
1324 if not next_value:
1325 # Read pre-existing register value.
1326 self.reset_test_sequence()
1327 self.test_sequence.add_log_lines(
1329 "read packet: $p{0:x};thread:{1:x}#00".format(
1330 reg_index, thread
1333 "direction": "send",
1334 "regex": r"^\$([0-9a-fA-F]+)#",
1335 "capture": {1: "p_response"},
1338 True,
1340 context = self.expect_gdbremote_sequence()
1341 self.assertIsNotNone(context)
1343 # Set the next value to use for writing as the increment plus
1344 # current value.
1345 p_response = context.get("p_response")
1346 self.assertIsNotNone(p_response)
1347 next_value = lldbgdbserverutils.unpack_register_hex_unsigned(
1348 endian, p_response
1351 # Set new value using P and thread suffix.
1352 self.reset_test_sequence()
1353 self.test_sequence.add_log_lines(
1355 "read packet: $P{0:x}={1};thread:{2:x}#00".format(
1356 reg_index,
1357 lldbgdbserverutils.pack_register_hex(
1358 endian, next_value, byte_size=reg_byte_size
1360 thread,
1362 "send packet: $OK#00",
1364 True,
1366 context = self.expect_gdbremote_sequence()
1367 self.assertIsNotNone(context)
1369 # Save the value we set.
1370 expected_reg_values.append(next_value)
1372 # Increment value for next thread to use (we want them all
1373 # different so we can verify they wrote to each thread correctly
1374 # next.)
1375 next_value += register_increment
1377 # Revisit each thread and verify they have the expected value set for
1378 # the register we wrote.
1379 thread_index = 0
1380 for thread in threads:
1381 # Read pre-existing register value.
1382 self.reset_test_sequence()
1383 self.test_sequence.add_log_lines(
1385 "read packet: $p{0:x};thread:{1:x}#00".format(reg_index, thread),
1387 "direction": "send",
1388 "regex": r"^\$([0-9a-fA-F]+)#",
1389 "capture": {1: "p_response"},
1392 True,
1394 context = self.expect_gdbremote_sequence()
1395 self.assertIsNotNone(context)
1397 # Get the register value.
1398 p_response = context.get("p_response")
1399 self.assertIsNotNone(p_response)
1400 read_value = lldbgdbserverutils.unpack_register_hex_unsigned(
1401 endian, p_response
1404 # Make sure we read back what we wrote.
1405 self.assertEqual(read_value, expected_reg_values[thread_index])
1406 thread_index += 1
1408 @skipUnlessPlatform(oslist=["freebsd", "linux"])
1409 @add_test_categories(["llgs"])
1410 def test_qXfer_siginfo_read(self):
1411 self.build()
1412 self.set_inferior_startup_launch()
1413 procs = self.prep_debug_monitor_and_inferior(
1414 inferior_args=["thread:segfault", "thread:new", "sleep:10"]
1416 self.test_sequence.add_log_lines(["read packet: $c#63"], True)
1417 self.expect_gdbremote_sequence()
1419 # Run until SIGSEGV comes in.
1420 self.reset_test_sequence()
1421 self.test_sequence.add_log_lines(
1424 "direction": "send",
1425 "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
1426 "capture": {1: "signo", 2: "thread_id"},
1429 True,
1432 # Figure out which thread crashed.
1433 context = self.expect_gdbremote_sequence()
1434 self.assertIsNotNone(context)
1435 self.assertEqual(
1436 int(context["signo"], 16), lldbutil.get_signal_number("SIGSEGV")
1438 crashing_thread = int(context["thread_id"], 16)
1440 # Grab siginfo for the crashing thread.
1441 self.reset_test_sequence()
1442 self.add_process_info_collection_packets()
1443 self.test_sequence.add_log_lines(
1445 "read packet: $Hg{:x}#00".format(crashing_thread),
1446 "send packet: $OK#00",
1447 "read packet: $qXfer:siginfo:read::0,80:#00",
1449 "direction": "send",
1450 "regex": re.compile(
1451 r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL
1453 "capture": {1: "response_type", 2: "content_raw"},
1456 True,
1458 context = self.expect_gdbremote_sequence()
1459 self.assertIsNotNone(context)
1461 # Ensure we end up with all data in one packet.
1462 self.assertEqual(context.get("response_type"), "l")
1464 # Decode binary data.
1465 content_raw = context.get("content_raw")
1466 self.assertIsNotNone(content_raw)
1467 content = self.decode_gdbremote_binary(content_raw).encode("latin1")
1469 # Decode siginfo_t.
1470 process_info = self.parse_process_info_response(context)
1471 pad = ""
1472 if process_info["ptrsize"] == "8":
1473 pad = "i"
1474 signo_idx = 0
1475 errno_idx = 1
1476 code_idx = 2
1477 addr_idx = -1
1478 SEGV_MAPERR = 1
1479 if process_info["ostype"] == "linux":
1480 # si_signo, si_errno, si_code, [pad], _sifields._sigfault.si_addr
1481 format_str = "iii{}P".format(pad)
1482 elif process_info["ostype"].startswith("freebsd"):
1483 # si_signo, si_errno, si_code, si_pid, si_uid, si_status, si_addr
1484 format_str = "iiiiiiP"
1485 elif process_info["ostype"].startswith("netbsd"):
1486 # _signo, _code, _errno, [pad], _reason._fault._addr
1487 format_str = "iii{}P".format(pad)
1488 errno_idx = 2
1489 code_idx = 1
1490 else:
1491 assert False, "unknown ostype"
1493 decoder = struct.Struct(format_str)
1494 decoded = decoder.unpack(content[: decoder.size])
1495 self.assertEqual(decoded[signo_idx], lldbutil.get_signal_number("SIGSEGV"))
1496 self.assertEqual(decoded[errno_idx], 0) # si_errno
1497 self.assertEqual(decoded[code_idx], SEGV_MAPERR) # si_code
1498 self.assertEqual(decoded[addr_idx], 0) # si_addr