diff options
author | Joel Brobecker <brobecker@gnat.com> | 2009-10-28 15:01:27 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2009-10-28 15:01:27 +0000 |
commit | 9a7071a8ce92ca34996d97b77e72ac8cc3946cd6 (patch) | |
tree | 9f70f54a268195155ff17a5b382b60a41d5d38f3 /gdb/remote.c | |
parent | 14610ad10e3d4b84565d3590eaa9582f9793f743 (diff) | |
download | gdb-9a7071a8ce92ca34996d97b77e72ac8cc3946cd6.zip gdb-9a7071a8ce92ca34996d97b77e72ac8cc3946cd6.tar.gz gdb-9a7071a8ce92ca34996d97b77e72ac8cc3946cd6.tar.bz2 |
gdb/:
* remote.c (interrupt_sequence_control_c)
(interrupt_sequence_break, interrupt_sequence_break_g)
(interrupt_sequence_modes): New constants.
(interrupt_sequence_mode, interrupt_on_connect): New variable.
(show_interrupt_sequence): New function.
(set_remotebreak, show_remotebreak): New function.
(send_interrupt_sequence): New function.
(remote_start_remote): Call send_interrupt_sequence if
interrupt_on_connect is true.
(remote_stop_as): Call send_interrupt_sequence.
(_initialize_remote): Add interrupt-sequence and interrupt-on-connect,
modify remotebreak to call set_remotebreak and show_remotebreak.
* NEWS: Add entry for "set/show remote interrupt-sequence" and
"set/show remote interrupt-on-connect". Also mention that
"set/show remotebreak" is now deprecated.
gdb/doc/:
* gdb.texinfo (Remote Configuration): Add "set/show remote
interrupt-sequence" and "set/show remote interrupt-on-connect" command.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 127 |
1 files changed, 116 insertions, 11 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 43955e9..664a9c7 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -546,14 +546,76 @@ static int remote_async_mask_value = 1; this can go away. */ static int wait_forever_enabled_p = 1; +/* Allow the user to specify what sequence to send to the remote + when he requests a program interruption: Although ^C is usually + what remote systems expect (this is the default, here), it is + sometimes preferable to send a break. On other systems such + as the Linux kernel, a break followed by g, which is Magic SysRq g + is required in order to interrupt the execution. */ +const char interrupt_sequence_control_c[] = "Ctrl-C"; +const char interrupt_sequence_break[] = "BREAK"; +const char interrupt_sequence_break_g[] = "BREAK-g"; +static const char *interrupt_sequence_modes[] = + { + interrupt_sequence_control_c, + interrupt_sequence_break, + interrupt_sequence_break_g, + NULL + }; +static const char *interrupt_sequence_mode = interrupt_sequence_control_c; + +static void +show_interrupt_sequence (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ + if (interrupt_sequence_mode == interrupt_sequence_control_c) + fprintf_filtered (file, + _("Send the ASCII ETX character (Ctrl-c) " + "to the remote target to interrupt the " + "execution of the program.\n")); + else if (interrupt_sequence_mode == interrupt_sequence_break) + fprintf_filtered (file, + _("send a break signal to the remote target " + "to interrupt the execution of the program.\n")); + else if (interrupt_sequence_mode == interrupt_sequence_break_g) + fprintf_filtered (file, + _("Send a break signal and 'g' a.k.a. Magic SysRq g to " + "the remote target to interrupt the execution " + "of Linux kernel.\n")); + else + internal_error (__FILE__, __LINE__, + _("Invalid value for interrupt_sequence_mode: %s."), + interrupt_sequence_mode); +} -/* This variable chooses whether to send a ^C or a break when the user - requests program interruption. Although ^C is usually what remote - systems expect, and that is the default here, sometimes a break is - preferable instead. */ +/* This boolean variable specifies whether interrupt_sequence is sent + to the remote target when gdb connects to it. + This is mostly needed when you debug the Linux kernel: The Linux kernel + expects BREAK g which is Magic SysRq g for connecting gdb. */ +static int interrupt_on_connect = 0; +/* This variable is used to implement the "set/show remotebreak" commands. + Since these commands are now deprecated in favor of "set/show remote + interrupt-sequence", it no longer has any effect on the code. */ static int remote_break; +static void +set_remotebreak (char *args, int from_tty, struct cmd_list_element *c) +{ + if (remote_break) + interrupt_sequence_mode = interrupt_sequence_break; + else + interrupt_sequence_mode = interrupt_sequence_control_c; +} + +static void +show_remotebreak (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ +} + /* Descriptor for I/O to remote machine. Initialize it to NULL so that remote_open knows that we don't have a file open when the program starts. */ @@ -2604,6 +2666,25 @@ struct start_remote_args int extended_p; }; +/* Send interrupt_sequence to remote target. */ +static void +send_interrupt_sequence () +{ + if (interrupt_sequence_mode == interrupt_sequence_control_c) + serial_write (remote_desc, "\x03", 1); + else if (interrupt_sequence_mode == interrupt_sequence_break) + serial_send_break (remote_desc); + else if (interrupt_sequence_mode == interrupt_sequence_break_g) + { + serial_send_break (remote_desc); + serial_write (remote_desc, "g", 1); + } + else + internal_error (__FILE__, __LINE__, + _("Invalid value for interrupt_sequence_mode: %s."), + interrupt_sequence_mode); +} + static void remote_start_remote (struct ui_out *uiout, void *opaque) { @@ -2617,6 +2698,9 @@ remote_start_remote (struct ui_out *uiout, void *opaque) /* Ack any packet which the remote side has already sent. */ serial_write (remote_desc, "+", 1); + if (interrupt_on_connect) + send_interrupt_sequence (); + /* The first packet we send to the target is the optional "supported packets" request. If the target can answer this, it will tell us which later probes to skip. */ @@ -4044,12 +4128,8 @@ remote_stop_as (ptid_t ptid) if (rs->cached_wait_status) return; - /* Send a break or a ^C, depending on user preference. */ - - if (remote_break) - serial_send_break (remote_desc); - else - serial_write (remote_desc, "\003", 1); + /* Send interrupt_sequence to remote target. */ + send_interrupt_sequence (); } /* This is the generic stop called via the target vector. When a target @@ -9019,6 +9099,8 @@ void _initialize_remote (void) { struct remote_state *rs; + struct cmd_list_element *cmd; + char *cmd_name; /* architecture specific data */ remote_gdbarch_data_handle = @@ -9086,8 +9168,31 @@ terminating `#' character and checksum."), Set whether to send break if interrupted."), _("\ Show whether to send break if interrupted."), _("\ If set, a break, instead of a cntrl-c, is sent to the remote target."), - NULL, NULL, /* FIXME: i18n: Whether to send break if interrupted is %s. */ + set_remotebreak, show_remotebreak, &setlist, &showlist); + cmd_name = "remotebreak"; + cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1); + deprecate_cmd (cmd, "set remote interrupt-sequence"); + cmd_name = "remotebreak"; /* needed because lookup_cmd updates the pointer */ + cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1); + deprecate_cmd (cmd, "show remote interrupt-sequence"); + + add_setshow_enum_cmd ("interrupt-sequence", class_support, + interrupt_sequence_modes, &interrupt_sequence_mode, _("\ +Set interrupt sequence to remote target."), _("\ +Show interrupt sequence to remote target."), _("\ +Valid value is \"Ctrl-C\", \"BREAK\" or \"BREAK-g\". The default is \"Ctrl-C\"."), + NULL, show_interrupt_sequence, + &remote_set_cmdlist, + &remote_show_cmdlist); + + add_setshow_boolean_cmd ("interrupt-on-connect", class_support, + &interrupt_on_connect, _("\ +Set whether interrupt-sequence is sent to remote target when gdb connects to."), _(" \ +Show whether interrupt-sequence is sent to remote target when gdb connects to."), _(" \ +If set, interrupt sequence is sent to remote target."), + NULL, NULL, + &remote_set_cmdlist, &remote_show_cmdlist); /* Install commands for configuring memory read/write packets. */ |