I was debugging against a remote stub in async mode, using the TUI, and I issued "quit" while still connected, in the hopes of bailing out of GDB without much fuss, but, I ran into this SEGV: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7fcf597fb6e0 (LWP 13869)] 0x0000000000552f5e in serial_can_async_p (scb=0x0) at ../../src/gdb/serial.c:504 504 return (scb->ops->async != NULL); (top-gdb) bt #0 0x0000000000552f5e in serial_can_async_p (scb=0x0) at ../../src/gdb/serial.c:504 During symbol reading, unsupported tag: 'DW_TAG_const_type'. #1 0x000000000042ffa3 in remote_can_async_p () at ../../src/gdb/remote.c:8207 During symbol reading, DW_AT_type missing from DW_TAG_subrange_type. #2 0x000000000040d740 in execute_command (p=0x7fff618212a0 "set width 118", from_tty=0) at ../../src/gdb/top.c:382 #3 0x0000000000457d1c in tui_update_gdb_sizes () at ../../src/gdb/tui/tui-win.c:468 #4 0x0000000000452002 in tui_disable () at ../../src/gdb/tui/tui.c:455 #5 0x0000000000452581 in tui_exit () at ../../src/gdb/tui/tui-interp.c:45 #6 0x00007fcf589e0110 in exit () from /lib/libc.so.6 #7 0x000000000040edeb in quit_force (args=0x0, from_tty=1) at ../../src/gdb/top.c:1292 #8 0x0000000000443f20 in quit_command (args=0x0, from_tty=1) at ../../src/gdb/cli/cli-cmds.c:315 #9 0x000000000043e660 in do_cfunc (c=0xa344b0, args=0x0, from_tty=1) at ../../src/gdb/cli/cli-decode.c:60 #10 0x00000000004412a3 in cmd_func (cmd=0xa344b0, args=0x0, from_tty=1) at ../../src/gdb/cli/cli-decode.c:1680 #11 0x000000000040d9df in execute_command (p=0x9e81c1 "", from_tty=1) at ../../src/gdb/top.c:465 #12 0x00000000004c19ea in command_handler (command=0x9e81c0 "q") at ../../src/gdb/event-top.c:514 As you can see from from #2, disabling the tui ends up executing a command. At this point, the remote target was still pushed on the stack, but it had already been closed, hence the remote connection was closed, and remote_desc was == NULL. There are target_can_async_p call around every command invocation, and since the remote target was still on the stack, remote_can_async_p was called, but it isn't expecting to be reached with remote_desc == NULL, as most of remote's code: static int remote_can_async_p (void) { if (!remote_async_permitted) /* We only enable async when the user specifically asks for it. */ return 0; /* We're async whenever the serial device is. */ return remote_async_mask_value && serial_can_async_p (remote_desc); } The issue is that quit_target closes the current target, but doesn't pop it: static int quit_target (void *arg) { struct qt_args *qt = (struct qt_args *)arg; if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) { if (attach_flag) target_detach (qt->args, qt->from_tty); else target_kill (); } /* UDI wants this, to kill the TIP. */ target_close (¤t_target, 1); /* Save the history information if it is appropriate to do so. */ if (write_history_p && history_filename) write_history (history_filename); do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */ return 0; } The UDI target seems to be gone from the sources, but, even if it's still here and I missed it, this is broken. It should at best be a pop_target. But, while I'm at it, if the current target is of stratum > process_stratum, this will still leave the process_stratum target open, which is much more likelly to need closing. So, I've come up with a new pop_all_targets method and used it instead. Tested against x86_64-unknown-linux-gnu native and gdbserver. OK? -- Pedro Alves