daniel5151 / gdbstub

An ergonomic, featureful, and easy-to-integrate implementation of the GDB Remote Serial Protocol in Rust (with no-compromises #![no_std] support)
Other
301 stars 49 forks source link

PacketUnexpected with ThreadStopReason::GdbCtrlCInterrupt #89

Closed gz closed 3 years ago

gz commented 3 years ago

I tried to support Ctrl+C (in GDB) by waiting for the serial line interrupt, and if it arrives providing a ThreadStopReason::GdbCtrlCInterrupt to the state machine. However, this gives me:

17017938078 [ERROR] - gdbstub::gdbstub_impl::state_machine: Unexpected interrupt packet!
17029278514 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected

Which seems to be going here. The comment is strange because I'm doing a Ctrl+C while my code is spinning in an infinite loop. Anyways I figured I'd ask also because PacketUnexpected is treated as "always a bug"...

daniel5151 commented 3 years ago

Yeah... that's not good.

Could you post some more context on how you arrived at this situation? i.e: the debug logs from gdbstub and the GDB client?

gz commented 3 years ago
gdbstub trace log ```log 839434646 [INFO ] - nrk::arch::gdb: Waiting for a GDB connection (I/O port 0x2f8 )... 847761916 [INFO ] - nrk::arch::gdb: Use `target remote localhost:1234` in gdb to connect. 142583929118 [INFO ] - nrk::arch::gdb: Debugger connected. 142627577238 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vMustReplyEmpt y") 142770680278 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qTStatus") 142877358354 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qC") 142885060668 [TRACE] - nrk::arch::gdb: read_registers X86_64CoreRegs { regs: [00, 00, 40003D4939F0, 16, 40003D1FD7A2, 40003E426CE8, 40003E426FF0, 40003E355000, 00 , 00, 40003E3540A8, 591, 01, 01, 04, 3F2005D4], eflags: 06, rip: 40003D0024EC, se gments: X86SegmentRegs { cs: 08, ss: 10, ds: 00, es: 00, fs: 00, gs: 00 }, st: [[ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00] , [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 0 0, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00 , 00, 00]], fpu: X87FpuInternalRegs { fctrl: 37F, fstat: 00, ftag: 00, fiseg: 00, fioff: 00, foseg: 00, fooff: 00, fop: 00 }, xmm: [40003CA1C000000040003CA1C000, 20000000000000000000000000, 40003D422620, C0C0, 8080, 10000000000000001, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00], mxcsr: 1FA0 } 142925585414 [TRACE] - nrk::arch::gdb: read_addr 0x57cf40 142932373264 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:setfs:0" ) 143031828638 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:open:6a7 573742070726f62696e67,0,1c0") 143054849962 [TRACE] - nrk::arch::gdb: read_addr 0x40003d0024ec 143062693116 [TRACE] - nrk::arch::gdb: read_addr 0x40003d0024ec 143084145190 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426d98 143187032914 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426da0 143193488566 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qSymbol::") 151065824906 [TRACE] - nrk::arch::gdb: resume_with = Continue 151068806666 [TRACE] - nrk::arch::gdb: Resume execution. 151072033922 [INFO ] - nrk: watchpoint_trigger is 0 151074625712 [INFO ] - nrk: watchpoint_trigger is 3735928559 151077452858 [INFO ] - nrk: step 151079547652 [INFO ] - nrk: step 157326735746 [DEBUG] - gdbstub::gdbstub_impl: <-- interrupt packet 157329869902 [ERROR] - gdbstub::gdbstub_impl::state_machine: Unexpected interrupt packet! 157333321616 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected ```
gdb log ```log Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ../target/x86_64-uefi/debug/esp/kernel... -> exec->log_command (...) <- exec->log_command (target remote localhost:1234) -> remote->open (...) target_close () Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a...Ack Packet received: PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;swbreak+;hwbreak+;qXfer:features:read+ Packet qSupported (supported-packets) is supported Sending packet: $vMustReplyEmpty#3a...Ack Packet received: Sending packet: $QStartNoAckMode#b0...Ack Packet received: OK Sending packet: $Hgp0.0#ad...Packet received: OK Sending packet: $qXfer:features:read:target.xml:0,ffb#79...Packet received: mi386:x86-64 remote:target_xfer_partial (10, target.xml, 0x55c0b830a9b0, 0x0, 0x0, 4096) = 1, 118, bytes = 3c 74 61 72 67 65 74 20 76 65 72 73 69 6f 6e 3d ... Sending packet: $qXfer:features:read:target.xml:76,ffb#b6...Packet received: l remote:target_xfer_partial (10, target.xml, 0x55c0b7caf6c6, 0x0, 0x76, 4096) = 0, 0 target description (line 1): Starting: i386:x86-64 target description (line 1): Entering element target description (line 1): Entering element target description (line 1): Leaving element target description (line 1): Entering element target description (line 1): Leaving element target description (line 1): Leaving element target description (line 1): XInclude processing succeeded. target description (line 1): Starting: i386:x86-64 target description (line 1): Entering element target description (line 1): Parsing attribute version="1.0" target description (line 1): Entering element target description (line 1): Leaving element target description (line 1): Entering element target description (line 1): Parsing attribute name="org.gnu.gdb.i386.sse" target description (line 1): Leaving element target description (line 1): Leaving element gdbarch_find_by_info: info.bfd_arch_info i386:x86-64 gdbarch_find_by_info: info.byte_order 1 (little) gdbarch_find_by_info: info.osabi 5 (GNU/Linux) gdbarch_find_by_info: info.abfd 0x55c0b79a52f0 gdbarch_find_by_info: info.tdep_info 0x0 gdbarch_find_by_info: New architecture 0x55c0b7bb8930 (i386:x86-64) selected gdbarch_dump: GDB_NM_FILE = config/nm-linux.h gdbarch_dump: addr_bit = 64 gdbarch_dump: addr_bits_remove = <0x55c0b63b4910> gdbarch_dump: gdbarch_address_class_name_to_type_flags_p() = 0 gdbarch_dump: address_class_name_to_type_flags = <0x0> gdbarch_dump: gdbarch_address_class_type_flags_p() = 0 gdbarch_dump: address_class_type_flags = <0x0> gdbarch_dump: gdbarch_address_class_type_flags_to_name_p() = 0 gdbarch_dump: address_class_type_flags_to_name = <0x0> gdbarch_dump: address_to_pointer = <0x55c0b64c08d0> gdbarch_dump: addressable_memory_unit_size = <0x55c0b63b5ab0> gdbarch_dump: gdbarch_adjust_breakpoint_address_p() = 0 gdbarch_dump: adjust_breakpoint_address = <0x0> gdbarch_dump: adjust_dwarf2_addr = <0x55c0b63b4960> gdbarch_dump: adjust_dwarf2_line = <0x55c0b63b4970> gdbarch_dump: auto_charset = <0x55c0b64058f0> gdbarch_dump: auto_wide_charset = <0x55c0b6405900> gdbarch_dump: gdbarch_auxv_parse_p() = 0 gdbarch_dump: auxv_parse = <0x0> gdbarch_dump: gdbarch_ax_pseudo_register_collect_p() = 1 gdbarch_dump: ax_pseudo_register_collect = <0x55c0b63af930> gdbarch_dump: gdbarch_ax_pseudo_register_push_stack_p() = 0 gdbarch_dump: ax_pseudo_register_push_stack = <0x0> gdbarch_dump: believe_pcc_promotion = 0 gdbarch_dump: bfd_arch_info = i386:x86-64 gdbarch_dump: breakpoint_from_pc = <0x55c0b63b58c0> gdbarch_dump: breakpoint_kind_from_current_state = <0x55c0b63b58f0> gdbarch_dump: breakpoint_kind_from_pc = <0x55c0b64fbd40> gdbarch_dump: byte_order = 1 gdbarch_dump: byte_order_for_code = 1 gdbarch_dump: call_dummy_location = 1 gdbarch_dump: cannot_fetch_register = <0x55c0b63b4990> gdbarch_dump: cannot_step_breakpoint = 0 gdbarch_dump: cannot_store_register = <0x55c0b63b4990> gdbarch_dump: char_signed = 1 gdbarch_dump: code_of_frame_writable = <0x55c0b63b48e0> gdbarch_dump: coff_make_msymbol_special = <0x55c0b63b4940> gdbarch_dump: convert_from_func_ptr_addr = <0x55c0b63b4920> gdbarch_dump: convert_register_p = <0x55c0b6509db0> gdbarch_dump: gdbarch_core_info_proc_p() = 1 gdbarch_dump: core_info_proc = <0x55c0b654e6c0> gdbarch_dump: gdbarch_core_pid_to_str_p() = 1 gdbarch_dump: core_pid_to_str = <0x55c0b654d130> gdbarch_dump: gdbarch_core_read_description_p() = 1 gdbarch_dump: core_read_description = <0x55c0b63ae780> gdbarch_dump: gdbarch_core_thread_name_p() = 0 gdbarch_dump: core_thread_name = <0x0> gdbarch_dump: gdbarch_core_xfer_shared_libraries_p() = 0 gdbarch_dump: core_xfer_shared_libraries = <0x0> gdbarch_dump: gdbarch_core_xfer_shared_libraries_aix_p() = 0 gdbarch_dump: core_xfer_shared_libraries_aix = <0x0> gdbarch_dump: gdbarch_core_xfer_siginfo_p() = 1 gdbarch_dump: core_xfer_siginfo = <0x55c0b654fc50> gdbarch_dump: decr_pc_after_break = 0x1 gdbarch_dump: deprecated_fp_regnum = -1 gdbarch_dump: deprecated_function_start_offset = 0x0 gdbarch_dump: disassembler_options = (null) gdbarch_dump: disassembler_options_implicit = (null) gdbarch_dump: gdbarch_displaced_step_copy_insn_p() = 1 gdbarch_dump: displaced_step_copy_insn = <0x55c0b63b1f50> gdbarch_dump: gdbarch_displaced_step_fixup_p() = 1 gdbarch_dump: displaced_step_fixup = <0x55c0b63b23e0> gdbarch_dump: displaced_step_hw_singlestep = <0x55c0b63b4790> gdbarch_dump: displaced_step_location = <0x55c0b6550430> gdbarch_dump: double_bit = 64 gdbarch_dump: double_format = floatformat_ieee_double_big gdbarch_dump: gdbarch_dtrace_disable_probe_p() = 1 gdbarch_dump: dtrace_disable_probe = <0x55c0b63ae480> gdbarch_dump: gdbarch_dtrace_enable_probe_p() = 1 gdbarch_dump: dtrace_enable_probe = <0x55c0b63ae4a0> gdbarch_dump: gdbarch_dtrace_parse_probe_argument_p() = 1 gdbarch_dump: dtrace_parse_probe_argument = <0x55c0b63ae5a0> gdbarch_dump: gdbarch_dtrace_probe_is_enabled_p() = 1 gdbarch_dump: dtrace_probe_is_enabled = <0x55c0b63ae4c0> gdbarch_dump: dummy_id = <0x55c0b63af730> gdbarch_dump: dwarf2_addr_size = 8 gdbarch_dump: dwarf2_reg_to_regnum = <0x55c0b63af7a0> gdbarch_dump: ecoff_reg_to_regnum = <0x55c0b63b4930> gdbarch_dump: gdbarch_elf_make_msymbol_special_p() = 0 gdbarch_dump: elf_make_msymbol_special = <0x0> gdbarch_dump: execute_dwarf_cfa_vendor_op = <0x55c0b63b4980> gdbarch_dump: fast_tracepoint_valid_at = <0x55c0b64ffee0> gdbarch_dump: gdbarch_fetch_pointer_argument_p() = 1 gdbarch_dump: fetch_pointer_argument = <0x55c0b64fd6d0> gdbarch_dump: gdbarch_fetch_tls_load_module_address_p() = 1 gdbarch_dump: fetch_tls_load_module_address = <0x55c0b6625970> gdbarch_dump: gdbarch_find_memory_regions_p() = 1 gdbarch_dump: find_memory_regions = <0x55c0b654e100> gdbarch_dump: float_bit = 32 gdbarch_dump: float_format = floatformat_ieee_single_big gdbarch_dump: floatformat_for_type = <0x55c0b64fe7e0> gdbarch_dump: fp0_regnum = 24 gdbarch_dump: gdbarch_frame_align_p() = 1 gdbarch_dump: frame_align = <0x55c0b63aed50> gdbarch_dump: frame_args_skip = 0x8 gdbarch_dump: gdbarch_frame_num_args_p() = 0 gdbarch_dump: frame_num_args = <0x0> gdbarch_dump: frame_red_zone_size = 128 gdbarch_dump: gcc_target_options = <0x55c0b63b5a10> gdbarch_dump: gdbarch_gcore_bfd_target_p() = 0 gdbarch_dump: gcore_bfd_target = (null) gdbarch_dump: gdbarch_gdb_signal_from_target_p() = 1 gdbarch_dump: gdb_signal_from_target = <0x55c0b654c870> gdbarch_dump: gdbarch_gdb_signal_to_target_p() = 1 gdbarch_dump: gdb_signal_to_target = <0x55c0b654caa0> gdbarch_dump: gen_return_address = <0x55c0b63aee80> gdbarch_dump: gdbarch_get_longjmp_target_p() = 1 gdbarch_dump: get_longjmp_target = <0x55c0b63af290> gdbarch_dump: get_pc_address_flags = <0x55c0b63b5ca0> gdbarch_dump: gdbarch_get_siginfo_type_p() = 1 gdbarch_dump: get_siginfo_type = <0x55c0b64faa20> gdbarch_dump: gdbarch_get_syscall_number_p() = 1 gdbarch_dump: get_syscall_number = <0x55c0b63adb80> gdbarch_dump: gdbarch_get_thread_local_address_p() = 0 gdbarch_dump: get_thread_local_address = <0x0> gdbarch_dump: gnu_triplet_regexp = <0x55c0b64fbd30> gdbarch_dump: guess_tracepoint_registers = <0x55c0b63b5ac0> gdbarch_dump: half_bit = 16 gdbarch_dump: half_format = floatformat_ieee_half_big gdbarch_dump: gdbarch_handle_segmentation_fault_p() = 1 gdbarch_dump: handle_segmentation_fault = <0x55c0b64fa830> gdbarch_dump: has_dos_based_file_system = 0 gdbarch_dump: has_global_breakpoints = 0 gdbarch_dump: has_global_solist = 0 gdbarch_dump: has_shared_address_space = <0x55c0b6550420> gdbarch_dump: have_nonsteppable_watchpoint = 0 gdbarch_dump: in_indirect_branch_thunk = <0x55c0b63aed60> gdbarch_dump: in_solib_return_trampoline = <0x55c0b63b48c0> gdbarch_dump: infcall_mmap = <0x55c0b654cdd0> gdbarch_dump: infcall_munmap = <0x55c0b654ccd0> gdbarch_dump: gdbarch_info_proc_p() = 1 gdbarch_dump: info_proc = <0x55c0b6550650> gdbarch_dump: inner_than = <0x55c0b63b48f0> gdbarch_dump: insn_is_call = <0x55c0b63aee70> gdbarch_dump: insn_is_jump = <0x55c0b63aee50> gdbarch_dump: insn_is_ret = <0x55c0b63aee60> gdbarch_dump: int_bit = 32 gdbarch_dump: gdbarch_integer_to_address_p() = 0 gdbarch_dump: integer_to_address = <0x0> gdbarch_dump: iterate_over_objfiles_in_search_order = <0x55c0b6623f20> gdbarch_dump: gdbarch_iterate_over_regset_sections_p() = 1 gdbarch_dump: iterate_over_regset_sections = <0x55c0b63aba70> gdbarch_dump: long_bit = 64 gdbarch_dump: long_double_bit = 128 gdbarch_dump: long_double_format = floatformat_i387_ext gdbarch_dump: long_long_bit = 64 gdbarch_dump: gdbarch_make_corefile_notes_p() = 1 gdbarch_dump: make_corefile_notes = <0x55c0b654f010> gdbarch_dump: make_symbol_special = <0x55c0b63b4950> gdbarch_dump: gdbarch_max_insn_length_p() = 1 gdbarch_dump: max_insn_length = 16 gdbarch_dump: memory_insert_breakpoint = <0x55c0b656f910> gdbarch_dump: memory_remove_breakpoint = <0x55c0b656fa00> gdbarch_dump: num_pseudo_regs = 52 gdbarch_dump: num_regs = 155 gdbarch_dump: osabi = 5 gdbarch_dump: gdbarch_overlay_update_p() = 0 gdbarch_dump: overlay_update = <0x0> gdbarch_dump: pc_regnum = 16 gdbarch_dump: pointer_to_address = <0x55c0b64c0870> gdbarch_dump: print_auxv_entry = <0x55c0b63be780> gdbarch_dump: print_float_info = <0x55c0b6509250> gdbarch_dump: print_insn = <0x55c0b64ffe80> gdbarch_dump: print_registers_info = <0x55c0b65141d0> gdbarch_dump: gdbarch_print_vector_info_p() = 0 gdbarch_dump: print_vector_info = <0x0> gdbarch_dump: gdbarch_process_record_p() = 1 gdbarch_dump: process_record = <0x55c0b65038e0> gdbarch_dump: gdbarch_process_record_signal_p() = 1 gdbarch_dump: process_record_signal = <0x55c0b63adaa0> gdbarch_dump: ps_regnum = 17 gdbarch_dump: gdbarch_pseudo_register_read_p() = 0 gdbarch_dump: pseudo_register_read = <0x0> gdbarch_dump: gdbarch_pseudo_register_read_value_p() = 1 gdbarch_dump: pseudo_register_read_value = <0x55c0b63afc30> gdbarch_dump: gdbarch_pseudo_register_write_p() = 1 gdbarch_dump: pseudo_register_write = <0x55c0b63af9f0> gdbarch_dump: ptr_bit = 64 gdbarch_dump: gdbarch_push_dummy_call_p() = 1 gdbarch_dump: push_dummy_call = <0x55c0b63b1080> gdbarch_dump: gdbarch_push_dummy_code_p() = 1 gdbarch_dump: push_dummy_code = <0x55c0b64fbd10> gdbarch_dump: ravenscar_ops = 0x0 gdbarch_dump: gdbarch_read_pc_p() = 0 gdbarch_dump: read_pc = <0x0> gdbarch_dump: gdbarch_record_special_symbol_p() = 0 gdbarch_dump: record_special_symbol = <0x0> gdbarch_dump: register_name = <0x55c0b665dfa0> gdbarch_dump: register_reggroup_p = <0x55c0b63ae550> gdbarch_dump: register_sim_regno = <0x55c0b63b4810> gdbarch_dump: register_to_value = <0x55c0b6509e00> gdbarch_dump: gdbarch_register_type_p() = 1 gdbarch_dump: register_type = <0x55c0b665da40> gdbarch_dump: gdbarch_relocate_instruction_p() = 1 gdbarch_dump: relocate_instruction = <0x55c0b63aeee0> gdbarch_dump: remote_register_number = <0x55c0b665d990> gdbarch_dump: return_in_first_hidden_param_p = <0x55c0b63b5920> gdbarch_dump: gdbarch_return_value_p() = 1 gdbarch_dump: return_value = <0x55c0b63b0740> gdbarch_dump: sdb_reg_to_regnum = <0x55c0b6501e20> gdbarch_dump: short_bit = 16 gdbarch_dump: significant_addr_bit = 0 gdbarch_dump: gdbarch_single_step_through_delay_p() = 0 gdbarch_dump: single_step_through_delay = <0x0> gdbarch_dump: gdbarch_skip_entrypoint_p() = 0 gdbarch_dump: skip_entrypoint = <0x0> gdbarch_dump: gdbarch_skip_main_prologue_p() = 0 gdbarch_dump: skip_main_prologue = <0x0> gdbarch_dump: skip_permanent_breakpoint = <0x55c0b63b5960> gdbarch_dump: skip_prologue = <0x55c0b63b1c70> gdbarch_dump: skip_solib_resolver = <0x55c0b64f2bf0> gdbarch_dump: skip_trampoline_code = <0x55c0b658aea0> gdbarch_dump: gdbarch_software_single_step_p() = 0 gdbarch_dump: software_single_step = <0x0> gdbarch_dump: sofun_address_maybe_missing = 0 gdbarch_dump: solib_symbols_extension = (null) gdbarch_dump: sp_regnum = 7 gdbarch_dump: stab_reg_to_regnum = <0x55c0b63af7a0> gdbarch_dump: stabs_argument_has_addr = <0x55c0b63b4b10> gdbarch_dump: stack_frame_destroyed_p = <0x55c0b63b48d0> gdbarch_dump: gdbarch_stap_adjust_register_p() = 0 gdbarch_dump: stap_adjust_register = <0x0> gdbarch_dump: stap_gdb_register_prefix = (null) gdbarch_dump: stap_gdb_register_suffix = (null) gdbarch_dump: stap_integer_prefixes = $, gdbarch_dump: stap_integer_suffixes = (null) gdbarch_dump: gdbarch_stap_is_single_operand_p() = 1 gdbarch_dump: stap_is_single_operand = <0x55c0b64fc3f0> gdbarch_dump: gdbarch_stap_parse_special_token_p() = 1 gdbarch_dump: stap_parse_special_token = <0x55c0b64fcd60> gdbarch_dump: stap_register_indirection_prefixes = (, gdbarch_dump: stap_register_indirection_suffixes = ), gdbarch_dump: stap_register_prefixes = %, gdbarch_dump: stap_register_suffixes = (null) gdbarch_dump: gdbarch_static_transform_name_p() = 0 gdbarch_dump: static_transform_name = <0x0> gdbarch_dump: sw_breakpoint_from_kind = <0x55c0b64fbd50> gdbarch_dump: syscalls_info = 0x0 gdbarch_dump: target_desc = 0x55c0b7f0a310 gdbarch_dump: type_align = <0x55c0b64fe890> gdbarch_dump: unwind_pc = <0x55c0b64fe070> gdbarch_dump: unwind_sp = <0x55c0b64c27d0> gdbarch_dump: valid_disassembler_options = 0x0 gdbarch_dump: value_from_register = <0x55c0b64c0a80> gdbarch_dump: value_to_register = <0x55c0b6509f40> gdbarch_dump: vbit_in_delta = 0 gdbarch_dump: virtual_frame_pointer = <0x55c0b63b49a0> gdbarch_dump: vsyscall_range = <0x55c0b654e150> gdbarch_dump: vtable_function_descriptors = 0 gdbarch_dump: wchar_bit = 32 gdbarch_dump: wchar_signed = 1 gdbarch_dump: gdbarch_write_pc_p() = 1 gdbarch_dump: write_pc = <0x55c0b63adc00> gdbarch_dump: xml_syscall_file = syscalls/amd64-linux.xml gdbarch_update_p: New architecture 0x55c0b7bb8930 (i386:x86-64) selected remote:target_xfer_partial (6, (null), 0x55c0b830a9b0, 0x0, 0x0, 4096) = -1, 0 Sending packet: $qTStatus#49...Packet received: Packet qTStatus (trace-status) is NOT supported Sending packet: $?#3f...Packet received: S05 Sending packet: $qfThreadInfo#bb...Packet received: mp01.01 Sending packet: $qsThreadInfo#c8...Packet received: l Sending packet: $qAttached:1#fa...Packet received: 1 Packet qAttached (query-attached) is supported Sending packet: $Hc-1#09...Packet received: OK Sending packet: $qC#b4...Packet received: warning: couldn't determine remote current thread; picking first in list. Sending packet: $qOffsets#4b...Packet received: Text=40003cf25000;Data=40003cf25000;Bss=40003cf25000 Sending packet: $g#67...Packet received: 00000000000000000000000000000000f039493d004000001600000000000000a2d71f3d00400000e86c423e00400000f06f423e004000000050353e0040000000000000000000000000000000000000a840353e004000009105000000000000010000000000000001000000000000000400000000000000d405203f00000000ec24003d004000000600000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000[608 bytes omitted] target_fetch_registers (rip) = ec24003d00400000 0x40003d0024ec 70369767597292 remote:target_xfer_partial (6, (null), 0x55c0b830a9b0, 0x0, 0x0, 4096) = -1, 0 remote:target_xfer_partial (12, (null), 0x55c0b830a9b0, 0x0, 0x0, 4096) = -1, 0 remote:target_xfer_partial (8, (null), 0x55c0b83119c0, 0x0, 0x0, 4096) = -1, 0 Sending packet: $m57cf40,8#6a...Packet received: 0000000000000000 remote:target_xfer_partial (1, (null), 0x7ffd7e77c820, 0x0, 0x57cf40, 8) = 1, 8, bytes = 00 00 00 00 00 00 00 00 Sending packet: $vFile:setfs:0#bf...Packet received: Packet vFile:setfs (hostio-setfs) is NOT supported Sending packet: $vFile:open:6a7573742070726f62696e67,0,1c0#ed...Packet received: Packet vFile:open (hostio-open) is NOT supported warning: remote target does not support file transfer, attempting to access files from local filesystem. warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. Sending packet: $qfThreadInfo#bb...Packet received: mp01.01 Sending packet: $qsThreadInfo#c8...Packet received: l Sending packet: $m40003d0024ec,1#b3...Packet received: e8 remote:target_xfer_partial (1, (null), 0x7ffd7e77c6f7, 0x0, 0x40003d0024ec, 1) = 1, 1, bytes = e8 Sending packet: $m40003d0024ec,1#b3...Packet received: e8 remote:target_xfer_partial (1, (null), 0x7ffd7e77c6f7, 0x0, 0x40003d0024ec, 1) = 1, 1, bytes = e8 nrk::arch::_start (Sending packet: $m40003e426d98,8#9e...Packet received: 0050123e00400000 remote:target_xfer_partial (1, (null), 0x55c0b7ea7830, 0x0, 0x40003e426d98, 8) = 1, 8, bytes = 00 50 12 3e 00 40 00 00 argc=70369785565184, Sending packet: $m40003e426da0,8#be...Packet received: 0900000000000000 remote:target_xfer_partial (1, (null), 0x55c0b7b82a10, 0x0, 0x40003e426da0, 8) = 1, 8, bytes = 09 00 00 00 00 00 00 00 _argv=0x9) at kernel/src/arch/x86_64/mod.rs:927 927 let _r = xmain(); Sending packet: $qSymbol::#5b...Packet received: Packet qSymbol (symbol-lookup) is NOT supported <- remote->open (localhost:1234, 0) (gdb) continue Continuing. Sending packet: $vCont?#49...Packet received: vCont;c;C;s;S Packet vCont (verbose-resume) is supported Sending packet: $vCont;c:p1.-1#0f...^Cremote_pass_ctrlc called remote_interrupt called Packet received: S05 Sending packet: $g#67...target_close () Remote connection closed ```
daniel5151 commented 3 years ago

Ahh, sorry - could you re-upload the gdbstub trace log with the trace-pkt feature enabled?

daniel5151 commented 3 years ago

Also, could you link to the specific revision of your gdbstub implementation that exhibits this behavior?

gz commented 3 years ago

I'm on the refactor/blocking-event-loop currently, will check if this also happens with latest dev/0.6 in a second

gdbstub with trace-pkt ```log 1066765958 [INFO ] - nrk::arch::gdb: Use `target remote localhost:1234` in gdb to connect. 81092034144 [INFO ] - nrk::arch::gdb: Debugger connected. 81096823916 [TRACE] - gdbstub::protocol::recv_packet: <-- + 81124022406 [TRACE] - gdbstub::protocol::recv_packet: <-- $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a 81145838950 [TRACE] - gdbstub::protocol::response_writer: --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;swbreak+;hwbreak+;qXfer:features:read+#47 81153880874 [TRACE] - gdbstub::protocol::recv_packet: <-- + 81159061360 [TRACE] - gdbstub::protocol::recv_packet: <-- $vMustReplyEmpty#3a 81162802302 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vMustReplyEmpty") 81166160342 [TRACE] - gdbstub::protocol::response_writer: --> $#00 81169668558 [TRACE] - gdbstub::protocol::recv_packet: <-- + 81174859122 [TRACE] - gdbstub::protocol::recv_packet: <-- $QStartNoAckMode#b0 81180146078 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 81185443954 [TRACE] - gdbstub::protocol::recv_packet: <-- + 81190546912 [TRACE] - gdbstub::protocol::recv_packet: <-- $Hgp0.0#ad 81195421004 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 81294244030 [TRACE] - gdbstub::protocol::recv_packet: <-- $qXfer:features:read:target.xml:0,ffb#79 81304113196 [TRACE] - gdbstub::protocol::response_writer: --> $mi386:x86-64#c7 81317905154 [TRACE] - gdbstub::protocol::recv_packet: <-- $qXfer:features:read:target.xml:76,ffb#b6 81323953014 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 81343168780 [TRACE] - gdbstub::protocol::recv_packet: <-- $qTStatus#49 81347922584 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qTStatus") 81352925762 [TRACE] - gdbstub::protocol::response_writer: --> $#00 81447439352 [TRACE] - gdbstub::protocol::recv_packet: <-- $?#3f 81450929164 [TRACE] - gdbstub::protocol::response_writer: --> $S05#b8 81456085700 [TRACE] - gdbstub::protocol::recv_packet: <-- $qfThreadInfo#bb 81460219144 [TRACE] - gdbstub::protocol::response_writer: --> $mp01.01#cd 81465820010 [TRACE] - gdbstub::protocol::recv_packet: <-- $qsThreadInfo#c8 81469680828 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 81474842296 [TRACE] - gdbstub::protocol::recv_packet: <-- $qAttached:1#fa 81478627006 [TRACE] - gdbstub::protocol::response_writer: --> $1#31 81570782010 [TRACE] - gdbstub::protocol::recv_packet: <-- $Hc-1#09 81574385340 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 81578823846 [TRACE] - gdbstub::protocol::recv_packet: <-- $qC#b4 81582197314 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qC") 81585717570 [TRACE] - gdbstub::protocol::response_writer: --> $#00 81590707124 [TRACE] - gdbstub::protocol::recv_packet: <-- $qOffsets#4b 81605668698 [TRACE] - gdbstub::protocol::response_writer: --> $Text=40003cf24000;Data=40003cf24000;Bss=40003cf24000#96 81620022386 [TRACE] - gdbstub::protocol::recv_packet: <-- $g#67 81624148540 [TRACE] - nrk::arch::gdb: read_registers X86_64CoreRegs { regs: [00, 00, 40003D496838, 16, 40003D4057B2, 40003E426CE8, 40003E426FF0, 40003E355000, 00, 00, 40003E3540A8, 32A, 01, 01, 04, 3F2005D4], eflags: 06, rip: 40003D029C8C, segments: X86SegmentRegs { cs: 08, ss: 10, ds: 00, es: 00, fs: 00, gs: 00 }, st: [[00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00]], fpu: X87FpuInternalRegs { fctrl: 37F, fstat: 00, ftag: 00, fiseg: 00, fioff: 00, foseg: 00, fooff: 00, fop: 00 }, xmm: [40003CA1C000000040003CA1C000, 20000000000000000000000000, 40003D4216E0, C0C0, 8080, 10000000000000001, 00 , 00, 00, 00, 00, 00, 00, 00, 00, 00], mxcsr: 1FA0 } 81683023348 [TRACE] - gdbstub::protocol::response_writer: --> $000000000000000000000000000000003868493d004000001600000000000000b257403d00400000e86c423e00400000f06f423e004000000050353e00400000000000000000000000000000000000 00a840353e004000002a03000000000000010000000000000001000000000000000400000000000000d405203f000000008c9c023d0040000006000000080000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000c0a13c0040000000c0a13c004000000000000000000000 0000000020000000e016423d004000000000000000000000c0c00000000000000000000000000000808000000000000000000000000000000100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 81777802132 [TRACE] - gdbstub::protocol::recv_packet: <-- $m57df40,8#6b 81786650474 [TRACE] - nrk::arch::gdb: read_addr 0x57df40 81796881910 [TRACE] - gdbstub::protocol::response_writer: --> $0000000000000000#8 6 81809282896 [TRACE] - gdbstub::protocol::recv_packet: <-- $vFile:setfs:0#bf 81817522454 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:setfs:0") 81826350068 [TRACE] - gdbstub::protocol::response_writer: --> $#00 81844309510 [TRACE] - gdbstub::protocol::recv_packet: <-- $vFile:open:6a757374207 0726f62696e67,0,1c0#ed 81856324872 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:open:6a75 73742070726f62696e67,0,1c0") 81864491254 [TRACE] - gdbstub::protocol::response_writer: --> $#00 81967019384 [TRACE] - gdbstub::protocol::recv_packet: <-- $qfThreadInfo#bb 81970810944 [TRACE] - gdbstub::protocol::response_writer: --> $mp01.01#cd 81975998644 [TRACE] - gdbstub::protocol::recv_packet: <-- $qsThreadInfo#c8 81979534160 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 82001606538 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003d029c8c,1#be 82005135502 [TRACE] - nrk::arch::gdb: read_addr 0x40003d029c8c 82008464202 [TRACE] - gdbstub::protocol::response_writer: --> $e8#9d 82098894824 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003d029c8c,1#be 82102497996 [TRACE] - nrk::arch::gdb: read_addr 0x40003d029c8c 82105949486 [TRACE] - gdbstub::protocol::response_writer: --> $e8#9d 82129907876 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003e426d98,8#9e 82133512856 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426d98 82137240916 [TRACE] - gdbstub::protocol::response_writer: --> $0050123e00400000#c f 82144285848 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003e426da0,8#be 82147870414 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426da0 82151882000 [TRACE] - gdbstub::protocol::response_writer: --> $0900000000000000#e d 82248496686 [TRACE] - gdbstub::protocol::recv_packet: <-- $qSymbol::#5b 82251761450 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qSymbol::") 82255043808 [TRACE] - gdbstub::protocol::response_writer: --> $#00 94928978732 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont?#49 94932958498 [TRACE] - gdbstub::protocol::response_writer: --> $vCont;c;C;s;S#62 94938592094 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;c:p1.-1#0f 94941879458 [TRACE] - nrk::arch::gdb: resume_with = Continue 94944714772 [TRACE] - nrk::arch::gdb: Resume execution. 94947951964 [INFO ] - nrk: watchpoint_trigger is 0 94950646512 [INFO ] - nrk: watchpoint_trigger is 3735928559 94954960864 [INFO ] - nrk: step 94958019902 [INFO ] - nrk: step 102264921268 [TRACE] - gdbstub::protocol::response_writer: --> $S05#b8 102268107020 [TRACE] - gdbstub::protocol::recv_packet: <-- 102271156160 [DEBUG] - gdbstub::gdbstub_impl: <-- interrupt packet 102273952962 [ERROR] - gdbstub::gdbstub_impl::state_machine: Unexpected interrupt packet! ```
gz commented 3 years ago

Same issue with dev/0.6 (I guess this was at the same revision anyways). Maybe I'm also just doing something stupid. My approach is to wait for the serial line receive interrupt and if I get that I pass in the ThreadStopReason::GdbCtrlCInterrupt to the state machine. Is this what I'm supposed to do?

daniel5151 commented 3 years ago

Before I look into it this more (likely sometime this weekend), do you know if this was something that started happening after I merged #88, or was this happening before as well?

Theoretically, this assert is there because the GDB client should never send an interrupt packet while the GDB stub is still in the "paused" state (i.e: the Pump state, where it is waiting for more data while the target isn't running). The fact that this is happening means that there's either an issue with how the state machine API is written (i.e: there's a missing state transition), or there's something spooky going on in your implementation (which I would appreciate a commit-hash'd link to)

gz commented 3 years ago

Here is the start of my state machine:

https://github.com/vmware-labs/node-replicated-kernel/blob/c943ca493d2e6832ccaac90ab9808606de46ff13/kernel/src/arch/x86_64/gdb.rs#L101

pretty much all the gdb logic stuff is in that file

gz commented 3 years ago

I didn't have Ctrl+C working before #88 but I can easily revert the changes for that branch and try it, let me do that.

daniel5151 commented 3 years ago

Alright, I've skimmed through your implementation, and I think I understand the issue in your implementation.

Before going into the specific issue at hand, lets back up for a second and discuss how the overall state machine flow goes:

                        (1) pump(u8)
                 ┌─────────────────────────┐
                 │                         │
  start    ┌─────┴──┐                 ┌────▼─────────────────┐
 ──────────►  Pump  │                 │  DeferredStopReason  │
           └─────▲──┘                 └────┬───┬──────────▲──┘
                 │                         │   │          │
                 └─────────────────────────┘   └──────────┘
                   deferred_stop_reason(..)    (2) pump(u8)

The Pump state represents the state where the Target is entirely stopped, and gdbstub is waiting for data (e.g: "read these registers", "write to this memory address", etc...).

Once the gdbstub receives a resume packet, it transitions into the DeferredStopReason state, whereupon the Target is running concurrently with gdbstub.

In this state, there are two events that need to be handled (hence the two methods onGdbStubStateMachineInner<DeferredStopReason>: the case where the Target reports a stop reason (e.g: a breakpoint is hit), and the case where the GDB client sends more data down the line.

The first case is easy to understand: call deferred_stop_reason with the appropriate stop reason, and then the stub will transition back into Pump, awaiting more instructions.

The second case seems a bit weird... why would the GDB client send data while the target is running?

Well... as it turns out, Ctrl-C interrupts are signaled by sending special "interrupt" packets down the wire! Specifically, an interrupt can be signaled either by sending a single 0x3 byte down the wire, or in some cases, by sending a properly framed vCtrlC packet.

See https://sourceware.org/gdb/onlinedocs/gdb/Interrupts.html#Interrupts for details.


In your implementation, you are not handling the "data is sent down the wire while the target is running" case at all. Instead, your current implementation seems to do the following:

  1. KCoreStopReason::ConnectionInterrupt => Some(ThreadStopReason::GdbCtrlCInterrupt) - i.e: if you sense new data on the wire, without even checking what it is, report a stop reason.
  2. deferred_stop_reason dutifully reports the stop reason back to the client, and transitions back into the Pump state to await new data
  3. Upon entering the Pump state, it finally reads the data that was sent down the wire, only to find a interrupt packet that should have been handled by the pump flow in the DeferredStopReason state! An assertion fires, and everything dies.

i.e: you should only call deferred_stop_reason after the .pump() method in the DeferredStopReason returns a Event::CtrlCInterrupt.

A good starting point for how to structure your event loop would be to look at the guts of the new run_blocking method, specifically, the contents of the GdbStubStateMachine::DeferredStopReason match arm:

https://github.com/daniel5151/gdbstub/blob/4e46b72/src/gdbstub_impl/mod.rs#L199


After writing this explanation, I realize that the fact that you ran into this issue is indicative that this new API still needs some work + polish.

I suspect that the API itself could be improved (possibly by adding some more fine-grained states), and it goes without saying that the biggest missing piece right now is good documentation/examples...

Ideally, I want to craft an API that's impossible to misuse - leveraging as many Rust type-system shenanigans to have the compiler enforce all branches are being accounted for. I'll have to think about how I can tweak the current iteration of the API to achieve that...

daniel5151 commented 3 years ago

Ah, in addition, I really should remove the ThreadStopReason::GdbCtrlCInterrupt entirely. It's literally just a "short hand" for writing ThreadStopReason::DoneStep, but I suspect that its naming will lead to lots of confusion...

I'll go ahead and do immediately.

gz commented 3 years ago

Ah I see, yes I figured the chances are high it's just me doing something wrong here. This detailed explanation helps a lot. If you'd like me to I could try to put this into the docs (only if you don't want to do it yourself of course).

daniel5151 commented 3 years ago

I appreciate the offer, but I think this is something I should tackle myself - especially since there's a non-zero chance I rework the API a bit, which would invalidate any docs.

And of course, when you get the chance, please let me know if my explanation + suggested fix was correct!

gz commented 3 years ago

Great, so thanks a lot for your help, I rewrote my state-machine a little to reflect the fact that it should pump() in DeferredStopReason when I have data available. I hope this accurately captures what you wanted me to do.

With this change, Ctrl+C does work fine together with continue (tested with an infinite loop):

nrk::arch::_start (argc=70369785565184, _argv=0x9)
    at kernel/src/arch/x86_64/mod.rs:927
927         let _r = xmain();
(gdb) continue
Continuing.
^C
Program received signal SIGTRAP, Trace/breakpoint trap.
nrk::xmain () at kernel/src/integration_main.rs:512
512         while cond {}
(gdb) continue
Continuing.
^C
Program received signal SIGTRAP, Trace/breakpoint trap.
nrk::xmain () at kernel/src/integration_main.rs:512
512         while cond {}
(gdb) continue
Continuing.
^C
Program received signal SIGTRAP, Trace/breakpoint trap.
nrk::xmain () at kernel/src/integration_main.rs:512
512         while cond {}
(gdb) next
^CRemote communication error.  Target disconnected.: Connection reset by peer.

So while continue works fine, doing a next or step and then hitting Ctrl+C again still gives me gdbstub::gdbstub_impl::state_machine: Unexpected interrupt packet! (and the connection reset above as a cascading error).

I think I understand what's going on: when I do next, the program will start to single-step through the loop so it will execute the state-machine logic many times. What's weird then is that the state-machine does end up in the Pump state (as indicated by the pumping... log message below. Am I correct that this shouldn't happen since GDB is just single-stepping and I don't actually have a prompt (in gdb)?

e.g. the way the log looks it seems for one state-machine execution after taking a step it ends up many times in Pump state without me ever having a GDB prompt, so unsurprisingly it gets an unexpected interrupt packet when I hit Ctrl+c during this time:

[ .. beginning of one gdb stm logic when we got interrupted from after taking a  single-step ..]
26533530728 [INFO ] - nrk::arch::gdb: event_loop reason DebugInterrupt               
[.. we determine that we stopped because we're stepping ..]
26537096730 [TRACE] - nrk::arch::gdb: stop reason is DoneStep                        
26540296784 [INFO ] - nrk::arch::gdb: stop_reason Some(DoneStep) 
[ .. the stm was in deferredstopreason state, this is good too ..]                    
26543815968 [INFO ] - nrk::arch::gdb: deferred_stop_reason                           
26547158636 [TRACE] - gdbstub::protocol::response_writer: --> $S05#b8
[ .. transitions into pump state here, ok but I don't have a gdb prompt yet ..]                
26550949190 [INFO ] - nrk::arch::gdb: pumping...                                     
26554247238 [INFO ] - nrk::arch::gdb: pumping...                                     
26557388140 [INFO ] - nrk::arch::gdb: pumping...                                     
26560478940 [INFO ] - nrk::arch::gdb: pumping...                                     
26563497220 [INFO ] - nrk::arch::gdb: pumping...                                     
26566565346 [TRACE] - gdbstub::protocol::recv_packet: <-- $g#67  
[  .. does some stuff this is all fine ..]
26570024202 [TRACE] - nrk::arch::gdb: read_registers X86_64CoreRegs { regs: [40003D4B
FC4F, 00, 40003D41D600, 01, 00, 40003D4BFC4F, 40003E354FF0, 40003E354D70, 00, 00, 400
03E3544F8, 8C, 01, 01, 04, 3F2005D4], eflags: 302, rip: 40003CFB5CB4, segments: X86Se
gmentRegs { cs: 08, ss: 10, ds: 00, es: 00, fs: 00, gs: 00 }, st: [[00, 00, 00, 00, 0
0, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00
, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00,
 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 
00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00]], fpu: X87FpuInternalRe
gs { fctrl: 37F, fstat: 00, ftag: 00, fiseg: 00, fioff: 00, foseg: 00, fooff: 00, fop
: 00 }, xmm: [1000040003D49BC88, 20000000000000000000000000, 40003D41D860, C0C0, 8080
, 10000000000000001, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00], mxcsr: 1FA0 }          
26609124980 [TRACE] - gdbstub::protocol::response_writer: --> $4ffc4b3d00400000000000
000000000000d6413d00400000010000000000000000000000000000004ffc4b3d00400000f04f353e004
00000704d353e0040000000000000000000000000000000000000f844353e004000008c00000000000000
010000000000000001000000000000000400000000000000d405203f00000000b45cfb3c0040000002030
0000800000010000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000007f030000000000000000000000000000000000000000
0000000000000000000088bc493d004000000100000000000000000000000000000000000000200000006
0d8413d004000000000000000000000c0c000000000000000000000000000008080000000000000000000
0000000000010000000000000001000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000a01f0000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#d0    
[  .. lots of pumping, if I hit Ctrl+C here ever I'm in trouble ..]
26646637356 [INFO ] - nrk::arch::gdb: pumping...                                     
26691508732 [INFO ] - nrk::arch::gdb: pumping...                                     
26694696538 [INFO ] - nrk::arch::gdb: pumping...                                     
26697971936 [INFO ] - nrk::arch::gdb: pumping...                                     
26701309008 [INFO ] - nrk::arch::gdb: pumping...                                     
26704563356 [INFO ] - nrk::arch::gdb: pumping...                                     
26708698674 [INFO ] - nrk::arch::gdb: pumping...                                     
26712805744 [INFO ] - nrk::arch::gdb: pumping...                            
[.. skipped some ..]
26899875856 [INFO ] - nrk::arch::gdb: pumping...                                     
26903197970 [INFO ] - nrk::arch::gdb: pumping...                                     
26906359538 [INFO ] - nrk::arch::gdb: pumping...                                     
26909491578 [INFO ] - nrk::arch::gdb: pumping...                                     
26912674862 [INFO ] - nrk::arch::gdb: pumping...                                     
26915956958 [INFO ] - nrk::arch::gdb: pumping...                                     
26919280244 [INFO ] - nrk::arch::gdb: pumping...                                     
26922500174 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;s:p1.1;c:p1.-1#f7   
26926665256 [INFO ] - nrk::arch::gdb: set resume_with =  Step                        
26930201850 [INFO ] - nrk::arch::gdb: before resuming...
[ .. ok we're done with one gdb stm loop for single-step, we determine we should resume with single step ..]                             
26933414652 [TRACE] - nrk::arch::gdb: Step execution, set TF flag.                   
[ .. things repeat, the step has completed we end up figuring out we did a step and run the gdb stm again ..]
26936998000 [INFO ] - nrk::arch::gdb: event_loop reason DebugInterrupt               
26940745424 [TRACE] - nrk::arch::gdb: stop reason is DoneStep                        
26944102380 [INFO ] - nrk::arch::gdb: stop_reason Some(DoneStep)                     
26947737106 [INFO ] - nrk::arch::gdb: deferred_stop_reason                           
26951167928 [TRACE] - gdbstub::protocol::response_writer: --> $S05#b8                
26954947042 [INFO ] - nrk::arch::gdb: pumping...                                     
27042501250 [INFO ] - nrk::arch::gdb: pumping...                                     
27045500900 [INFO ] - nrk::arch::gdb: pumping...                                     
27048638710 [INFO ] - nrk::arch::gdb: pumping...                                     
27051728572 [INFO ] - nrk::arch::gdb: pumping...                                     
27054819982 [TRACE] - gdbstub::protocol::recv_packet: <-- $g#67                      
27058266062 [TRACE] - nrk::arch::gdb: read_registers X86_64CoreRegs { regs: [40003D4B
FC4F, 00, 40003D41D600, 01, 00, 40003D4BFC4F, 40003E354FF0, 40003E354D70, 00, 00, 400
03E3544F8, 8C, 01, 01, 04, 3F2005D4], eflags: 302, rip: 40003CFB5CBB, segments: X86Se
gmentRegs { cs: 08, ss: 10, ds: 00, es: 00, fs: 00, gs: 00 }, st: [[00, 00, 00, 00, 0
0, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00
, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00,
 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 
00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00]], fpu: X87FpuInternalRe
gs { fctrl: 37F, fstat: 00, ftag: 00, fiseg: 00, fioff: 00, foseg: 00, fooff: 00, fop
: 00 }, xmm: [1000040003D49BC88, 20000000000000000000000000, 40003D41D860, C0C0, 8080
, 10000000000000001, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00], mxcsr: 1FA0 }          
27098559170 [TRACE] - gdbstub::protocol::response_writer: --> $4ffc4b3d00400000000000
000000000000d6413d00400000010000000000000000000000000000004ffc4b3d00400000f04f353e004
00000704d353e0040000000000000000000000000000000000000f844353e004000008c00000000000000
010000000000000001000000000000000400000000000000d405203f00000000bb5cfb3c0040000002030
0000800000010000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000007f030000000000000000000000000000000000000000
0000000000000000000088bc493d004000000100000000000000000000000000000000000000200000006
0d8413d004000000000000000000000c0c000000000000000000000000000008080000000000000000000
00000000000100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000a01f0000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#fe
[ .. again i'm going in the pump state, not clear why ..]
27136006782 [INFO ] - nrk::arch::gdb: pumping...
[.. here I hit Ctrl+C in GDB (I didn't have a prompt) .. ]                                     
27139247866 [TRACE] - gdbstub::protocol::recv_packet: <--                            
27142773072 [DEBUG] - gdbstub::gdbstub_impl: <-- interrupt packet
[ .. gdbstub (rightfully?) complains because it was in pump state? ..]                    
27146204800 [ERROR] - gdbstub::gdbstub_impl::state_machine: Unexpected interrupt pack
et!
27150376962 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected      
daniel5151 commented 3 years ago

Hmm, I'm not entirely sure what's going on here just yet, but here are a few things you can try:

  1. Blindly copy the code from https://github.com/daniel5151/gdbstub/blob/dev/0.6/src/gdbstub_impl/mod.rs#L236-L252, explicitly calling deferred_stop_reason from the Event::CtrlCInterrupt branch.
  2. Maybe your single-step implementation has a bug in it? If so, you can try out the changes at #92, keep single-stepping disabled, and see if that makes the issue go away.
gz commented 3 years ago

Did some tests:

Re 1: Changed it but didn't make a difference (still seems like it gets a ctrl+c packet when not expecting it)

Re 2: Using the new feature branch (feature/optional-single-step): Didn't resolve the issue, I noticed that disabling stepping breaks my next and step commands a bit more than it is already :) (meaning I can't even get to point where I would issue a ctrl+c to stop my infinite loop).

With stepping is enabled, the step, next commands works fine (like before I switched to the branch) when I'm not in a loop (but it will end up with an unexpected packet error when I'm sending a ctrl+c after a next in an infinite loop):

nrk::arch::_start (argc=70369785565184, _argv=0x9)                                    
    at kernel/src/arch/x86_64/mod.rs:927                                              
927         let _r = xmain();                                                         
(gdb) step                                                                            
nrk::xmain () at kernel/src/integration_main.rs:499                                   
499         arch::irq::ioapic_establish_route(0x0, 0x0);
(gdb) step
nrk::arch::irq::ioapic_establish_route (_gsi=0, _core=0)
    at kernel/src/arch/x86_64/irq.rs:810
810         for io_apic in atopology::MACHINE_TOPOLOGY.io_apics() {
(gdb) step
<atopology::MACHINE_TOPOLOGY as core::ops::deref::Deref>::deref (self=0x40003d409b38)
    at /home/gz/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/lib.rs:144
144                     __stability()
(gdb) step
<atopology::MACHINE_TOPOLOGY as core::ops::deref::Deref>::deref::__stability ()
    at /home/gz/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/lib.rs:144
144                     __stability()
(gdb) step
lazy_static::lazy::Lazy<T>::get (
    self=0x40003d4bfb08 <<atopology::MACHINE_TOPOLOGY as core::ops::deref::Deref>::deref::__stability::LAZY>, builder=<optimized out>)
    at /home/gz/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/core_lazy.rs:21
21              self.0.call_once(builder)
(gdb) step

If I disable stepping (fn support_single_step returns None), I'm getting an unexpected packet error immediately after sending a next in gdb (similar problem to the one above but this time it's not a ctrl+c packet but rather a vCont package). Now of course I'm not sure what it means for next and step if single stepping is disabled but I figured it wouldn't matter (as long as I don't do stepi or something) since it could just set a breakpoint?

nrk::arch::_start (argc=70369785565184, _argv=0x9)                                    
    at kernel/src/arch/x86_64/mod.rs:927                                              
927         let _r = xmain();                                                         
(gdb) step                                                                            
Remote connection closed                                                              
(gdb) q          
10122983318 [INFO ] - nrk::arch::gdb: pumping...                                      
10126255784 [INFO ] - nrk::arch::gdb: pumping...                                      
10129504230 [INFO ] - nrk::arch::gdb: pumping...                                      
10132724428 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;s:p1.1;c:p1.-1#f7    
10136879558 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected   
gz commented 3 years ago

FWIW it seems to me that the root of the issue is that the state machine unconditionally goes from deferred_stop_reason into pump state. However, I think in my case, gdb seems to think it's best to just execute the next command by single-stepping through the program stopping after every instruction (without giving me a prompt or anything) -- so judging from this code hitting ctrl+c while in the pump state will be inevitable.

I'm maybe understanding this wrong but so far I assumed the STM is only supposed to be in the pump state when I have a gdb prompt on the client side?

daniel5151 commented 3 years ago

I noticed that disabling stepping breaks my next and step commands a bit more than it is already

That could be indicative of an issue in how you're handling your breakpoints / other stop reasons... Are you adjusting the PC after the breakpoint has been hit?

GDB will do some very weird stuff if breakpoints aren't implemented correctly, and that isn't something gdbstub can detect / catch.


If it's not that... I can try to take a closer look sometime this weekend. In the meantime, you should consider doing some hands-on hacking with the current gdbstub state machine implementation, and see if there might be some incorrect state transitions going on.

As mentioned earlier, this is relatively untested code!

gz commented 3 years ago

That could be indicative of an issue in how you're handling your breakpoints / other stop reasons... Are you adjusting the PC after the breakpoint has been hit?

So I do/did worry about this, because I saw this piece in the docs and it was not something I'm doing. However, the breakpoints and single-step seemed to be working fine without it (except for when it's in this infinite loop :)), so I looked at two other implementations:

In both examples if they use RFlags to single-step I couldn't find any adjustment they do to the RIP when single-stepping. Also in the iPXE code, they do use hardware debug registers for breakpoints (like I do) and don't seem to adjust the RIP after getting a hardware breakpoint. Now, I tried to check the SDM too to get some conclusive information on what RIP is after a hardware debug breakpoint, but unfortunately I didn't find a conclusive statement (yet).

I did add some asserts to verify when I get a debug interrupt due to hitting a breakpoint (with the dr registers), that the RIP corresponds to the same address that I programmed in the dr register and doesn't point to the next instruction, and this seems to be true so far. So, in the end I concluded that maybe this is only relevant for int 3 type interrupts that get inserted into the code?

daniel5151 commented 3 years ago

So, in the end I concluded that maybe this is only relevant for int 3 type interrupts that get inserted into the code?

While I can't give you a definitive yes/no answer for that, based on the docs you've linked, that seems correct?

That said, the fact that you code completely breaks when single-stepping support isn't available is not a good sign (i.e: regardless if ctrl-c interrupts are being handled or not). Hardware-assisted single stepping is an optional feature, and if it isn't available, GDB should be using continue + temporary breakpoints to get things working.

What if you roll-back the code to a point before you started trying to support ctrl-c interrupts, and make super sure that the simple case of disabling single stepping + resuming via continue & temporary breakpoints works as expected.

gz commented 3 years ago

And for having single-stepping disabled. I haven't shared a complete log for that failure yet so here is one:

gdbstub trace log ``` 1101136270 [INFO ] - nrk::arch::gdb: Use `target remote localhost:1234` in gdb to connect. 10680332932 [INFO ] - nrk::arch::gdb: Debugger connected. 10685063254 [TRACE] - nrk::arch::gdb: event_loop reason DebugInterrupt 10688828938 [TRACE] - nrk::arch::gdb: stop_reason None 10691941324 [TRACE] - gdbstub::protocol::recv_packet: <-- + 10719219804 [TRACE] - gdbstub::protocol::recv_packet: <-- $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vCont Supported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a 10740276684 [TRACE] - gdbstub::protocol::response_writer: --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;swbreak+;hwbreak+;qXfer:features: read+#47 10749386038 [TRACE] - gdbstub::protocol::recv_packet: <-- + 10755553658 [TRACE] - gdbstub::protocol::recv_packet: <-- $vMustReplyEmpty#3a 10760667638 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vMustReplyEmpty") 10765739762 [TRACE] - gdbstub::protocol::response_writer: --> $#00 10769783520 [TRACE] - gdbstub::protocol::recv_packet: <-- + 10775149526 [TRACE] - gdbstub::protocol::recv_packet: <-- $QStartNoAckMode#b0 10779194636 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 10783279600 [TRACE] - gdbstub::protocol::recv_packet: <-- + 10787410004 [TRACE] - gdbstub::protocol::recv_packet: <-- $Hgp0.0#ad 10792295672 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 10893187020 [TRACE] - gdbstub::protocol::recv_packet: <-- $qXfer:features:read:target.xml:0,ffb#79 10906524372 [TRACE] - gdbstub::protocol::response_writer: --> $mi386:x86-64#c7 10923025926 [TRACE] - gdbstub::protocol::recv_packet: <-- $qXfer:features:read:target.xml:76,ffb#b6 10927686182 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 10945510934 [TRACE] - gdbstub::protocol::recv_packet: <-- $qTStatus#49 10950528166 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qTStatus") 10955737284 [TRACE] - gdbstub::protocol::response_writer: --> $#00 11054542430 [TRACE] - gdbstub::protocol::recv_packet: <-- $?#3f 11058036250 [TRACE] - gdbstub::protocol::response_writer: --> $S05#b8 11063477958 [TRACE] - gdbstub::protocol::recv_packet: <-- $qfThreadInfo#bb 11067548232 [TRACE] - gdbstub::protocol::response_writer: --> $mp01.01#cd 11073135704 [TRACE] - gdbstub::protocol::recv_packet: <-- $qsThreadInfo#c8 11077081434 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 11082109332 [TRACE] - gdbstub::protocol::recv_packet: <-- $qAttached:1#fa 11085966800 [TRACE] - gdbstub::protocol::response_writer: --> $1#31 11177817596 [TRACE] - gdbstub::protocol::recv_packet: <-- $Hc-1#09 11181501690 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 11186128436 [TRACE] - gdbstub::protocol::recv_packet: <-- $qC#b4 11189551998 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qC") 11193120242 [TRACE] - gdbstub::protocol::response_writer: --> $#00 11198167210 [TRACE] - gdbstub::protocol::recv_packet: <-- $qOffsets#4b 11204444816 [TRACE] - gdbstub::protocol::response_writer: --> $Text=40003cf1c000;Data=40003cf1c000;Bss=40003cf1c000#20 11210386404 [TRACE] - gdbstub::protocol::recv_packet: <-- $g#67 11214040412 [TRACE] - nrk::arch::gdb: read_registers X86_64CoreRegs { regs: [00, 00, 40003D491028, 16, 40003D401982, 40003E426CE8, 40003E426FF0, 40003E355000, 00, 00, 40003E3540A8, 6A, 01, 01, 04, 3F2005D4], eflags: 06, rip: 40003D03578C, segments: X86SegmentRegs { cs: 08, ss: 10, ds: 00, es: 00, fs: 00, gs: 00 }, st : [[00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 0 0, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00]], fpu: X87FpuInternalRegs { fctrl: 37F, fstat: 00, ftag: 00, fiseg: 00, fioff: 00, foseg: 00, fooff: 00, fop: 00 }, xmm: [40003CA1C00000004 0003CA1C000, 20000000000000000000000000, 40003D41D960, C0C0, 8080, 10000000000000001, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00], mxcsr: 1FA0 } 11253766362 [TRACE] - gdbstub::protocol::response_writer: --> $000000000000000000000000000000002810493d0040000016000000000000008219403d00400000e86c423[19/1646] f06f423e004000000050353e0040000000000000000000000000000000000000a840353e004000006a00000000000000010000000000000001000000000000000400000000000000d405203f0000000 08c57033d004000000600000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000c0a13c0040000000c0a 13c004000000000000000000000000000002000000060d9413d004000000000000000000000c0c000000000000000000000000000008080000000000000000000000000000001000000000000000100 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000a01f0000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#5f 11337399048 [TRACE] - gdbstub::protocol::recv_packet: <-- $m581f40,8#39 11341050590 [TRACE] - nrk::arch::gdb: read_addr 0x581f40 11345754916 [TRACE] - gdbstub::protocol::response_writer: --> $0000000000000000#86 11352360516 [TRACE] - gdbstub::protocol::recv_packet: <-- $vFile:setfs:0#bf 11356127114 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:setfs:0") 11360029426 [TRACE] - gdbstub::protocol::response_writer: --> $#00 11371227096 [TRACE] - gdbstub::protocol::recv_packet: <-- $vFile:open:6a7573742070726f62696e67,0,1c0#ed 11377301220 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:open:6a7573742070726f62696e67,0,1c0") 11383584116 [TRACE] - gdbstub::protocol::response_writer: --> $#00 11486438998 [TRACE] - gdbstub::protocol::recv_packet: <-- $qfThreadInfo#bb 11490654990 [TRACE] - gdbstub::protocol::response_writer: --> $mp01.01#cd 11496323398 [TRACE] - gdbstub::protocol::recv_packet: <-- $qsThreadInfo#c8 11500180382 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 11519401998 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003d03578c,1#8f 11523236090 [TRACE] - nrk::arch::gdb: read_addr 0x40003d03578c 11526690780 [TRACE] - gdbstub::protocol::response_writer: --> $e8#9d 11617681050 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003d03578c,1#8f 11621543082 [TRACE] - nrk::arch::gdb: read_addr 0x40003d03578c 11625006922 [TRACE] - gdbstub::protocol::response_writer: --> $e8#9d 11644516906 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003e426d98,8#9e 11648376178 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426d98 11652639048 [TRACE] - gdbstub::protocol::response_writer: --> $0050123e00400000#cf 11660140934 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003e426da0,8#be 11664059118 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426da0 11667647044 [TRACE] - gdbstub::protocol::response_writer: --> $0900000000000000#ed 11758913042 [TRACE] - gdbstub::protocol::recv_packet: <-- $qSymbol::#5b 11762576726 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qSymbol::") 11766382520 [TRACE] - gdbstub::protocol::response_writer: --> $#00 24689898632 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont?#49 24694359324 [TRACE] - gdbstub::protocol::response_writer: --> $vCont;c;C#26 24701651338 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;s:p1.1;c:p1.-1#f7 24705773678 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected ```
gdb log ``` For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ../target/x86_64-uefi/debug/esp/kernel... -> exec->log_command (...) <- exec->log_command (target remote localhost:1234) -> remote->open (...) target_close () Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlR egisters=i386#6a...Ack Packet received: PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;swbreak+;hwbreak+;qXfer:features:read+ Packet qSupported (supported-packets) is supported Sending packet: $vMustReplyEmpty#3a...Ack Packet received: Sending packet: $QStartNoAckMode#b0...Ack Packet received: OK Sending packet: $Hgp0.0#ad...Packet received: OK Sending packet: $qXfer:features:read:target.xml:0,ffb#79...Packet received: mi386:x86-64 remote:target_xfer_partial (10, target.xml, 0x55ea26be3090, 0x0, 0x0, 4096) = 1, 118, bytes = 3c 74 61 72 67 65 74 20 76 65 72 73 69 6f 6e 3d ... Sending packet: $qXfer:features:read:target.xml:76,ffb#b6...Packet received: l remote:target_xfer_partial (10, target.xml, 0x55ea26b286e6, 0x0, 0x76, 4096) = 0, 0 target description (line 1): Starting: i386:x86-64 target description (line 1): Entering element target description (line 1): Entering element target description (line 1): Leaving element target description (line 1): Entering element target description (line 1): Leaving element target description (line 1): Leaving element target description (line 1): XInclude processing succeeded. target description (line 1): Starting: i386:x86-64 target description (line 1): Entering element target description (line 1): Parsing attribute version="1.0" target description (line 1): Entering element target description (line 1): Leaving element target description (line 1): Entering element target description (line 1): Parsing attribute name="org.gnu.gdb.i386.sse" target description (line 1): Leaving element target description (line 1): Leaving element gdbarch_find_by_info: info.bfd_arch_info i386:x86-64 gdbarch_find_by_info: info.byte_order 1 (little) gdbarch_find_by_info: info.osabi 5 (GNU/Linux) gdbarch_find_by_info: info.abfd 0x55ea268548b0 gdbarch_find_by_info: info.tdep_info 0x0 gdbarch_find_by_info: New architecture 0x55ea26cb76f0 (i386:x86-64) selected gdbarch_dump: GDB_NM_FILE = config/nm-linux.h gdbarch_dump: addr_bit = 64 gdbarch_dump: addr_bits_remove = <0x55ea244c8910> gdbarch_dump: gdbarch_address_class_name_to_type_flags_p() = 0 gdbarch_dump: address_class_name_to_type_flags = <0x0> gdbarch_dump: gdbarch_address_class_type_flags_p() = 0 gdbarch_dump: address_class_type_flags = <0x0> gdbarch_dump: gdbarch_address_class_type_flags_to_name_p() = 0 gdbarch_dump: address_class_type_flags_to_name = <0x0> gdbarch_dump: address_to_pointer = <0x55ea245d48d0> gdbarch_dump: addressable_memory_unit_size = <0x55ea244c9ab0> gdbarch_dump: gdbarch_adjust_breakpoint_address_p() = 0 gdbarch_dump: adjust_breakpoint_address = <0x0> gdbarch_dump: adjust_dwarf2_addr = <0x55ea244c8960> gdbarch_dump: adjust_dwarf2_line = <0x55ea244c8970> gdbarch_dump: auto_charset = <0x55ea245198f0> gdbarch_dump: auto_wide_charset = <0x55ea24519900> gdbarch_dump: gdbarch_auxv_parse_p() = 0 gdbarch_dump: auxv_parse = <0x0> gdbarch_dump: gdbarch_ax_pseudo_register_collect_p() = 1 gdbarch_dump: ax_pseudo_register_collect = <0x55ea244c3930> gdbarch_dump: gdbarch_ax_pseudo_register_push_stack_p() = 0 gdbarch_dump: ax_pseudo_register_push_stack = <0x0> gdbarch_dump: believe_pcc_promotion = 0 gdbarch_dump: bfd_arch_info = i386:x86-64 gdbarch_dump: breakpoint_from_pc = <0x55ea244c98c0> gdbarch_dump: breakpoint_kind_from_current_state = <0x55ea244c98f0> gdbarch_dump: breakpoint_kind_from_pc = <0x55ea2460fd40> gdbarch_dump: byte_order = 1 gdbarch_dump: byte_order_for_code = 1 gdbarch_dump: call_dummy_location = 1 gdbarch_dump: cannot_fetch_register = <0x55ea244c8990> gdbarch_dump: cannot_step_breakpoint = 0 gdbarch_dump: cannot_store_register = <0x55ea244c8990> gdbarch_dump: char_signed = 1 gdbarch_dump: code_of_frame_writable = <0x55ea244c88e0> gdbarch_dump: coff_make_msymbol_special = <0x55ea244c8940> gdbarch_dump: convert_from_func_ptr_addr = <0x55ea244c8920> gdbarch_dump: convert_register_p = <0x55ea2461ddb0> gdbarch_dump: gdbarch_core_info_proc_p() = 1 gdbarch_dump: core_info_proc = <0x55ea246626c0> gdbarch_dump: gdbarch_core_pid_to_str_p() = 1 gdbarch_dump: core_pid_to_str = <0x55ea24661130> gdbarch_dump: gdbarch_core_read_description_p() = 1 gdbarch_dump: core_read_description = <0x55ea244c2780> gdbarch_dump: gdbarch_core_thread_name_p() = 0 gdbarch_dump: core_thread_name = <0x0> gdbarch_dump: gdbarch_core_xfer_shared_libraries_p() = 0 gdbarch_dump: core_xfer_shared_libraries = <0x0> gdbarch_dump: gdbarch_core_xfer_shared_libraries_aix_p() = 0 gdbarch_dump: core_xfer_shared_libraries_aix = <0x0> gdbarch_dump: gdbarch_core_xfer_siginfo_p() = 1 gdbarch_dump: core_xfer_siginfo = <0x55ea24663c50> gdbarch_dump: decr_pc_after_break = 0x1 gdbarch_dump: deprecated_fp_regnum = -1 gdbarch_dump: deprecated_function_start_offset = 0x0 gdbarch_dump: disassembler_options = (null) gdbarch_dump: disassembler_options_implicit = (null) gdbarch_dump: gdbarch_displaced_step_copy_insn_p() = 1 gdbarch_dump: displaced_step_copy_insn = <0x55ea244c5f50> gdbarch_dump: gdbarch_displaced_step_fixup_p() = 1 gdbarch_dump: displaced_step_fixup = <0x55ea244c63e0> gdbarch_dump: displaced_step_hw_singlestep = <0x55ea244c8790> gdbarch_dump: displaced_step_location = <0x55ea24664430> gdbarch_dump: double_bit = 64 gdbarch_dump: double_format = floatformat_ieee_double_big gdbarch_dump: gdbarch_dtrace_disable_probe_p() = 1 gdbarch_dump: dtrace_disable_probe = <0x55ea244c2480> gdbarch_dump: gdbarch_dtrace_enable_probe_p() = 1 gdbarch_dump: dtrace_enable_probe = <0x55ea244c24a0> gdbarch_dump: gdbarch_dtrace_parse_probe_argument_p() = 1 gdbarch_dump: dtrace_parse_probe_argument = <0x55ea244c25a0> gdbarch_dump: gdbarch_dtrace_probe_is_enabled_p() = 1 gdbarch_dump: dtrace_probe_is_enabled = <0x55ea244c24c0> gdbarch_dump: dummy_id = <0x55ea244c3730> gdbarch_dump: dwarf2_addr_size = 8 gdbarch_dump: dwarf2_reg_to_regnum = <0x55ea244c37a0> gdbarch_dump: ecoff_reg_to_regnum = <0x55ea244c8930> gdbarch_dump: gdbarch_elf_make_msymbol_special_p() = 0 gdbarch_dump: elf_make_msymbol_special = <0x0> gdbarch_dump: execute_dwarf_cfa_vendor_op = <0x55ea244c8980> gdbarch_dump: gdbarch_fetch_pointer_argument_p() = 1 gdbarch_dump: fetch_pointer_argument = <0x55ea246116d0> gdbarch_dump: gdbarch_fetch_tls_load_module_address_p() = 1 gdbarch_dump: fetch_tls_load_module_address = <0x55ea24739970> gdbarch_dump: gdbarch_find_memory_regions_p() = 1 gdbarch_dump: find_memory_regions = <0x55ea24662100> gdbarch_dump: float_bit = 32 gdbarch_dump: float_format = floatformat_ieee_single_big gdbarch_dump: floatformat_for_type = <0x55ea246127e0> gdbarch_dump: fp0_regnum = 24 gdbarch_dump: gdbarch_frame_align_p() = 1 gdbarch_dump: frame_align = <0x55ea244c2d50> gdbarch_dump: frame_args_skip = 0x8 gdbarch_dump: gdbarch_frame_num_args_p() = 0 gdbarch_dump: frame_num_args = <0x0> gdbarch_dump: frame_red_zone_size = 128 gdbarch_dump: gcc_target_options = <0x55ea244c9a10> gdbarch_dump: gdbarch_gcore_bfd_target_p() = 0 gdbarch_dump: gcore_bfd_target = (null) gdbarch_dump: gdbarch_gdb_signal_from_target_p() = 1 gdbarch_dump: gdb_signal_from_target = <0x55ea24660870> gdbarch_dump: gdbarch_gdb_signal_to_target_p() = 1 gdbarch_dump: gdb_signal_to_target = <0x55ea24660aa0> gdbarch_dump: gen_return_address = <0x55ea244c2e80> gdbarch_dump: gdbarch_get_longjmp_target_p() = 1 gdbarch_dump: get_longjmp_target = <0x55ea244c3290> gdbarch_dump: get_pc_address_flags = <0x55ea244c9ca0> gdbarch_dump: gdbarch_get_siginfo_type_p() = 1 gdbarch_dump: get_siginfo_type = <0x55ea2460ea20> gdbarch_dump: gdbarch_get_syscall_number_p() = 1 gdbarch_dump: get_syscall_number = <0x55ea244c1b80> gdbarch_dump: gdbarch_get_thread_local_address_p() = 0 gdbarch_dump: get_thread_local_address = <0x0> gdbarch_dump: gnu_triplet_regexp = <0x55ea2460fd30> gdbarch_dump: guess_tracepoint_registers = <0x55ea244c9ac0> gdbarch_dump: half_bit = 16 gdbarch_dump: half_format = floatformat_ieee_half_big gdbarch_dump: gdbarch_handle_segmentation_fault_p() = 1 gdbarch_dump: handle_segmentation_fault = <0x55ea2460e830> gdbarch_dump: has_dos_based_file_system = 0 gdbarch_dump: has_global_breakpoints = 0 gdbarch_dump: has_global_solist = 0 gdbarch_dump: has_shared_address_space = <0x55ea24664420> gdbarch_dump: have_nonsteppable_watchpoint = 0 gdbarch_dump: in_indirect_branch_thunk = <0x55ea244c2d60> gdbarch_dump: in_solib_return_trampoline = <0x55ea244c88c0> gdbarch_dump: infcall_mmap = <0x55ea24660dd0> gdbarch_dump: infcall_munmap = <0x55ea24660cd0> gdbarch_dump: gdbarch_info_proc_p() = 1 gdbarch_dump: info_proc = <0x55ea24664650> gdbarch_dump: inner_than = <0x55ea244c88f0> gdbarch_dump: insn_is_call = <0x55ea244c2e70> gdbarch_dump: insn_is_jump = <0x55ea244c2e50> gdbarch_dump: insn_is_ret = <0x55ea244c2e60> gdbarch_dump: int_bit = 32 gdbarch_dump: gdbarch_integer_to_address_p() = 0 gdbarch_dump: integer_to_address = <0x0> gdbarch_dump: iterate_over_objfiles_in_search_order = <0x55ea24737f20> gdbarch_dump: gdbarch_iterate_over_regset_sections_p() = 1 gdbarch_dump: iterate_over_regset_sections = <0x55ea244bfa70> gdbarch_dump: long_bit = 64 gdbarch_dump: long_double_bit = 128 gdbarch_dump: long_double_format = floatformat_i387_ext gdbarch_dump: long_long_bit = 64 gdbarch_dump: gdbarch_make_corefile_notes_p() = 1 gdbarch_dump: make_corefile_notes = <0x55ea24663010> gdbarch_dump: make_symbol_special = <0x55ea244c8950> gdbarch_dump: gdbarch_max_insn_length_p() = 1 gdbarch_dump: max_insn_length = 16 gdbarch_dump: memory_insert_breakpoint = <0x55ea24683910> gdbarch_dump: memory_remove_breakpoint = <0x55ea24683a00> gdbarch_dump: num_pseudo_regs = 52 gdbarch_dump: num_regs = 155 gdbarch_dump: osabi = 5 gdbarch_dump: gdbarch_overlay_update_p() = 0 gdbarch_dump: overlay_update = <0x0> gdbarch_dump: pc_regnum = 16 gdbarch_dump: pointer_to_address = <0x55ea245d4870> gdbarch_dump: print_auxv_entry = <0x55ea244d2780> gdbarch_dump: print_float_info = <0x55ea2461d250> gdbarch_dump: print_insn = <0x55ea24613e80> gdbarch_dump: print_registers_info = <0x55ea246281d0> gdbarch_dump: gdbarch_print_vector_info_p() = 0 gdbarch_dump: print_vector_info = <0x0> gdbarch_dump: gdbarch_process_record_p() = 1 gdbarch_dump: process_record = <0x55ea246178e0> gdbarch_dump: gdbarch_process_record_signal_p() = 1 gdbarch_dump: process_record_signal = <0x55ea244c1aa0> gdbarch_dump: ps_regnum = 17 gdbarch_dump: gdbarch_pseudo_register_read_p() = 0 gdbarch_dump: pseudo_register_read = <0x0> gdbarch_dump: gdbarch_pseudo_register_read_value_p() = 1 gdbarch_dump: pseudo_register_read_value = <0x55ea244c3c30> gdbarch_dump: gdbarch_pseudo_register_write_p() = 1 gdbarch_dump: pseudo_register_write = <0x55ea244c39f0> gdbarch_dump: ptr_bit = 64 gdbarch_dump: gdbarch_push_dummy_call_p() = 1 gdbarch_dump: push_dummy_call = <0x55ea244c5080> gdbarch_dump: gdbarch_push_dummy_code_p() = 1 gdbarch_dump: push_dummy_code = <0x55ea2460fd10> gdbarch_dump: ravenscar_ops = 0x0 gdbarch_dump: gdbarch_read_pc_p() = 0 gdbarch_dump: read_pc = <0x0> gdbarch_dump: gdbarch_record_special_symbol_p() = 0 gdbarch_dump: record_special_symbol = <0x0> gdbarch_dump: register_name = <0x55ea24771fa0> gdbarch_dump: register_reggroup_p = <0x55ea244c2550> gdbarch_dump: register_sim_regno = <0x55ea244c8810> gdbarch_dump: register_to_value = <0x55ea2461de00> gdbarch_dump: gdbarch_register_type_p() = 1 gdbarch_dump: register_type = <0x55ea24771a40> gdbarch_dump: gdbarch_relocate_instruction_p() = 1 gdbarch_dump: relocate_instruction = <0x55ea244c2ee0> gdbarch_dump: remote_register_number = <0x55ea24771990> gdbarch_dump: return_in_first_hidden_param_p = <0x55ea244c9920> gdbarch_dump: gdbarch_return_value_p() = 1 gdbarch_dump: return_value = <0x55ea244c4740> gdbarch_dump: sdb_reg_to_regnum = <0x55ea24615e20> gdbarch_dump: short_bit = 16 gdbarch_dump: significant_addr_bit = 0 gdbarch_dump: gdbarch_single_step_through_delay_p() = 0 gdbarch_dump: single_step_through_delay = <0x0> gdbarch_dump: gdbarch_skip_entrypoint_p() = 0 gdbarch_dump: skip_entrypoint = <0x0> gdbarch_dump: gdbarch_skip_main_prologue_p() = 0 gdbarch_dump: skip_main_prologue = <0x0> gdbarch_dump: skip_permanent_breakpoint = <0x55ea244c9960> gdbarch_dump: skip_prologue = <0x55ea244c5c70> gdbarch_dump: skip_solib_resolver = <0x55ea24606bf0> gdbarch_dump: skip_trampoline_code = <0x55ea2469eea0> gdbarch_dump: gdbarch_software_single_step_p() = 0 gdbarch_dump: software_single_step = <0x0> gdbarch_dump: sofun_address_maybe_missing = 0 gdbarch_dump: solib_symbols_extension = (null) gdbarch_dump: sp_regnum = 7 gdbarch_dump: stab_reg_to_regnum = <0x55ea244c37a0> gdbarch_dump: stabs_argument_has_addr = <0x55ea244c8b10> gdbarch_dump: stack_frame_destroyed_p = <0x55ea244c88d0> gdbarch_dump: gdbarch_stap_adjust_register_p() = 0 gdbarch_dump: stap_adjust_register = <0x0> gdbarch_dump: stap_gdb_register_prefix = (null) gdbarch_dump: stap_gdb_register_suffix = (null) gdbarch_dump: stap_integer_prefixes = $, gdbarch_dump: stap_integer_suffixes = (null) gdbarch_dump: gdbarch_stap_is_single_operand_p() = 1 gdbarch_dump: stap_is_single_operand = <0x55ea246103f0> gdbarch_dump: gdbarch_stap_parse_special_token_p() = 1 gdbarch_dump: stap_parse_special_token = <0x55ea24610d60> gdbarch_dump: stap_register_indirection_prefixes = (, gdbarch_dump: stap_register_indirection_suffixes = ), gdbarch_dump: stap_register_prefixes = %, gdbarch_dump: stap_register_suffixes = (null) gdbarch_dump: gdbarch_static_transform_name_p() = 0 gdbarch_dump: static_transform_name = <0x0> gdbarch_dump: sw_breakpoint_from_kind = <0x55ea2460fd50> gdbarch_dump: syscalls_info = 0x0 gdbarch_dump: target_desc = 0x55ea26eef470 gdbarch_dump: type_align = <0x55ea24612890> gdbarch_dump: unwind_pc = <0x55ea24612070> gdbarch_dump: unwind_sp = <0x55ea245d67d0> gdbarch_dump: valid_disassembler_options = 0x0 gdbarch_dump: value_from_register = <0x55ea245d4a80> gdbarch_dump: value_to_register = <0x55ea2461df40> gdbarch_dump: vbit_in_delta = 0 gdbarch_dump: virtual_frame_pointer = <0x55ea244c89a0> gdbarch_dump: vsyscall_range = <0x55ea24662150> gdbarch_dump: vtable_function_descriptors = 0 gdbarch_dump: wchar_bit = 32 gdbarch_dump: wchar_signed = 1 gdbarch_dump: gdbarch_write_pc_p() = 1 gdbarch_dump: write_pc = <0x55ea244c1c00> gdbarch_dump: xml_syscall_file = syscalls/amd64-linux.xml gdbarch_update_p: New architecture 0x55ea26cb76f0 (i386:x86-64) selected remote:target_xfer_partial (6, (null), 0x55ea26be3090, 0x0, 0x0, 4096) = -1, 0 Sending packet: $qTStatus#49...Packet received: Packet qTStatus (trace-status) is NOT supported Sending packet: $?#3f...Packet received: S05 Sending packet: $qfThreadInfo#bb...Packet received: mp01.01 Sending packet: $qsThreadInfo#c8...Packet received: l Sending packet: $qAttached:1#fa...Packet received: 1 Packet qAttached (query-attached) is supported Sending packet: $Hc-1#09...Packet received: OK Sending packet: $qC#b4...Packet received: warning: couldn't determine remote current thread; picking first in list. Sending packet: $qOffsets#4b...Packet received: Text=40003cf1c000;Data=40003cf1c000;Bss=40003cf1c000 Sending packet: $g#67...Packet received: 000000000000000000000000000000002810493d0040000016000000000000008219403d00400000e86c423e00400000f06f423e004000000050353e0040000000000000000000000000000000000000a840353e004000006a00000000000000010000000000000001000000000000000400000000000000d405203f000000008c57033d004000000600000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000[608 bytes omitted] target_fetch_registers (rip) = 8c57033d00400000 0x40003d03578c 70369767806860 remote:target_xfer_partial (6, (null), 0x55ea26be3090, 0x0, 0x0, 4096) = -1, 0 remote:target_xfer_partial (12, (null), 0x55ea26be3090, 0x0, 0x0, 4096) = -1, 0 remote:target_xfer_partial (8, (null), 0x55ea27157ed0, 0x0, 0x0, 4096) = -1, 0 Sending packet: $m581f40,8#39...Packet received: 0000000000000000 remote:target_xfer_partial (1, (null), 0x7ffcf65e17d0, 0x0, 0x581f40, 8) = 1, 8, bytes = 00 00 00 00 00 00 00 00 Sending packet: $vFile:setfs:0#bf...Packet received: Packet vFile:setfs (hostio-setfs) is NOT supported Sending packet: $vFile:open:6a7573742070726f62696e67,0,1c0#ed...Packet received: Packet vFile:open (hostio-open) is NOT supported warning: remote target does not support file transfer, attempting to access files from local filesystem. warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. Sending packet: $qfThreadInfo#bb...Packet received: mp01.01 Sending packet: $qsThreadInfo#c8...Packet received: l Sending packet: $m40003d03578c,1#8f...Packet received: e8 remote:target_xfer_partial (1, (null), 0x7ffcf65e16a7, 0x0, 0x40003d03578c, 1) = 1, 1, bytes = e8 Sending packet: $m40003d03578c,1#8f...Packet received: e8 remote:target_xfer_partial (1, (null), 0x7ffcf65e16a7, 0x0, 0x40003d03578c, 1) = 1, 1, bytes = e8 nrk::arch::_start (Sending packet: $m40003e426d98,8#9e...Packet received: 0050123e00400000 remote:target_xfer_partial (1, (null), 0x55ea26c062d0, 0x0, 0x40003e426d98, 8) = 1, 8, bytes = 00 50 12 3e 00 40 00 00 argc=70369785565184, Sending packet: $m40003e426da0,8#be...Packet received: 0900000000000000 remote:target_xfer_partial (1, (null), 0x55ea2712ff20, 0x0, 0x40003e426da0, 8) = 1, 8, bytes = 09 00 00 00 00 00 00 00 _argv=0x9) at kernel/src/arch/x86_64/mod.rs:927 927 let _r = xmain(); Sending packet: $qSymbol::#5b...Packet received: Packet qSymbol (symbol-lookup) is NOT supported <- remote->open (localhost:1234, 0) (gdb) next Sending packet: $vCont?#49...Packet received: vCont;c;C Packet vCont (verbose-resume) is supported Sending packet: $vCont;s:p1.1;c:p1.-1#f7...target_close () Remote connection closed (gdb) ```
daniel5151 commented 3 years ago

Wait a sec, that's very weird... why is your GDB client sending $vCont;s:p1.1;c:p1.-1#f7? The stub responded to vCont? with just vCont;c;C, so the client should not be sending the stub a vCont;s packet!

Assuming those logs were from the feature/optional-single-step branch, this particular PacketUnexpected should be happening in a totally different part of the codebase, namely: https://github.com/daniel5151/gdbstub/blob/ba4b971f4ff562fe2a70d281f42503f251ed040a/src/gdbstub_impl/ext/base.rs#L510

Could you add a log statement to gdbstub to see if my guess is correct?

gz commented 3 years ago

Yes this is using the feature/optional-single-step branch, and looks like your guess is correct:

5660085612 [TRACE] - gdbstub::protocol::response_writer: --> $vCont;c;C#265674929254 
[TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;s:p1.1;c:p1.-1#f7
5685461636 [INFO ] - gdbstub::gdbstub_impl::ext::base: we are at base.rs:510
5695651002 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected
daniel5151 commented 3 years ago

What GDB client version are you using? gdb --version

gz commented 3 years ago
gdb --version
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
daniel5151 commented 3 years ago

Right, that's the same version I'm on...

What happens if instead of next, you explicitly set a (software) breakpoint + run continue?

gz commented 3 years ago

That works fine (break function, continue) (note that software breakpoint for me is programming dr registers on x86 -- while still using gdbstub::target::ext::breakpoints::SwBreakpoint)

gz commented 3 years ago

Trace for that interaction:

gdbstub trace log ``` 6977372162 [DEBUG] - nrk::arch::gdb: event_loop stop_reason None 6980852850 [TRACE] - gdbstub::protocol::recv_packet: <-- + 7008225862 [TRACE] - gdbstub::protocol::recv_packet: <-- $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContS upported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a 7029285274 [TRACE] - gdbstub::protocol::response_writer: --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;swbreak+;hwbreak+;qXfer:features:r ead+#47 7036481486 [TRACE] - gdbstub::protocol::recv_packet: <-- + 7041908766 [TRACE] - gdbstub::protocol::recv_packet: <-- $vMustReplyEmpty#3a 7045998870 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vMustReplyEmpty") 7050043914 [TRACE] - gdbstub::protocol::response_writer: --> $#00 7054248310 [TRACE] - gdbstub::protocol::recv_packet: <-- + 7060866178 [TRACE] - gdbstub::protocol::recv_packet: <-- $QStartNoAckMode#b0 7066272126 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 7071663790 [TRACE] - gdbstub::protocol::recv_packet: <-- + 7076830710 [TRACE] - gdbstub::protocol::recv_packet: <-- $Hgp0.0#ad 7081817664 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 7181970144 [TRACE] - gdbstub::protocol::recv_packet: <-- $qXfer:features:read:target.xml:0,ffb#79 7195307336 [TRACE] - gdbstub::protocol::response_writer: --> $mi386:x86-64#c7 7211568600 [TRACE] - gdbstub::protocol::recv_packet: <-- $qXfer:features:read:target.xml:76,ffb#b6 7216246482 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 7235144782 [TRACE] - gdbstub::protocol::recv_packet: <-- $qTStatus#49 7240025236 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qTStatus") 7245135482 [TRACE] - gdbstub::protocol::response_writer: --> $#00 7344366282 [TRACE] - gdbstub::protocol::recv_packet: <-- $?#3f 7348029250 [TRACE] - gdbstub::protocol::response_writer: --> $S05#b8 7353699162 [TRACE] - gdbstub::protocol::recv_packet: <-- $qfThreadInfo#bb 7357840314 [TRACE] - gdbstub::protocol::response_writer: --> $mp01.01#cd 7363500806 [TRACE] - gdbstub::protocol::recv_packet: <-- $qsThreadInfo#c8 7367407476 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 7372650144 [TRACE] - gdbstub::protocol::recv_packet: <-- $qAttached:1#fa 7376522966 [TRACE] - gdbstub::protocol::response_writer: --> $1#31 7467701838 [TRACE] - gdbstub::protocol::recv_packet: <-- $Hc-1#09 7471325642 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 7475944078 [TRACE] - gdbstub::protocol::recv_packet: <-- $qC#b4 7479423346 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qC") 7483002788 [TRACE] - gdbstub::protocol::response_writer: --> $#00 7488103236 [TRACE] - gdbstub::protocol::recv_packet: <-- $qOffsets#4b 7494507766 [TRACE] - gdbstub::protocol::response_writer: --> $Text=40003cf1e000;Data=40003cf1e000;Bss=40003cf1e000#26 7500571310 [TRACE] - gdbstub::protocol::recv_packet: <-- $g#67 7504041408 [TRACE] - nrk::arch::gdb: read_registers X86_64CoreRegs { regs: [00, 00, 40003D48CAE0, 16, 40003D1F83D2, 40003E426CE8, 40003E426FF0, 40003E355000, 0 0, 00, 40003E3540A8, 45, 01, 01, 04, 3F2005D4], eflags: 06, rip: 40003CFB5F0C, segments: X86SegmentRegs { cs: 08, ss: 10, ds: 00, es: 00, fs: 00, gs: 00 }, st: [[00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00 , 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 0 0, 00, 00, 00, 00]], fpu: X87FpuInternalRegs { fctrl: 37F, fstat: 00, ftag: 00, fiseg: 00, fioff: 00, foseg: 00, fooff: 00, fop: 00 }, xmm: [40003CA1C000000040 003CA1C000, 20000000000000000000000000, 40003D41E540, C0C0, 8080, 10000000000000001, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00], mxcsr: 1FA0 } 7543542740 [TRACE] - gdbstub::protocol::response_writer: --> $00000000000000000000000000000000e0ca483d004000001600000000000000d2831f3d00400000e86c423e00400000f 06f423e004000000050353e0040000000000000000000000000000000000000a840353e004000004500000000000000010000000000000001000000000000000400000000000000d405203f00000000 0c5ffb3c0040000006000000080000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000c0a13c0040000000c0a1 3c004000000000000000000000000000002000000040e5413d004000000000000000000000c0c0000000000000000000000000000080800000000000000000000000000000010000000000000001000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000a01f0000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#75 7627192734 [TRACE] - gdbstub::protocol::recv_packet: <-- $m57ff40,8#6d 7630796958 [TRACE] - nrk::arch::gdb: read_addr 0x57ff40 7635414306 [TRACE] - gdbstub::protocol::response_writer: --> $0000000000000000#86 7641986182 [TRACE] - gdbstub::protocol::recv_packet: <-- $vFile:setfs:0#bf 7645691498 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:setfs:0") 7649565474 [TRACE] - gdbstub::protocol::response_writer: --> $#00 7659335870 [TRACE] - gdbstub::protocol::recv_packet: <-- $vFile:open:6a7573742070726f62696e67,0,1c0#ed 7663997048 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("vFile:open:6a7573742070726f62696e67,0,1c0") 7668762702 [TRACE] - gdbstub::protocol::response_writer: --> $#00 7767227128 [TRACE] - gdbstub::protocol::recv_packet: <-- $qfThreadInfo#bb 7771479112 [TRACE] - gdbstub::protocol::response_writer: --> $mp01.01#cd 7777038588 [TRACE] - gdbstub::protocol::recv_packet: <-- $qsThreadInfo#c8 7780940288 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 7803036956 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003cfb5f0c,1#1a 7806883502 [TRACE] - nrk::arch::gdb: read_addr 0x40003cfb5f0c 7810467782 [TRACE] - gdbstub::protocol::response_writer: --> $e8#9d 7908064684 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003cfb5f0c,1#1a 7806883502 [TRACE] - nrk::arch::gdb: read_addr 0x40003cfb5f0c 7810467782 [TRACE] - gdbstub::protocol::response_writer: --> $e8#9d 7908064684 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003cfb5f0c,1#1a 7911849826 [TRACE] - nrk::arch::gdb: read_addr 0x40003cfb5f0c 7915344328 [TRACE] - gdbstub::protocol::response_writer: --> $e8#9d 7941072160 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003e426d98,8#9e 7945067912 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426d98 7949316616 [TRACE] - gdbstub::protocol::response_writer: --> $0050123e00400000#cf 7956650556 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003e426da0,8#be 7960612822 [TRACE] - nrk::arch::gdb: read_addr 0x40003e426da0 7964287718 [TRACE] - gdbstub::protocol::response_writer: --> $0900000000000000#ed 8057117554 [TRACE] - gdbstub::protocol::recv_packet: <-- $qSymbol::#5b 8060890784 [INFO ] - gdbstub::gdbstub_impl: Unknown command: Ok("qSymbol::") 8064837124 [TRACE] - gdbstub::protocol::response_writer: --> $#00 43254137788 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003cf84b3b,1#ed 43264758980 [TRACE] - nrk::arch::gdb: read_addr 0x40003cf84b3b 43274649388 [TRACE] - gdbstub::protocol::response_writer: --> $48#6c 48280899550 [TRACE] - gdbstub::protocol::recv_packet: <-- $Z0,40003cf84b3b,1#36 48291381918 [TRACE] - nrk::arch::gdb: add sw breakpoint 0x40003cf84b3b 48296342324 [TRACE] - nrk::arch::gdb: add hw breakpoint 0x40003cf84b3b (in ELF: 0x66b3b 48302161806 [INFO ] - nrk::arch::gdb: sa.enabled_bps 0b1 48306799684 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 48313523254 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont?#49 48317931928 [TRACE] - gdbstub::protocol::response_writer: --> $vCont;c;C#26 48324407470 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;c:p1.-1#0f 48328599708 [TRACE] - nrk::arch::gdb: resume: signal = None resume_with = Some(Continue) 48333206132 [DEBUG] - nrk::arch::gdb: event_loop stop_reason Some(HwBreak(1)) 48338383958 [TRACE] - gdbstub::protocol::response_writer: --> $T05thread:p01.01;hwbreak:;#5f 48432019284 [TRACE] - gdbstub::protocol::recv_packet: <-- $g#67 48435339726 [TRACE] - nrk::arch::gdb: read_registers X86_64CoreRegs { regs: [00, 00, 40003D48CAE0, 16, 40003D1F83D2, 40003E426CE8, 40003E354FF0, 40003E354E00, 00, 00, 40003E3540A8, 45, 01, 01, 04, 3F2005D4], eflags: 06, rip: 40003CF84B3B, segments: X86SegmentRegs { cs: 08, ss: 10, ds: 00, es: 00, fs: 00, gs: 00 }, st: [[00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00], [00, 00, 00, 00, 00, 00, 00, 00, 00, 00]], fpu: X87FpuInternalRegs { fctrl: 37F, fstat: 00, ftag: 00, fiseg: 00, fioff: 00, foseg: 00, fooff: 00, fop: 00 }, xmm: [40003CA1C000000040003CA1C000, 20000000000000000000000000, 40003D41E540, C0C0, 8080, 10000000000000001, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00], mxcsr: 1FA0 } 48475972132 [TRACE] - gdbstub::protocol::response_writer: --> $00000000000000000000000000000000e0ca483d004000001600000000000000d2831f3d00400000e86c423e00400000f04f353e00400000004e353e0040000000000000000000000000000000000000a840353e004000004500000000000000010000000000000001000000000000000400000000000000d405203f000000003b4bf83c004000000600000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000c0a13c0040000000c0a13c004000000000000000000000000000002000000040e5413d004000000000000000000000c0c00000000000000000000000000000808000000000000000000000000000000100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a01f0000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#ab48516400690 [TRACE] - gdbstub::protocol::recv_packet: <-- $qfThreadInfo#bb48520657822 [TRACE] - gdbstub::protocol::response_writer: --> $mp01.01#cd48526467640 [TRACE] - gdbstub::protocol::recv_packet: <-- $qsThreadInfo#c8 48530459124 [TRACE] - gdbstub::protocol::response_writer: --> $l#6c 48627088360 [TRACE] - gdbstub::protocol::recv_packet: <-- $z0,40003cf84b3b,1#56 48631016468 [TRACE] - nrk::arch::gdb: remove sw breakpoint 0x40003cf84b3b 48635232288 [TRACE] - nrk::arch::gdb: remove_hw_breakpoint 0x40003cf84b3b (in ELF: 0x66b3b 48641061978 [TRACE] - gdbstub::protocol::response_writer: --> $OK#9a 48649211888 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003cf84b3b,1#ed 48654413406 [TRACE] - nrk::arch::gdb: read_addr 0x40003cf84b3b 48659050382 [TRACE] - gdbstub::protocol::response_writer: --> $48#6c 48665789044 [TRACE] - gdbstub::protocol::recv_packet: <-- $m40003cf84b3b,1#ed 48669719918 [TRACE] - nrk::arch::gdb: read_addr 0x40003cf84b3b 48673253998 [TRACE] - gdbstub::protocol::response_writer: --> $48#6c ```
daniel5151 commented 3 years ago

Well, aside from the possibly weird interaction of returning a HwBreak stop reason from a breakpoint set via z0/Z0, good to see that it seems to be working as expected...

I quickly checked to see what happens if you disable single-step support (and just in case, range-step support) in the armv4t example, and the logs seem totally normal (i.e: I report vCont;c;C, and the client respects that)...

I'll be honest, I am now very confused. Your GDB client clearly acknowledged the vCont? response, but then it went ahead and sent s anyways...

Off the top of my head, a few more things to try:

gz commented 3 years ago

Well, aside from the possibly weird interaction of returning a HwBreak stop reason from a breakpoint set via z0/Z0, good to see that it seems to be working as expected...

Right, I noticed that too that I should probably respond with SwBreak. This is a problem with me forwarding this just to the HwBreak logic, will fix it. In theory it shouldn't matter for the vCont issue as this won't even set a BP. But I'll fix it now and report back...

gz commented 3 years ago

Ok I fixed reporting a HwBreak instead of SwBreak when appropriate.

Does the client still sent vCont;s if you explicitly call stepi (vs. next)?

I did some tests, it doesn't seem to matter what command I use: (support_single_step set to None in all cases)

(gdb) nexti
Sending packet: $vCont?#49...Packet received: vCont;c;C
Packet vCont (verbose-resume) is supported
Sending packet: $vCont;s:p1.1;c:p1.-1#f7...target_close ()
14103070338 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont?#49
14107316118 [TRACE] - gdbstub::protocol::response_writer: --> $vCont;c;C#26
14114603290 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;s:p1.1;c:p1.-1#f7
14118713350 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected
(gdb) step
Sending packet: $vCont?#49...Packet received: vCont;c;C
Packet vCont (verbose-resume) is supported
Sending packet: $vCont;s:p1.1;c:p1.-1#f7...target_close ()
Remote connection closed
7030775732 [TRACE] - gdbstub::protocol::response_writer: --> $#00
8871060246 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont?#49
8875015708 [TRACE] - gdbstub::protocol::response_writer: --> $vCont;c;C#26
8882109736 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;s:p1.1;c:p1.-1#f78886110586 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected
gz commented 3 years ago

Tried with latest gdb version 11.1 compiled from sources, same result:

85393326932 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont?#49
85398723430 [TRACE] - gdbstub::protocol::response_writer: --> $vCont;c;C#26
85407086552 [TRACE] - gdbstub::protocol::recv_packet: <-- $vCont;s:p1.1;c:p1.-1#f7
85412503838 [ERROR] - nrk::arch::gdb: gdbstub internal error PacketUnexpected
➜  gdb-11.1 ./gdb/gdb ../node-replicated-kernel/target/x86_64-uefi/debug/esp/kernel
Python Exception <type 'exceptions.ImportError'>: No module named gdb./gdb/gdb: warning: Could not load the Python gdb module from `/usr/local/share/gdb/python'.
Limited Python support is available from the _gdb module.Suggest passing --data-directory=/path/to/gdb/data-directory.
GNU gdb (GDB) 11.1Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../node-replicated-kernel/target/x86_64-uefi/debug/esp/kernel...
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
warning: remote target does not support file transfer, attempting to access files from local filesystem.
warning: Unable to find dynamic linker breakpoint function.GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
Python Exception <type 'exceptions.NameError'>: Installation error: gdb._execute_unwinders function is missing
nrk::arch::_start (argc=70369785565184, _argv=0x9)    at kernel/src/arch/x86_64/mod.rs:927927        
 let _r = xmain();
(gdb) next
Remote connection closed
daniel5151 commented 3 years ago

Fascinating...

Okay, another thought:

gz commented 3 years ago

can you post the contents of your .gdbinit?

It's just target remote localhost:1234

what happens if you connect to the target without using your .gdbinit script, or passing the binary to gdb

good question, I tried without passing a binary and/or gdbinit using nexti and stepi, but the error was still the same

daniel5151 commented 3 years ago

Right. Well shoot, I'm stumped.

Unless there's something incredibly obvious I'm missing, it seems that GDB is ignoring the fact that the stub doesn't support single-stepping, and is sending it single-step commands regardless.

I'll try to find some time this weekend to whip up some kind of "dummy" gdbstub implementation that uses the same Arch as you're currently using, and see if I can repro the behavior locally. Maybe this is some weird x86 specific issue, whereby GDB will unconditionally assume single-stepping is supported at the architecture level? If that's the case, then I'll have to rethink some of the changes I'm making in #92, in order to avoid try and catch what might be a absolutely terrible footgun.


In the meantime, I'll suggest that we shelve this digression into why optional single-stepping isn't working, and re-focus on the actual issue at hand: getting Ctrl-C interrupts working.

Go ahead and re-enable support for single stepping support, and then see if you can get your state machine implementation working correctly without handling Ctrl-C interrupts. That should give us a baseline level of "working code" to then re-introduce Ctrl-C functionality into.

daniel5151 commented 3 years ago

Well I'll be damned.

I hacked together a dummy gdbstub implementation backed by the x86 arch (i.e: memory is entirely filled with NOPs, registers are set to reasonable dummy values), and lo and behold: invoking stepi will unconditionally send s to the stub!

I'm now digging through the GDB client code to figure out what the heck this is happening...

gz commented 3 years ago

Indeed, looks more and more like a gdb bug :)

gz commented 3 years ago

In the meantime, I'll suggest that we shelve this digression into why optional single-stepping isn't working, and re-focus on the actual issue at hand: getting Ctrl-C interrupts working.

Right so coming back on this: I still believe there might be an issue with the assumptions in the state-machine; basically it seems what happens is that when I use next to start executing an infinite loop GDB will use the "Step mode" to execute said loop (e.g., stopping after every instruction). This means that the STM will go into the pump state many times without me ever having a gdb prompt, so it's likely that the ctrl+c comes in at an inconvenient time (during the pump state). Maybe now that you have a dummy x86 stub we could use it to confirm this problem in another implementation?

daniel5151 commented 3 years ago

Indeed, it seems you're right!

I'm not sure why I didn't try this out sooner, but if I spin up the in-repo armv4t example and execute stepi 10000 in GDB, hitting Ctrl-C triggers the same unexpected packet branch as you're seeing!

Now that I have an easy local repro, I can really dig into what's going on, though unfortunately, this week is a bit hectic for me, so I'm not sure when exactly I'll get the chance to dig into this issue...

In any case, I can confirm this is definitely an issue on gdbstub's end.

If you'd like to take a crack at fixing this issue, I'd be happy to review any code sent my way. Otherwise, give me some time, and I'll definitely fix this issue 😅

gz commented 3 years ago

Sure sounds good, I can take a look this week and see if I can fix it before you

daniel5151 commented 3 years ago

Just a heads up - if you do end up trying to fix it, could you please investigate your fix in the context of the in-tree armv4t example?

Assuming this isn't another funky architecture-specific issue, fixing it for the in-tree example should also fix things in your implementation, while also making it a lot easier for me to validate the solution on my end.

daniel5151 commented 3 years ago

Welp, this bug has nerd sniped me, so I spent my (late) lunch looking into this...

I went ahead and tested out what gdbserver does in this scenario (i.e: debugging a regular 'ol userland binary on my x64 linux box), and here's what I found:

Running stepi 10000 and then trying to Ctrl-C in between appears to work "correctly", insofar as the target seems to stop once the trigger is hit. I decided to dig into the gdbserver source code, and it uses some very straightforward logic whereby "if 0x3 is enountered outside of the regular packet framing, attempt to interrupt the target".

What does "interrupt the target" entail?

The gdbserver triggers a SIGINT (signal number 02) within the running process, which is then returned in the next stop-reply packet! i.e: instead of returning a typical SIGTRAP (S05) stop reply packet, the target will return a SIGINT (S02) stop reply packet instead, which the GDB client acknowledges, and breaks out of its stepi loop!

https://github.com/bminor/binutils-gdb/blob/3814a9e1fe77c01c7e872c25afa198537d4ac780/gdbserver/linux-low.cc#L5732-L5737

In fact, if you run the GDB command handle SIGINT nostop before proceeding to run stepi 1000, you can actually reproduce the "Ctrl-C doesn't work" behavior perfectly, as GDB will simply not stop when the target sends back a S02 response packet.

It seems a possible solution here will be to make the Pump state pump method return Event::CtrlCInterrupt as well. The added complexity here is that because we aren't in the DeferredStopReason part of the protocol state machine, we cannot immediately respond with S02, as that would result in a protocol error. Instead, we are forced to require that the target implementation "stashes" this interrupt request until the next time a vCont packet arrives.

EDIT: I have a (brittle) local fix that seems to prove that returning S02 does indeed break the stepi 10000 chain in the armv4t example. All that's left is to think of how this should be expressed via the state machine API, and whether or not it might be possible to hide this wart from end users all together...

gz commented 3 years ago

Nice! It seems like some clarification in the GDB documentation would be in order for this case... at least I couldn't find it there, the gdbserver implementation seems to be the documentation in this case :) FWIW deferring the Ctrl+C packet until we're in deferred stop state again seems like something that would be quite simple to support with the explicit state machine model. But it does make me wonder if this is the only packet that is a special case :)

daniel5151 commented 3 years ago

Sorry for the delay, but the fix is now in dev/0.6!

I've gone ahead and substantially reworked the state machine API to be a bit more streamlined and consistent. Notably, handling interrupts and disconnect conditions is now done via dedicated state machine states, rather than Events that get returned by certain methods.

While I don't have great documentation just yet, I would once again recommend that you take a look at the implementation of GdbStub::run_blocking for an example of how to interact with the state machine API.

I will close this issue after you get a chance to try out these changes + confirm that they are working as expected.

Cheers!

gz commented 3 years ago

sounds good I will give it a try this weekend!

daniel5151 commented 3 years ago

Just a heads up - I spent a bunch of time working on gdbstub today, and aside from this fix, I've also pushed up some other breaking changes to dev/0.6 as well (such as introducing a GDB RSP specific Signal type that's used instead of u8, making IDET method naming consistent by prefixing everything with support_, etc...).

Apologies for the API churn!

gz commented 3 years ago

Ok --I have a test now that does Ctrl+C & continue and happy to report that it's working as expected on dev/0.6 :+1:

gz commented 3 years ago

Got excited too early. I still have some issue with next (aka doing single-stepping) and sending Ctrl+C during that time. Will need to investigate further.

gz commented 3 years ago

Ok nvm, I figured that was my bug -- when single-stepping I accidentially reported StepDone instead of SIGINT to interrupt_handled... Now it works with next/single-step and Ctrl+c too :+1:

daniel5151 commented 3 years ago

Fantastic!

It sure was a long journey to get this fixed, but I'm glad we got it working in the end!

All that's left is the arduous task of documenting all of these APIs, updating the changelog, writing a 0.5 migration guide, and publishing to crates.io... At this rate, it's looking more and more likely that all that is going to have to happen sometime in December over the holiday season 😅

Cheers!