| Index: gdb/remote.c
|
| diff --git a/gdb/remote.c b/gdb/remote.c
|
| index 04b818f8b85cb8b1fcb38f53c8fec2196238b4e9..1c9367d2b0f569416588d3786d4a934e223d80a1 100644
|
| --- a/gdb/remote.c
|
| +++ b/gdb/remote.c
|
| @@ -65,13 +65,11 @@
|
| #include "tracepoint.h"
|
| #include "ax.h"
|
| #include "ax-gdb.h"
|
| +#include "agent.h"
|
|
|
| /* Temp hacks for tracepoint encoding migration. */
|
| static char *target_buf;
|
| static long target_buf_size;
|
| -/*static*/ void
|
| -encode_actions (struct breakpoint *t, struct bp_location *tloc,
|
| - char ***tdp_actions, char ***stepping_actions);
|
|
|
| /* The size to align memory write packets, when practical. The protocol
|
| does not guarantee any alignment, and gdb will generate short
|
| @@ -242,6 +240,10 @@ static int remote_read_description_p (struct target_ops *target);
|
|
|
| static void remote_console_output (char *msg);
|
|
|
| +static int remote_supports_cond_breakpoints (void);
|
| +
|
| +static int remote_can_run_breakpoint_commands (void);
|
| +
|
| /* The non-stop remote protocol provisions for one pending stop reply.
|
| This is where we keep it until it is acknowledged. */
|
|
|
| @@ -319,6 +321,14 @@ struct remote_state
|
| /* True if the stub reports support for conditional tracepoints. */
|
| int cond_tracepoints;
|
|
|
| + /* True if the stub reports support for target-side breakpoint
|
| + conditions. */
|
| + int cond_breakpoints;
|
| +
|
| + /* True if the stub reports support for target-side breakpoint
|
| + commands. */
|
| + int breakpoint_commands;
|
| +
|
| /* True if the stub reports support for fast tracepoints. */
|
| int fast_tracepoints;
|
|
|
| @@ -363,7 +373,7 @@ free_private_thread_info (struct private_thread_info *info)
|
| static int
|
| remote_multi_process_p (struct remote_state *rs)
|
| {
|
| - return rs->extended && rs->multi_process_aware;
|
| + return rs->multi_process_aware;
|
| }
|
|
|
| /* This data could be associated with a target, but we do not always
|
| @@ -479,7 +489,7 @@ remote_get_noisy_reply (char **buf_p,
|
| {
|
| adjusted_size = to - org_to;
|
|
|
| - sprintf (buf, "qRelocInsn:%x", adjusted_size);
|
| + xsnprintf (buf, *sizeof_buf, "qRelocInsn:%x", adjusted_size);
|
| putpkt (buf);
|
| }
|
| else if (ex.reason < 0 && ex.error == MEMORY_ERROR)
|
| @@ -746,7 +756,7 @@ static int wait_forever_enabled_p = 1;
|
| 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[] =
|
| +static const char *const interrupt_sequence_modes[] =
|
| {
|
| interrupt_sequence_control_c,
|
| interrupt_sequence_break,
|
| @@ -1242,6 +1252,7 @@ enum {
|
| PACKET_vFile_pwrite,
|
| PACKET_vFile_close,
|
| PACKET_vFile_unlink,
|
| + PACKET_vFile_readlink,
|
| PACKET_qXfer_auxv,
|
| PACKET_qXfer_features,
|
| PACKET_qXfer_libraries,
|
| @@ -1253,10 +1264,12 @@ enum {
|
| PACKET_qXfer_threads,
|
| PACKET_qXfer_statictrace_read,
|
| PACKET_qXfer_traceframe_info,
|
| + PACKET_qXfer_uib,
|
| PACKET_qGetTIBAddr,
|
| PACKET_qGetTLSAddr,
|
| PACKET_qSupported,
|
| PACKET_QPassSignals,
|
| + PACKET_QProgramSignals,
|
| PACKET_qSearch_memory,
|
| PACKET_vAttach,
|
| PACKET_vRun,
|
| @@ -1266,6 +1279,8 @@ enum {
|
| PACKET_qXfer_siginfo_write,
|
| PACKET_qAttached,
|
| PACKET_ConditionalTracepoints,
|
| + PACKET_ConditionalBreakpoints,
|
| + PACKET_BreakpointCommands,
|
| PACKET_FastTracepoints,
|
| PACKET_StaticTracepoints,
|
| PACKET_InstallInTrace,
|
| @@ -1275,6 +1290,7 @@ enum {
|
| PACKET_QAllow,
|
| PACKET_qXfer_fdpic,
|
| PACKET_QDisableRandomization,
|
| + PACKET_QAgent,
|
| PACKET_MAX
|
| };
|
|
|
| @@ -1414,14 +1430,15 @@ static int
|
| remote_query_attached (int pid)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| + size_t size = get_remote_packet_size ();
|
|
|
| if (remote_protocol_packets[PACKET_qAttached].support == PACKET_DISABLE)
|
| return 0;
|
|
|
| if (remote_multi_process_p (rs))
|
| - sprintf (rs->buf, "qAttached:%x", pid);
|
| + xsnprintf (rs->buf, size, "qAttached:%x", pid);
|
| else
|
| - sprintf (rs->buf, "qAttached");
|
| + xsnprintf (rs->buf, size, "qAttached");
|
|
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
| @@ -1443,16 +1460,17 @@ remote_query_attached (int pid)
|
| return 0;
|
| }
|
|
|
| -/* Add PID to GDB's inferior table. Since we can be connected to a
|
| - remote system before before knowing about any inferior, mark the
|
| - target with execution when we find the first inferior. If ATTACHED
|
| - is 1, then we had just attached to this inferior. If it is 0, then
|
| - we just created this inferior. If it is -1, then try querying the
|
| - remote stub to find out if it had attached to the inferior or
|
| - not. */
|
| +/* Add PID to GDB's inferior table. If FAKE_PID_P is true, then PID
|
| + has been invented by GDB, instead of reported by the target. Since
|
| + we can be connected to a remote system before before knowing about
|
| + any inferior, mark the target with execution when we find the first
|
| + inferior. If ATTACHED is 1, then we had just attached to this
|
| + inferior. If it is 0, then we just created this inferior. If it
|
| + is -1, then try querying the remote stub to find out if it had
|
| + attached to the inferior or not. */
|
|
|
| static struct inferior *
|
| -remote_add_inferior (int pid, int attached)
|
| +remote_add_inferior (int fake_pid_p, int pid, int attached)
|
| {
|
| struct inferior *inf;
|
|
|
| @@ -1484,6 +1502,7 @@ remote_add_inferior (int pid, int attached)
|
| }
|
|
|
| inf->attach_flag = attached;
|
| + inf->fake_pid_p = fake_pid_p;
|
|
|
| return inf;
|
| }
|
| @@ -1559,7 +1578,13 @@ remote_notice_new_inferior (ptid_t currthread, int running)
|
| may not know about it yet. Add it before adding its child
|
| thread, so notifications are emitted in a sensible order. */
|
| if (!in_inferior_list (ptid_get_pid (currthread)))
|
| - inf = remote_add_inferior (ptid_get_pid (currthread), -1);
|
| + {
|
| + struct remote_state *rs = get_remote_state ();
|
| + int fake_pid_p = !remote_multi_process_p (rs);
|
| +
|
| + inf = remote_add_inferior (fake_pid_p,
|
| + ptid_get_pid (currthread), -1);
|
| + }
|
|
|
| /* This is really a new thread. Add it. */
|
| remote_add_thread (currthread, running);
|
| @@ -1574,7 +1599,7 @@ remote_notice_new_inferior (ptid_t currthread, int running)
|
|
|
| /* Return the private thread data, creating it if necessary. */
|
|
|
| -struct private_thread_info *
|
| +static struct private_thread_info *
|
| demand_private_info (ptid_t ptid)
|
| {
|
| struct thread_info *info = find_thread_ptid (ptid);
|
| @@ -1657,6 +1682,65 @@ remote_pass_signals (int numsigs, unsigned char *pass_signals)
|
| }
|
| }
|
|
|
| +/* The last QProgramSignals packet sent to the target. We bypass
|
| + sending a new program signals list down to the target if the new
|
| + packet is exactly the same as the last we sent. IOW, we only let
|
| + the target know about program signals list changes. */
|
| +
|
| +static char *last_program_signals_packet;
|
| +
|
| +/* If 'QProgramSignals' is supported, tell the remote stub what
|
| + signals it should pass through to the inferior when detaching. */
|
| +
|
| +static void
|
| +remote_program_signals (int numsigs, unsigned char *signals)
|
| +{
|
| + if (remote_protocol_packets[PACKET_QProgramSignals].support != PACKET_DISABLE)
|
| + {
|
| + char *packet, *p;
|
| + int count = 0, i;
|
| +
|
| + gdb_assert (numsigs < 256);
|
| + for (i = 0; i < numsigs; i++)
|
| + {
|
| + if (signals[i])
|
| + count++;
|
| + }
|
| + packet = xmalloc (count * 3 + strlen ("QProgramSignals:") + 1);
|
| + strcpy (packet, "QProgramSignals:");
|
| + p = packet + strlen (packet);
|
| + for (i = 0; i < numsigs; i++)
|
| + {
|
| + if (signal_pass_state (i))
|
| + {
|
| + if (i >= 16)
|
| + *p++ = tohex (i >> 4);
|
| + *p++ = tohex (i & 15);
|
| + if (count)
|
| + *p++ = ';';
|
| + else
|
| + break;
|
| + count--;
|
| + }
|
| + }
|
| + *p = 0;
|
| + if (!last_program_signals_packet
|
| + || strcmp (last_program_signals_packet, packet) != 0)
|
| + {
|
| + struct remote_state *rs = get_remote_state ();
|
| + char *buf = rs->buf;
|
| +
|
| + putpkt (packet);
|
| + getpkt (&rs->buf, &rs->buf_size, 0);
|
| + packet_ok (buf, &remote_protocol_packets[PACKET_QProgramSignals]);
|
| + xfree (last_program_signals_packet);
|
| + last_program_signals_packet = packet;
|
| + }
|
| + else
|
| + xfree (packet);
|
| + }
|
| +}
|
| +
|
| /* If PTID is MAGIC_NULL_PTID, don't set any thread. If PTID is
|
| MINUS_ONE_PTID, set the thread to -1, so the stub returns the
|
| thread. If GEN is set, set the general thread, if not, then set
|
| @@ -1717,7 +1801,7 @@ set_general_process (void)
|
| struct remote_state *rs = get_remote_state ();
|
|
|
| /* If the remote can't handle multiple processes, don't bother. */
|
| - if (!remote_multi_process_p (rs))
|
| + if (!rs->extended || !remote_multi_process_p (rs))
|
| return;
|
|
|
| /* We only need to change the remote current thread if it's pointing
|
| @@ -2820,7 +2904,7 @@ remote_static_tracepoint_marker_at (CORE_ADDR addr,
|
| struct remote_state *rs = get_remote_state ();
|
| char *p = rs->buf;
|
|
|
| - sprintf (p, "qTSTMat:");
|
| + xsnprintf (p, get_remote_packet_size (), "qTSTMat:");
|
| p += strlen (p);
|
| p += hexnumstr (p, addr);
|
| putpkt (rs->buf);
|
| @@ -2839,20 +2923,6 @@ remote_static_tracepoint_marker_at (CORE_ADDR addr,
|
| return 0;
|
| }
|
|
|
| -static void
|
| -free_current_marker (void *arg)
|
| -{
|
| - struct static_tracepoint_marker **marker_p = arg;
|
| -
|
| - if (*marker_p != NULL)
|
| - {
|
| - release_static_tracepoint_marker (*marker_p);
|
| - xfree (*marker_p);
|
| - }
|
| - else
|
| - *marker_p = NULL;
|
| -}
|
| -
|
| static VEC(static_tracepoint_marker_p) *
|
| remote_static_tracepoint_markers_by_strid (const char *strid)
|
| {
|
| @@ -3153,6 +3223,45 @@ send_interrupt_sequence (void)
|
| interrupt_sequence_mode);
|
| }
|
|
|
| +/* Query the remote target for which is the current thread/process,
|
| + add it to our tables, and update INFERIOR_PTID. The caller is
|
| + responsible for setting the state such that the remote end is ready
|
| + to return the current thread. */
|
| +
|
| +static void
|
| +add_current_inferior_and_thread (void)
|
| +{
|
| + struct remote_state *rs = get_remote_state ();
|
| + int fake_pid_p = 0;
|
| + ptid_t ptid;
|
| +
|
| + inferior_ptid = null_ptid;
|
| +
|
| + /* Now, if we have thread information, update inferior_ptid. */
|
| + ptid = remote_current_thread (inferior_ptid);
|
| + if (!ptid_equal (ptid, null_ptid))
|
| + {
|
| + if (!remote_multi_process_p (rs))
|
| + fake_pid_p = 1;
|
| +
|
| + inferior_ptid = ptid;
|
| + }
|
| + else
|
| + {
|
| + /* Without this, some commands which require an active target
|
| + (such as kill) won't work. This variable serves (at least)
|
| + double duty as both the pid of the target process (if it has
|
| + such), and as a flag indicating that a target is active. */
|
| + inferior_ptid = magic_null_ptid;
|
| + fake_pid_p = 1;
|
| + }
|
| +
|
| + remote_add_inferior (fake_pid_p, ptid_get_pid (inferior_ptid), -1);
|
| +
|
| + /* Add the main thread. */
|
| + add_thread_silent (inferior_ptid);
|
| +}
|
| +
|
| static void
|
| remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
|
| {
|
| @@ -3213,6 +3322,10 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
| }
|
|
|
| + /* Let the target know which signals it is allowed to pass down to
|
| + the program. */
|
| + update_signals_program_target ();
|
| +
|
| /* Next, if the target can specify a description, read it. We do
|
| this before anything involving memory or registers. */
|
| target_find_description ();
|
| @@ -3261,6 +3374,10 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
|
|
|
| if (!non_stop)
|
| {
|
| + ptid_t ptid;
|
| + int fake_pid_p = 0;
|
| + struct inferior *inf;
|
| +
|
| if (rs->buf[0] == 'W' || rs->buf[0] == 'X')
|
| {
|
| if (!extended_p)
|
| @@ -3281,22 +3398,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
|
| /* Let the stub know that we want it to return the thread. */
|
| set_continue_thread (minus_one_ptid);
|
|
|
| - /* Without this, some commands which require an active target
|
| - (such as kill) won't work. This variable serves (at least)
|
| - double duty as both the pid of the target process (if it has
|
| - such), and as a flag indicating that a target is active.
|
| - These functions should be split out into seperate variables,
|
| - especially since GDB will someday have a notion of debugging
|
| - several processes. */
|
| - inferior_ptid = magic_null_ptid;
|
| -
|
| - /* Now, if we have thread information, update inferior_ptid. */
|
| - inferior_ptid = remote_current_thread (inferior_ptid);
|
| -
|
| - remote_add_inferior (ptid_get_pid (inferior_ptid), -1);
|
| -
|
| - /* Always add the main thread. */
|
| - add_thread_silent (inferior_ptid);
|
| + add_current_inferior_and_thread ();
|
|
|
| /* init_wait_for_inferior should be called before get_offsets in order
|
| to manage `inserted' flag in bp loc in a correct state.
|
| @@ -3568,13 +3670,13 @@ remote_set_permissions (void)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
|
|
| - sprintf (rs->buf, "QAllow:"
|
| - "WriteReg:%x;WriteMem:%x;"
|
| - "InsertBreak:%x;InsertTrace:%x;"
|
| - "InsertFastTrace:%x;Stop:%x",
|
| - may_write_registers, may_write_memory,
|
| - may_insert_breakpoints, may_insert_tracepoints,
|
| - may_insert_fast_tracepoints, may_stop);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QAllow:"
|
| + "WriteReg:%x;WriteMem:%x;"
|
| + "InsertBreak:%x;InsertTrace:%x;"
|
| + "InsertFastTrace:%x;Stop:%x",
|
| + may_write_registers, may_write_memory,
|
| + may_insert_breakpoints, may_insert_tracepoints,
|
| + may_insert_fast_tracepoints, may_stop);
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
|
|
| @@ -3696,6 +3798,26 @@ remote_cond_tracepoint_feature (const struct protocol_feature *feature,
|
| }
|
|
|
| static void
|
| +remote_cond_breakpoint_feature (const struct protocol_feature *feature,
|
| + enum packet_support support,
|
| + const char *value)
|
| +{
|
| + struct remote_state *rs = get_remote_state ();
|
| +
|
| + rs->cond_breakpoints = (support == PACKET_ENABLE);
|
| +}
|
| +
|
| +static void
|
| +remote_breakpoint_commands_feature (const struct protocol_feature *feature,
|
| + enum packet_support support,
|
| + const char *value)
|
| +{
|
| + struct remote_state *rs = get_remote_state ();
|
| +
|
| + rs->breakpoint_commands = (support == PACKET_ENABLE);
|
| +}
|
| +
|
| +static void
|
| remote_fast_tracepoint_feature (const struct protocol_feature *feature,
|
| enum packet_support support,
|
| const char *value)
|
| @@ -3779,6 +3901,8 @@ static struct protocol_feature remote_protocol_features[] = {
|
| PACKET_qXfer_traceframe_info },
|
| { "QPassSignals", PACKET_DISABLE, remote_supported_packet,
|
| PACKET_QPassSignals },
|
| + { "QProgramSignals", PACKET_DISABLE, remote_supported_packet,
|
| + PACKET_QProgramSignals },
|
| { "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet,
|
| PACKET_QStartNoAckMode },
|
| { "multiprocess", PACKET_DISABLE, remote_multi_process_feature, -1 },
|
| @@ -3789,6 +3913,10 @@ static struct protocol_feature remote_protocol_features[] = {
|
| PACKET_qXfer_siginfo_write },
|
| { "ConditionalTracepoints", PACKET_DISABLE, remote_cond_tracepoint_feature,
|
| PACKET_ConditionalTracepoints },
|
| + { "ConditionalBreakpoints", PACKET_DISABLE, remote_cond_breakpoint_feature,
|
| + PACKET_ConditionalBreakpoints },
|
| + { "BreakpointCommands", PACKET_DISABLE, remote_breakpoint_commands_feature,
|
| + PACKET_BreakpointCommands },
|
| { "FastTracepoints", PACKET_DISABLE, remote_fast_tracepoint_feature,
|
| PACKET_FastTracepoints },
|
| { "StaticTracepoints", PACKET_DISABLE, remote_static_tracepoint_feature,
|
| @@ -3809,8 +3937,11 @@ static struct protocol_feature remote_protocol_features[] = {
|
| remote_enable_disable_tracepoint_feature, -1 },
|
| { "qXfer:fdpic:read", PACKET_DISABLE, remote_supported_packet,
|
| PACKET_qXfer_fdpic },
|
| + { "qXfer:uib:read", PACKET_DISABLE, remote_supported_packet,
|
| + PACKET_qXfer_uib },
|
| { "QDisableRandomization", PACKET_DISABLE, remote_supported_packet,
|
| PACKET_QDisableRandomization },
|
| + { "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
|
| { "tracenz", PACKET_DISABLE,
|
| remote_string_tracing_feature, -1 },
|
| };
|
| @@ -3879,8 +4010,7 @@ remote_query_supported (void)
|
| char *q = NULL;
|
| struct cleanup *old_chain = make_cleanup (free_current_contents, &q);
|
|
|
| - if (rs->extended)
|
| - q = remote_query_supported_append (q, "multiprocess+");
|
| + q = remote_query_supported_append (q, "multiprocess+");
|
|
|
| if (remote_support_xml)
|
| q = remote_query_supported_append (q, remote_support_xml);
|
| @@ -4045,6 +4175,11 @@ remote_open_1 (char *name, int from_tty,
|
| xfree (last_pass_packet);
|
| last_pass_packet = NULL;
|
|
|
| + /* Make sure we send the program signals list the next time we
|
| + resume. */
|
| + xfree (last_program_signals_packet);
|
| + last_program_signals_packet = NULL;
|
| +
|
| remote_fileio_reset ();
|
| reopen_exec_file ();
|
| reread_symbols ();
|
| @@ -4185,9 +4320,19 @@ remote_detach_1 (char *args, int from_tty, int extended)
|
| if (!target_has_execution)
|
| error (_("No process to detach from."));
|
|
|
| + if (from_tty)
|
| + {
|
| + char *exec_file = get_exec_file (0);
|
| + if (exec_file == NULL)
|
| + exec_file = "";
|
| + printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
|
| + target_pid_to_str (pid_to_ptid (pid)));
|
| + gdb_flush (gdb_stdout);
|
| + }
|
| +
|
| /* Tell the remote target to detach. */
|
| if (remote_multi_process_p (rs))
|
| - sprintf (rs->buf, "D;%x", pid);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "D;%x", pid);
|
| else
|
| strcpy (rs->buf, "D");
|
|
|
| @@ -4201,19 +4346,8 @@ remote_detach_1 (char *args, int from_tty, int extended)
|
| else
|
| error (_("Can't detach process."));
|
|
|
| - if (from_tty)
|
| - {
|
| - if (remote_multi_process_p (rs))
|
| - printf_filtered (_("Detached from remote %s.\n"),
|
| - target_pid_to_str (pid_to_ptid (pid)));
|
| - else
|
| - {
|
| - if (extended)
|
| - puts_filtered (_("Detached from remote process.\n"));
|
| - else
|
| - puts_filtered (_("Ending remote debugging.\n"));
|
| - }
|
| - }
|
| + if (from_tty && !extended)
|
| + puts_filtered (_("Ending remote debugging.\n"));
|
|
|
| discard_pending_stop_replies (pid);
|
| target_mourn_inferior ();
|
| @@ -4266,17 +4400,27 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
|
| if (remote_protocol_packets[PACKET_vAttach].support == PACKET_DISABLE)
|
| error (_("This target does not support attaching to a process"));
|
|
|
| - sprintf (rs->buf, "vAttach;%x", pid);
|
| + if (from_tty)
|
| + {
|
| + char *exec_file = get_exec_file (0);
|
| +
|
| + if (exec_file)
|
| + printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
|
| + target_pid_to_str (pid_to_ptid (pid)));
|
| + else
|
| + printf_unfiltered (_("Attaching to %s\n"),
|
| + target_pid_to_str (pid_to_ptid (pid)));
|
| +
|
| + gdb_flush (gdb_stdout);
|
| + }
|
| +
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "vAttach;%x", pid);
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
|
|
| if (packet_ok (rs->buf,
|
| &remote_protocol_packets[PACKET_vAttach]) == PACKET_OK)
|
| {
|
| - if (from_tty)
|
| - printf_unfiltered (_("Attached to %s\n"),
|
| - target_pid_to_str (pid_to_ptid (pid)));
|
| -
|
| if (!non_stop)
|
| {
|
| /* Save the reply for later. */
|
| @@ -4294,7 +4438,7 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
|
| error (_("Attaching to %s failed"),
|
| target_pid_to_str (pid_to_ptid (pid)));
|
|
|
| - set_current_inferior (remote_add_inferior (pid, 1));
|
| + set_current_inferior (remote_add_inferior (0, pid, 1));
|
|
|
| inferior_ptid = pid_to_ptid (pid);
|
|
|
| @@ -4487,15 +4631,15 @@ remote_vcont_probe (struct remote_state *rs)
|
|
|
| static char *
|
| append_resumption (char *p, char *endp,
|
| - ptid_t ptid, int step, enum target_signal siggnal)
|
| + ptid_t ptid, int step, enum gdb_signal siggnal)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
|
|
| - if (step && siggnal != TARGET_SIGNAL_0)
|
| + if (step && siggnal != GDB_SIGNAL_0)
|
| p += xsnprintf (p, endp - p, ";S%02x", siggnal);
|
| else if (step)
|
| p += xsnprintf (p, endp - p, ";s");
|
| - else if (siggnal != TARGET_SIGNAL_0)
|
| + else if (siggnal != GDB_SIGNAL_0)
|
| p += xsnprintf (p, endp - p, ";C%02x", siggnal);
|
| else
|
| p += xsnprintf (p, endp - p, ";c");
|
| @@ -4519,6 +4663,28 @@ append_resumption (char *p, char *endp,
|
| return p;
|
| }
|
|
|
| +/* Append a vCont continue-with-signal action for threads that have a
|
| + non-zero stop signal. */
|
| +
|
| +static char *
|
| +append_pending_thread_resumptions (char *p, char *endp, ptid_t ptid)
|
| +{
|
| + struct thread_info *thread;
|
| +
|
| + ALL_THREADS (thread)
|
| + if (ptid_match (thread->ptid, ptid)
|
| + && !ptid_equal (inferior_ptid, thread->ptid)
|
| + && thread->suspend.stop_signal != GDB_SIGNAL_0
|
| + && signal_pass_state (thread->suspend.stop_signal))
|
| + {
|
| + p = append_resumption (p, endp, thread->ptid,
|
| + 0, thread->suspend.stop_signal);
|
| + thread->suspend.stop_signal = GDB_SIGNAL_0;
|
| + }
|
| +
|
| + return p;
|
| +}
|
| +
|
| /* Resume the remote inferior by using a "vCont" packet. The thread
|
| to be resumed is PTID; STEP and SIGGNAL indicate whether the
|
| resumed thread should be single-stepped and/or signalled. If PTID
|
| @@ -4530,7 +4696,7 @@ append_resumption (char *p, char *endp,
|
| moment. */
|
|
|
| static int
|
| -remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
|
| +remote_vcont_resume (ptid_t ptid, int step, enum gdb_signal siggnal)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| char *p;
|
| @@ -4565,14 +4731,18 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
|
| process), with preference for INFERIOR_PTID. This assumes
|
| inferior_ptid belongs to the set of all threads we are about
|
| to resume. */
|
| - if (step || siggnal != TARGET_SIGNAL_0)
|
| + if (step || siggnal != GDB_SIGNAL_0)
|
| {
|
| /* Step inferior_ptid, with or without signal. */
|
| p = append_resumption (p, endp, inferior_ptid, step, siggnal);
|
| }
|
|
|
| + /* Also pass down any pending signaled resumption for other
|
| + threads not the current. */
|
| + p = append_pending_thread_resumptions (p, endp, ptid);
|
| +
|
| /* And continue others without a signal. */
|
| - append_resumption (p, endp, ptid, /*step=*/ 0, TARGET_SIGNAL_0);
|
| + append_resumption (p, endp, ptid, /*step=*/ 0, GDB_SIGNAL_0);
|
| }
|
| else
|
| {
|
| @@ -4598,13 +4768,13 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
|
|
|
| /* Tell the remote machine to resume. */
|
|
|
| -static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
|
| +static enum gdb_signal last_sent_signal = GDB_SIGNAL_0;
|
|
|
| static int last_sent_step;
|
|
|
| static void
|
| remote_resume (struct target_ops *ops,
|
| - ptid_t ptid, int step, enum target_signal siggnal)
|
| + ptid_t ptid, int step, enum gdb_signal siggnal)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| char *buf;
|
| @@ -4629,7 +4799,7 @@ remote_resume (struct target_ops *ops,
|
| if (execution_direction == EXEC_REVERSE)
|
| {
|
| /* We don't pass signals to the target in reverse exec mode. */
|
| - if (info_verbose && siggnal != TARGET_SIGNAL_0)
|
| + if (info_verbose && siggnal != GDB_SIGNAL_0)
|
| warning (_(" - Can't pass signal %d to target in reverse: ignored."),
|
| siggnal);
|
|
|
| @@ -4642,7 +4812,7 @@ remote_resume (struct target_ops *ops,
|
|
|
| strcpy (buf, step ? "bs" : "bc");
|
| }
|
| - else if (siggnal != TARGET_SIGNAL_0)
|
| + else if (siggnal != GDB_SIGNAL_0)
|
| {
|
| buf[0] = step ? 'S' : 'C';
|
| buf[1] = tohex (((int) siggnal >> 4) & 0xf);
|
| @@ -4709,7 +4879,7 @@ static void
|
| async_remote_interrupt (gdb_client_data arg)
|
| {
|
| if (remote_debug)
|
| - fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
|
| + fprintf_unfiltered (gdb_stdlog, "async_remote_interrupt called\n");
|
|
|
| target_stop (inferior_ptid);
|
| }
|
| @@ -4720,7 +4890,7 @@ void
|
| async_remote_interrupt_twice (gdb_client_data arg)
|
| {
|
| if (remote_debug)
|
| - fprintf_unfiltered (gdb_stdlog, "remote_interrupt_twice called\n");
|
| + fprintf_unfiltered (gdb_stdlog, "async_remote_interrupt_twice called\n");
|
|
|
| interrupt_query ();
|
| }
|
| @@ -5259,7 +5429,7 @@ Packet: '%s'\n"),
|
| else
|
| {
|
| event->ws.kind = TARGET_WAITKIND_STOPPED;
|
| - event->ws.value.sig = (enum target_signal)
|
| + event->ws.value.sig = (enum gdb_signal)
|
| (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
|
| }
|
| break;
|
| @@ -5285,7 +5455,7 @@ Packet: '%s'\n"),
|
| {
|
| /* The remote process exited with a signal. */
|
| event->ws.kind = TARGET_WAITKIND_SIGNALLED;
|
| - event->ws.value.sig = (enum target_signal) value;
|
| + event->ws.value.sig = (enum gdb_signal) value;
|
| }
|
|
|
| /* If no process is specified, assume inferior_ptid. */
|
| @@ -5578,7 +5748,7 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
|
| not? Not is more likely, so report a stop. */
|
| warning (_("Remote failure reply: %s"), buf);
|
| status->kind = TARGET_WAITKIND_STOPPED;
|
| - status->value.sig = TARGET_SIGNAL_0;
|
| + status->value.sig = GDB_SIGNAL_0;
|
| break;
|
| case 'F': /* File-I/O request. */
|
| remote_fileio_request (buf, rs->ctrlc_pending_p);
|
| @@ -5604,15 +5774,15 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
|
|
|
| break;
|
| case '\0':
|
| - if (last_sent_signal != TARGET_SIGNAL_0)
|
| + if (last_sent_signal != GDB_SIGNAL_0)
|
| {
|
| /* Zero length reply means that we tried 'S' or 'C' and the
|
| remote system doesn't support it. */
|
| target_terminal_ours_for_output ();
|
| printf_filtered
|
| ("Can't send signals to this remote system. %s not sent.\n",
|
| - target_signal_to_name (last_sent_signal));
|
| - last_sent_signal = TARGET_SIGNAL_0;
|
| + gdb_signal_to_name (last_sent_signal));
|
| + last_sent_signal = GDB_SIGNAL_0;
|
| target_terminal_inferior ();
|
|
|
| strcpy ((char *) buf, last_sent_step ? "s" : "c");
|
| @@ -5748,7 +5918,7 @@ send_g_packet (void)
|
| struct remote_state *rs = get_remote_state ();
|
| int buf_len;
|
|
|
| - sprintf (rs->buf, "g");
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "g");
|
| remote_send (&rs->buf, &rs->buf_size);
|
|
|
| /* We can get out of synch in various cases. If the first character
|
| @@ -6325,7 +6495,7 @@ check_binary_download (CORE_ADDR addr)
|
|
|
| static int
|
| remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
|
| - const gdb_byte *myaddr, int len,
|
| + const gdb_byte *myaddr, ssize_t len,
|
| char packet_format, int use_length)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| @@ -6486,7 +6656,7 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
|
| error. Only transfer a single packet. */
|
|
|
| static int
|
| -remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
|
| +remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
|
| {
|
| char *packet_format = 0;
|
|
|
| @@ -7413,7 +7583,7 @@ remote_vkill (int pid, struct remote_state *rs)
|
| return -1;
|
|
|
| /* Tell the remote target to detach. */
|
| - sprintf (rs->buf, "vKill;%x", pid);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "vKill;%x", pid);
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
|
|
| @@ -7434,7 +7604,7 @@ extended_remote_kill (struct target_ops *ops)
|
| struct remote_state *rs = get_remote_state ();
|
|
|
| res = remote_vkill (pid, rs);
|
| - if (res == -1 && !remote_multi_process_p (rs))
|
| + if (res == -1 && !(rs->extended && remote_multi_process_p (rs)))
|
| {
|
| /* Don't try 'k' on a multi-process aware stub -- it has no way
|
| to specify the pid. */
|
| @@ -7556,7 +7726,8 @@ extended_remote_disable_randomization (int val)
|
| struct remote_state *rs = get_remote_state ();
|
| char *reply;
|
|
|
| - sprintf (rs->buf, "QDisableRandomization:%x", val);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QDisableRandomization:%x",
|
| + val);
|
| putpkt (rs->buf);
|
| reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
|
| if (*reply == '\0')
|
| @@ -7668,14 +7839,7 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
|
| init_wait_for_inferior ();
|
| }
|
|
|
| - /* Now mark the inferior as running before we do anything else. */
|
| - inferior_ptid = magic_null_ptid;
|
| -
|
| - /* Now, if we have thread information, update inferior_ptid. */
|
| - inferior_ptid = remote_current_thread (inferior_ptid);
|
| -
|
| - remote_add_inferior (ptid_get_pid (inferior_ptid), 0);
|
| - add_thread_silent (inferior_ptid);
|
| + add_current_inferior_and_thread ();
|
|
|
| /* Get updated offsets, if the stub uses qOffsets. */
|
| get_offsets ();
|
| @@ -7690,6 +7854,75 @@ extended_remote_create_inferior (struct target_ops *ops,
|
| }
|
|
|
|
|
| +/* Given a location's target info BP_TGT and the packet buffer BUF, output
|
| + the list of conditions (in agent expression bytecode format), if any, the
|
| + target needs to evaluate. The output is placed into the packet buffer
|
| + started from BUF and ended at BUF_END. */
|
| +
|
| +static int
|
| +remote_add_target_side_condition (struct gdbarch *gdbarch,
|
| + struct bp_target_info *bp_tgt, char *buf,
|
| + char *buf_end)
|
| +{
|
| + struct agent_expr *aexpr = NULL;
|
| + int i, ix;
|
| + char *pkt;
|
| + char *buf_start = buf;
|
| +
|
| + if (VEC_empty (agent_expr_p, bp_tgt->conditions))
|
| + return 0;
|
| +
|
| + buf += strlen (buf);
|
| + xsnprintf (buf, buf_end - buf, "%s", ";");
|
| + buf++;
|
| +
|
| + /* Send conditions to the target and free the vector. */
|
| + for (ix = 0;
|
| + VEC_iterate (agent_expr_p, bp_tgt->conditions, ix, aexpr);
|
| + ix++)
|
| + {
|
| + xsnprintf (buf, buf_end - buf, "X%x,", aexpr->len);
|
| + buf += strlen (buf);
|
| + for (i = 0; i < aexpr->len; ++i)
|
| + buf = pack_hex_byte (buf, aexpr->buf[i]);
|
| + *buf = '\0';
|
| + }
|
| +
|
| + VEC_free (agent_expr_p, bp_tgt->conditions);
|
| + return 0;
|
| +}
|
| +
|
| +static void
|
| +remote_add_target_side_commands (struct gdbarch *gdbarch,
|
| + struct bp_target_info *bp_tgt, char *buf)
|
| +{
|
| + struct agent_expr *aexpr = NULL;
|
| + int i, ix;
|
| +
|
| + if (VEC_empty (agent_expr_p, bp_tgt->tcommands))
|
| + return;
|
| +
|
| + buf += strlen (buf);
|
| +
|
| + sprintf (buf, ";cmds:%x,", bp_tgt->persist);
|
| + buf += strlen (buf);
|
| +
|
| + /* Concatenate all the agent expressions that are commands into the
|
| + cmds parameter. */
|
| + for (ix = 0;
|
| + VEC_iterate (agent_expr_p, bp_tgt->tcommands, ix, aexpr);
|
| + ix++)
|
| + {
|
| + sprintf (buf, "X%x,", aexpr->len);
|
| + buf += strlen (buf);
|
| + for (i = 0; i < aexpr->len; ++i)
|
| + buf = pack_hex_byte (buf, aexpr->buf[i]);
|
| + *buf = '\0';
|
| + }
|
| +
|
| + VEC_free (agent_expr_p, bp_tgt->tcommands);
|
| +}
|
| +
|
| /* Insert a breakpoint. On targets that have software breakpoint
|
| support, we ask the remote target to do the work; on targets
|
| which don't, we insert a traditional memory breakpoint. */
|
| @@ -7707,20 +7940,28 @@ remote_insert_breakpoint (struct gdbarch *gdbarch,
|
| {
|
| CORE_ADDR addr = bp_tgt->placed_address;
|
| struct remote_state *rs;
|
| - char *p;
|
| + char *p, *endbuf;
|
| int bpsize;
|
| + struct condition_list *cond = NULL;
|
|
|
| gdbarch_remote_breakpoint_from_pc (gdbarch, &addr, &bpsize);
|
|
|
| rs = get_remote_state ();
|
| p = rs->buf;
|
| + endbuf = rs->buf + get_remote_packet_size ();
|
|
|
| *(p++) = 'Z';
|
| *(p++) = '0';
|
| *(p++) = ',';
|
| addr = (ULONGEST) remote_address_masked (addr);
|
| p += hexnumstr (p, addr);
|
| - sprintf (p, ",%d", bpsize);
|
| + xsnprintf (p, endbuf - p, ",%d", bpsize);
|
| +
|
| + if (remote_supports_cond_breakpoints ())
|
| + remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
|
| +
|
| + if (remote_can_run_breakpoint_commands ())
|
| + remote_add_target_side_commands (gdbarch, bp_tgt, p);
|
|
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
| @@ -7751,6 +7992,7 @@ remote_remove_breakpoint (struct gdbarch *gdbarch,
|
| if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
|
| {
|
| char *p = rs->buf;
|
| + char *endbuf = rs->buf + get_remote_packet_size ();
|
|
|
| *(p++) = 'z';
|
| *(p++) = '0';
|
| @@ -7758,7 +8000,7 @@ remote_remove_breakpoint (struct gdbarch *gdbarch,
|
|
|
| addr = (ULONGEST) remote_address_masked (bp_tgt->placed_address);
|
| p += hexnumstr (p, addr);
|
| - sprintf (p, ",%d", bp_tgt->placed_size);
|
| + xsnprintf (p, endbuf - p, ",%d", bp_tgt->placed_size);
|
|
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
| @@ -7794,17 +8036,18 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type,
|
| struct expression *cond)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| + char *endbuf = rs->buf + get_remote_packet_size ();
|
| char *p;
|
| enum Z_packet_type packet = watchpoint_to_Z_packet (type);
|
|
|
| if (remote_protocol_packets[PACKET_Z0 + packet].support == PACKET_DISABLE)
|
| return 1;
|
|
|
| - sprintf (rs->buf, "Z%x,", packet);
|
| + xsnprintf (rs->buf, endbuf - rs->buf, "Z%x,", packet);
|
| p = strchr (rs->buf, '\0');
|
| addr = remote_address_masked (addr);
|
| p += hexnumstr (p, (ULONGEST) addr);
|
| - sprintf (p, ",%x", len);
|
| + xsnprintf (p, endbuf - p, ",%x", len);
|
|
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
| @@ -7822,23 +8065,33 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type,
|
| _("remote_insert_watchpoint: reached end of function"));
|
| }
|
|
|
| +static int
|
| +remote_watchpoint_addr_within_range (struct target_ops *target, CORE_ADDR addr,
|
| + CORE_ADDR start, int length)
|
| +{
|
| + CORE_ADDR diff = remote_address_masked (addr - start);
|
| +
|
| + return diff < length;
|
| +}
|
| +
|
|
|
| static int
|
| remote_remove_watchpoint (CORE_ADDR addr, int len, int type,
|
| struct expression *cond)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| + char *endbuf = rs->buf + get_remote_packet_size ();
|
| char *p;
|
| enum Z_packet_type packet = watchpoint_to_Z_packet (type);
|
|
|
| if (remote_protocol_packets[PACKET_Z0 + packet].support == PACKET_DISABLE)
|
| return -1;
|
|
|
| - sprintf (rs->buf, "z%x,", packet);
|
| + xsnprintf (rs->buf, endbuf - rs->buf, "z%x,", packet);
|
| p = strchr (rs->buf, '\0');
|
| addr = remote_address_masked (addr);
|
| p += hexnumstr (p, (ULONGEST) addr);
|
| - sprintf (p, ",%x", len);
|
| + xsnprintf (p, endbuf - p, ",%x", len);
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
|
|
| @@ -7925,7 +8178,7 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch,
|
| {
|
| CORE_ADDR addr;
|
| struct remote_state *rs;
|
| - char *p;
|
| + char *p, *endbuf;
|
|
|
| /* The length field should be set to the size of a breakpoint
|
| instruction, even though we aren't inserting one ourselves. */
|
| @@ -7938,6 +8191,7 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch,
|
|
|
| rs = get_remote_state ();
|
| p = rs->buf;
|
| + endbuf = rs->buf + get_remote_packet_size ();
|
|
|
| *(p++) = 'Z';
|
| *(p++) = '1';
|
| @@ -7945,7 +8199,13 @@ remote_insert_hw_breakpoint (struct gdbarch *gdbarch,
|
|
|
| addr = remote_address_masked (bp_tgt->placed_address);
|
| p += hexnumstr (p, (ULONGEST) addr);
|
| - sprintf (p, ",%x", bp_tgt->placed_size);
|
| + xsnprintf (p, endbuf - p, ",%x", bp_tgt->placed_size);
|
| +
|
| + if (remote_supports_cond_breakpoints ())
|
| + remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
|
| +
|
| + if (remote_can_run_breakpoint_commands ())
|
| + remote_add_target_side_commands (gdbarch, bp_tgt, p);
|
|
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
| @@ -7970,6 +8230,7 @@ remote_remove_hw_breakpoint (struct gdbarch *gdbarch,
|
| CORE_ADDR addr;
|
| struct remote_state *rs = get_remote_state ();
|
| char *p = rs->buf;
|
| + char *endbuf = rs->buf + get_remote_packet_size ();
|
|
|
| if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE)
|
| return -1;
|
| @@ -7980,7 +8241,7 @@ remote_remove_hw_breakpoint (struct gdbarch *gdbarch,
|
|
|
| addr = remote_address_masked (bp_tgt->placed_address);
|
| p += hexnumstr (p, (ULONGEST) addr);
|
| - sprintf (p, ",%x", bp_tgt->placed_size);
|
| + xsnprintf (p, endbuf - p, ",%x", bp_tgt->placed_size);
|
|
|
| putpkt (rs->buf);
|
| getpkt (&rs->buf, &rs->buf_size, 0);
|
| @@ -8404,6 +8665,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
|
| case TARGET_OBJECT_FDPIC:
|
| return remote_read_qxfer (ops, "fdpic", annex, readbuf, offset, len,
|
| &remote_protocol_packets[PACKET_qXfer_fdpic]);
|
| +
|
| + case TARGET_OBJECT_OPENVMS_UIB:
|
| + return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
|
| + &remote_protocol_packets[PACKET_qXfer_uib]);
|
| +
|
| default:
|
| return -1;
|
| }
|
| @@ -8577,8 +8843,17 @@ remote_rcmd (char *command,
|
| char *buf;
|
|
|
| /* XXX - see also remote_get_noisy_reply(). */
|
| + QUIT; /* Allow user to bail out with ^C. */
|
| rs->buf[0] = '\0';
|
| - getpkt (&rs->buf, &rs->buf_size, 0);
|
| + if (getpkt_sane (&rs->buf, &rs->buf_size, 0) == -1)
|
| + {
|
| + /* Timeout. Continue to (try to) read responses.
|
| + This is better than stopping with an error, assuming the stub
|
| + is still executing the (long) monitor command.
|
| + If needed, the user can interrupt gdb using C-c, obtaining
|
| + an effect similar to stop on timeout. */
|
| + continue;
|
| + }
|
| buf = rs->buf;
|
| if (buf[0] == '\0')
|
| error (_("Target does not support this command."));
|
| @@ -8801,7 +9076,9 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
|
| static char buf[64];
|
| struct remote_state *rs = get_remote_state ();
|
|
|
| - if (ptid_is_pid (ptid))
|
| + if (ptid_equal (ptid, null_ptid))
|
| + return normal_pid_to_str (ptid);
|
| + else if (ptid_is_pid (ptid))
|
| {
|
| /* Printing an inferior target id. */
|
|
|
| @@ -8826,7 +9103,7 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
|
| {
|
| if (ptid_equal (magic_null_ptid, ptid))
|
| xsnprintf (buf, sizeof buf, "Thread <main>");
|
| - else if (remote_multi_process_p (rs))
|
| + else if (rs->extended && remote_multi_process_p (rs))
|
| xsnprintf (buf, sizeof buf, "Thread %d.%ld",
|
| ptid_get_pid (ptid), ptid_get_tid (ptid));
|
| else
|
| @@ -8887,7 +9164,7 @@ remote_get_thread_local_address (struct target_ops *ops,
|
| /* Provide thread local base, i.e. Thread Information Block address.
|
| Returns 1 if ptid is found and thread_local_base is non zero. */
|
|
|
| -int
|
| +static int
|
| remote_get_tib_address (ptid_t ptid, CORE_ADDR *addr)
|
| {
|
| if (remote_protocol_packets[PACKET_qGetTIBAddr].support != PACKET_DISABLE)
|
| @@ -9353,6 +9630,44 @@ remote_hostio_unlink (const char *filename, int *remote_errno)
|
| remote_errno, NULL, NULL);
|
| }
|
|
|
| +/* Read value of symbolic link FILENAME on the remote target. Return
|
| + a null-terminated string allocated via xmalloc, or NULL if an error
|
| + occurs (and set *REMOTE_ERRNO). */
|
| +
|
| +static char *
|
| +remote_hostio_readlink (const char *filename, int *remote_errno)
|
| +{
|
| + struct remote_state *rs = get_remote_state ();
|
| + char *p = rs->buf;
|
| + char *attachment;
|
| + int left = get_remote_packet_size ();
|
| + int len, attachment_len;
|
| + int read_len;
|
| + char *ret;
|
| +
|
| + remote_buffer_add_string (&p, &left, "vFile:readlink:");
|
| +
|
| + remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
|
| + strlen (filename));
|
| +
|
| + len = remote_hostio_send_command (p - rs->buf, PACKET_vFile_readlink,
|
| + remote_errno, &attachment,
|
| + &attachment_len);
|
| +
|
| + if (len < 0)
|
| + return NULL;
|
| +
|
| + ret = xmalloc (len + 1);
|
| +
|
| + read_len = remote_unescape_input (attachment, attachment_len,
|
| + ret, len);
|
| + if (read_len != len)
|
| + error (_("Readlink returned %d, but %d bytes."), len, read_len);
|
| +
|
| + ret[len] = '\0';
|
| + return ret;
|
| +}
|
| +
|
| static int
|
| remote_fileio_errno_to_host (int errnum)
|
| {
|
| @@ -9767,10 +10082,14 @@ remote_supports_multi_process (void)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
|
|
| - return remote_multi_process_p (rs);
|
| + /* Only extended-remote handles being attached to multiple
|
| + processes, even though plain remote can use the multi-process
|
| + thread id extensions, so that GDB knows the target process's
|
| + PID. */
|
| + return rs->extended && remote_multi_process_p (rs);
|
| }
|
|
|
| -int
|
| +static int
|
| remote_supports_cond_tracepoints (void)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| @@ -9778,7 +10097,15 @@ remote_supports_cond_tracepoints (void)
|
| return rs->cond_tracepoints;
|
| }
|
|
|
| -int
|
| +static int
|
| +remote_supports_cond_breakpoints (void)
|
| +{
|
| + struct remote_state *rs = get_remote_state ();
|
| +
|
| + return rs->cond_breakpoints;
|
| +}
|
| +
|
| +static int
|
| remote_supports_fast_tracepoints (void)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| @@ -9818,6 +10145,14 @@ remote_supports_string_tracing (void)
|
| return rs->string_tracing;
|
| }
|
|
|
| +static int
|
| +remote_can_run_breakpoint_commands (void)
|
| +{
|
| + struct remote_state *rs = get_remote_state ();
|
| +
|
| + return rs->breakpoint_commands;
|
| +}
|
| +
|
| static void
|
| remote_trace_init (void)
|
| {
|
| @@ -9892,10 +10227,11 @@ remote_download_command_source (int num, ULONGEST addr,
|
| static void
|
| remote_download_tracepoint (struct bp_location *loc)
|
| {
|
| +#define BUF_SIZE 2048
|
|
|
| CORE_ADDR tpaddr;
|
| char addrbuf[40];
|
| - char buf[2048];
|
| + char buf[BUF_SIZE];
|
| char **tdp_actions;
|
| char **stepping_actions;
|
| int ndx;
|
| @@ -9914,10 +10250,10 @@ remote_download_tracepoint (struct bp_location *loc)
|
|
|
| tpaddr = loc->address;
|
| sprintf_vma (addrbuf, tpaddr);
|
| - sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", b->number,
|
| - addrbuf, /* address */
|
| - (b->enable_state == bp_enabled ? 'E' : 'D'),
|
| - t->step_count, t->pass_count);
|
| + xsnprintf (buf, BUF_SIZE, "QTDP:%x:%s:%c:%lx:%x", b->number,
|
| + addrbuf, /* address */
|
| + (b->enable_state == bp_enabled ? 'E' : 'D'),
|
| + t->step_count, t->pass_count);
|
| /* Fast tracepoints are mostly handled by the target, but we can
|
| tell the target how big of an instruction block should be moved
|
| around. */
|
| @@ -9931,7 +10267,8 @@ remote_download_tracepoint (struct bp_location *loc)
|
|
|
| if (gdbarch_fast_tracepoint_valid_at (target_gdbarch,
|
| tpaddr, &isize, NULL))
|
| - sprintf (buf + strlen (buf), ":F%x", isize);
|
| + xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":F%x",
|
| + isize);
|
| else
|
| /* If it passed validation at definition but fails now,
|
| something is very wrong. */
|
| @@ -9975,7 +10312,8 @@ remote_download_tracepoint (struct bp_location *loc)
|
| {
|
| aexpr = gen_eval_for_expr (tpaddr, loc->cond);
|
| aexpr_chain = make_cleanup_free_agent_expr (aexpr);
|
| - sprintf (buf + strlen (buf), ":X%x,", aexpr->len);
|
| + xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":X%x,",
|
| + aexpr->len);
|
| pkt = buf + strlen (buf);
|
| for (ndx = 0; ndx < aexpr->len; ++ndx)
|
| pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
|
| @@ -10000,11 +10338,11 @@ remote_download_tracepoint (struct bp_location *loc)
|
| for (ndx = 0; tdp_actions[ndx]; ndx++)
|
| {
|
| QUIT; /* Allow user to bail out with ^C. */
|
| - sprintf (buf, "QTDP:-%x:%s:%s%c",
|
| - b->number, addrbuf, /* address */
|
| - tdp_actions[ndx],
|
| - ((tdp_actions[ndx + 1] || stepping_actions)
|
| - ? '-' : 0));
|
| + xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%c",
|
| + b->number, addrbuf, /* address */
|
| + tdp_actions[ndx],
|
| + ((tdp_actions[ndx + 1] || stepping_actions)
|
| + ? '-' : 0));
|
| putpkt (buf);
|
| remote_get_noisy_reply (&target_buf,
|
| &target_buf_size);
|
| @@ -10017,11 +10355,11 @@ remote_download_tracepoint (struct bp_location *loc)
|
| for (ndx = 0; stepping_actions[ndx]; ndx++)
|
| {
|
| QUIT; /* Allow user to bail out with ^C. */
|
| - sprintf (buf, "QTDP:-%x:%s:%s%s%s",
|
| - b->number, addrbuf, /* address */
|
| - ((ndx == 0) ? "S" : ""),
|
| - stepping_actions[ndx],
|
| - (stepping_actions[ndx + 1] ? "-" : ""));
|
| + xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%s%s",
|
| + b->number, addrbuf, /* address */
|
| + ((ndx == 0) ? "S" : ""),
|
| + stepping_actions[ndx],
|
| + (stepping_actions[ndx + 1] ? "-" : ""));
|
| putpkt (buf);
|
| remote_get_noisy_reply (&target_buf,
|
| &target_buf_size);
|
| @@ -10097,8 +10435,9 @@ remote_download_trace_state_variable (struct trace_state_variable *tsv)
|
| struct remote_state *rs = get_remote_state ();
|
| char *p;
|
|
|
| - sprintf (rs->buf, "QTDV:%x:%s:%x:",
|
| - tsv->number, phex ((ULONGEST) tsv->initial_value, 8), tsv->builtin);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QTDV:%x:%s:%x:",
|
| + tsv->number, phex ((ULONGEST) tsv->initial_value, 8),
|
| + tsv->builtin);
|
| p = rs->buf + strlen (rs->buf);
|
| if ((p - rs->buf) + strlen (tsv->name) * 2 >= get_remote_packet_size ())
|
| error (_("Trace state variable name too long for tsv definition packet"));
|
| @@ -10119,7 +10458,8 @@ remote_enable_tracepoint (struct bp_location *location)
|
| char addr_buf[40];
|
|
|
| sprintf_vma (addr_buf, location->address);
|
| - sprintf (rs->buf, "QTEnable:%x:%s", location->owner->number, addr_buf);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QTEnable:%x:%s",
|
| + location->owner->number, addr_buf);
|
| putpkt (rs->buf);
|
| remote_get_noisy_reply (&rs->buf, &rs->buf_size);
|
| if (*rs->buf == '\0')
|
| @@ -10135,7 +10475,8 @@ remote_disable_tracepoint (struct bp_location *location)
|
| char addr_buf[40];
|
|
|
| sprintf_vma (addr_buf, location->address);
|
| - sprintf (rs->buf, "QTDisable:%x:%s", location->owner->number, addr_buf);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QTDisable:%x:%s",
|
| + location->owner->number, addr_buf);
|
| putpkt (rs->buf);
|
| remote_get_noisy_reply (&rs->buf, &rs->buf_size);
|
| if (*rs->buf == '\0')
|
| @@ -10148,6 +10489,7 @@ static void
|
| remote_trace_set_readonly_regions (void)
|
| {
|
| asection *s;
|
| + bfd *abfd = NULL;
|
| bfd_size_type size;
|
| bfd_vma vma;
|
| int anysecs = 0;
|
| @@ -10168,7 +10510,7 @@ remote_trace_set_readonly_regions (void)
|
| continue;
|
|
|
| anysecs = 1;
|
| - vma = bfd_get_section_vma (,s);
|
| + vma = bfd_get_section_vma (abfd, s);
|
| size = bfd_get_section_size (s);
|
| sprintf_vma (tmp1, vma);
|
| sprintf_vma (tmp2, vma + size);
|
| @@ -10181,7 +10523,8 @@ remote_trace_set_readonly_regions (void)
|
| Too many sections for read-only sections definition packet."));
|
| break;
|
| }
|
| - sprintf (target_buf + offset, ":%s,%s", tmp1, tmp2);
|
| + xsnprintf (target_buf + offset, target_buf_size - offset, ":%s,%s",
|
| + tmp1, tmp2);
|
| offset += sec_length;
|
| }
|
| if (anysecs)
|
| @@ -10246,7 +10589,7 @@ remote_get_trace_status (struct trace_status *ts)
|
| return ts->running;
|
| }
|
|
|
| -void
|
| +static void
|
| remote_get_tracepoint_status (struct breakpoint *bp,
|
| struct uploaded_tp *utp)
|
| {
|
| @@ -10254,6 +10597,7 @@ remote_get_tracepoint_status (struct breakpoint *bp,
|
| char *reply;
|
| struct bp_location *loc;
|
| struct tracepoint *tp = (struct tracepoint *) bp;
|
| + size_t size = get_remote_packet_size ();
|
|
|
| if (tp)
|
| {
|
| @@ -10265,8 +10609,8 @@ remote_get_tracepoint_status (struct breakpoint *bp,
|
| any status. */
|
| if (tp->number_on_target == 0)
|
| continue;
|
| - sprintf (rs->buf, "qTP:%x:%s", tp->number_on_target,
|
| - phex_nz (loc->address, 0));
|
| + xsnprintf (rs->buf, size, "qTP:%x:%s", tp->number_on_target,
|
| + phex_nz (loc->address, 0));
|
| putpkt (rs->buf);
|
| reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
|
| if (reply && *reply)
|
| @@ -10280,7 +10624,8 @@ remote_get_tracepoint_status (struct breakpoint *bp,
|
| {
|
| utp->hit_count = 0;
|
| utp->traceframe_usage = 0;
|
| - sprintf (rs->buf, "qTP:%x:%s", utp->number, phex_nz (utp->addr, 0));
|
| + xsnprintf (rs->buf, size, "qTP:%x:%s", utp->number,
|
| + phex_nz (utp->addr, 0));
|
| putpkt (rs->buf);
|
| reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
|
| if (reply && *reply)
|
| @@ -10308,6 +10653,7 @@ remote_trace_find (enum trace_find_type type, int num,
|
| int *tpp)
|
| {
|
| struct remote_state *rs = get_remote_state ();
|
| + char *endbuf = rs->buf + get_remote_packet_size ();
|
| char *p, *reply;
|
| int target_frameno = -1, target_tracept = -1;
|
|
|
| @@ -10323,19 +10669,21 @@ remote_trace_find (enum trace_find_type type, int num,
|
| switch (type)
|
| {
|
| case tfind_number:
|
| - sprintf (p, "%x", num);
|
| + xsnprintf (p, endbuf - p, "%x", num);
|
| break;
|
| case tfind_pc:
|
| - sprintf (p, "pc:%s", phex_nz (addr1, 0));
|
| + xsnprintf (p, endbuf - p, "pc:%s", phex_nz (addr1, 0));
|
| break;
|
| case tfind_tp:
|
| - sprintf (p, "tdp:%x", num);
|
| + xsnprintf (p, endbuf - p, "tdp:%x", num);
|
| break;
|
| case tfind_range:
|
| - sprintf (p, "range:%s:%s", phex_nz (addr1, 0), phex_nz (addr2, 0));
|
| + xsnprintf (p, endbuf - p, "range:%s:%s", phex_nz (addr1, 0),
|
| + phex_nz (addr2, 0));
|
| break;
|
| case tfind_outside:
|
| - sprintf (p, "outside:%s:%s", phex_nz (addr1, 0), phex_nz (addr2, 0));
|
| + xsnprintf (p, endbuf - p, "outside:%s:%s", phex_nz (addr1, 0),
|
| + phex_nz (addr2, 0));
|
| break;
|
| default:
|
| error (_("Unknown trace find type %d"), type);
|
| @@ -10390,7 +10738,7 @@ remote_get_trace_state_variable_value (int tsvnum, LONGEST *val)
|
|
|
| set_remote_traceframe ();
|
|
|
| - sprintf (rs->buf, "qTV:%x", tsvnum);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "qTV:%x", tsvnum);
|
| putpkt (rs->buf);
|
| reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
|
| if (reply && *reply)
|
| @@ -10479,7 +10827,7 @@ remote_set_disconnected_tracing (int val)
|
| {
|
| char *reply;
|
|
|
| - sprintf (rs->buf, "QTDisconnected:%x", val);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QTDisconnected:%x", val);
|
| putpkt (rs->buf);
|
| reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
|
| if (*reply == '\0')
|
| @@ -10507,7 +10855,7 @@ remote_set_circular_trace_buffer (int val)
|
| struct remote_state *rs = get_remote_state ();
|
| char *reply;
|
|
|
| - sprintf (rs->buf, "QTBuffer:circular:%x", val);
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QTBuffer:circular:%x", val);
|
| putpkt (rs->buf);
|
| reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
|
| if (*reply == '\0')
|
| @@ -10547,7 +10895,15 @@ remote_get_min_fast_tracepoint_insn_len (void)
|
| struct remote_state *rs = get_remote_state ();
|
| char *reply;
|
|
|
| - sprintf (rs->buf, "qTMinFTPILen");
|
| + /* If we're not debugging a process yet, the IPA can't be
|
| + loaded. */
|
| + if (!target_has_execution)
|
| + return 0;
|
| +
|
| + /* Make sure the remote is pointing at the right process. */
|
| + set_general_process ();
|
| +
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "qTMinFTPILen");
|
| putpkt (rs->buf);
|
| reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
|
| if (*reply == '\0')
|
| @@ -10607,6 +10963,34 @@ remote_set_trace_notes (char *user, char *notes, char *stop_notes)
|
| return 1;
|
| }
|
|
|
| +static int
|
| +remote_use_agent (int use)
|
| +{
|
| + if (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE)
|
| + {
|
| + struct remote_state *rs = get_remote_state ();
|
| +
|
| + /* If the stub supports QAgent. */
|
| + xsnprintf (rs->buf, get_remote_packet_size (), "QAgent:%d", use);
|
| + putpkt (rs->buf);
|
| + getpkt (&rs->buf, &rs->buf_size, 0);
|
| +
|
| + if (strcmp (rs->buf, "OK") == 0)
|
| + {
|
| + use_agent = use;
|
| + return 1;
|
| + }
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +static int
|
| +remote_can_use_agent (void)
|
| +{
|
| + return (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE);
|
| +}
|
| +
|
| static void
|
| init_remote_ops (void)
|
| {
|
| @@ -10631,6 +11015,8 @@ Specify the serial device it is connected to\n\
|
| remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
|
| remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
|
| remote_ops.to_stopped_data_address = remote_stopped_data_address;
|
| + remote_ops.to_watchpoint_addr_within_range =
|
| + remote_watchpoint_addr_within_range;
|
| remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
|
| remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
|
| remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
|
| @@ -10642,6 +11028,7 @@ Specify the serial device it is connected to\n\
|
| remote_ops.to_load = generic_load;
|
| remote_ops.to_mourn_inferior = remote_mourn;
|
| remote_ops.to_pass_signals = remote_pass_signals;
|
| + remote_ops.to_program_signals = remote_program_signals;
|
| remote_ops.to_thread_alive = remote_thread_alive;
|
| remote_ops.to_find_new_threads = remote_threads_info;
|
| remote_ops.to_pid_to_str = remote_pid_to_str;
|
| @@ -10675,8 +11062,16 @@ Specify the serial device it is connected to\n\
|
| remote_ops.to_supports_multi_process = remote_supports_multi_process;
|
| remote_ops.to_supports_disable_randomization
|
| = remote_supports_disable_randomization;
|
| + remote_ops.to_fileio_open = remote_hostio_open;
|
| + remote_ops.to_fileio_pwrite = remote_hostio_pwrite;
|
| + remote_ops.to_fileio_pread = remote_hostio_pread;
|
| + remote_ops.to_fileio_close = remote_hostio_close;
|
| + remote_ops.to_fileio_unlink = remote_hostio_unlink;
|
| + remote_ops.to_fileio_readlink = remote_hostio_readlink;
|
| remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
|
| remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
|
| + remote_ops.to_supports_evaluation_of_breakpoint_conditions = remote_supports_cond_breakpoints;
|
| + remote_ops.to_can_run_breakpoint_commands = remote_can_run_breakpoint_commands;
|
| remote_ops.to_trace_init = remote_trace_init;
|
| remote_ops.to_download_tracepoint = remote_download_tracepoint;
|
| remote_ops.to_can_download_tracepoint = remote_can_download_tracepoint;
|
| @@ -10710,6 +11105,8 @@ Specify the serial device it is connected to\n\
|
| remote_ops.to_static_tracepoint_markers_by_strid
|
| = remote_static_tracepoint_markers_by_strid;
|
| remote_ops.to_traceframe_info = remote_traceframe_info;
|
| + remote_ops.to_use_agent = remote_use_agent;
|
| + remote_ops.to_can_use_agent = remote_can_use_agent;
|
| }
|
|
|
| /* Set up the extended remote vector by making a copy of the standard
|
| @@ -11077,6 +11474,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_QPassSignals],
|
| "QPassSignals", "pass-signals", 0);
|
|
|
| + add_packet_config_cmd (&remote_protocol_packets[PACKET_QProgramSignals],
|
| + "QProgramSignals", "program-signals", 0);
|
| +
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_qSymbol],
|
| "qSymbol", "symbol-lookup", 0);
|
|
|
| @@ -11138,6 +11538,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
|
| (&remote_protocol_packets[PACKET_qXfer_traceframe_info],
|
| "qXfer:trace-frame-info:read", "traceframe-info", 0);
|
|
|
| + add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_uib],
|
| + "qXfer:uib:read", "unwind-info-block", 0);
|
| +
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
|
| "qGetTLSAddr", "get-thread-local-storage-address",
|
| 0);
|
| @@ -11173,6 +11576,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_unlink],
|
| "vFile:unlink", "hostio-unlink", 0);
|
|
|
| + add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_readlink],
|
| + "vFile:readlink", "hostio-readlink", 0);
|
| +
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_vAttach],
|
| "vAttach", "attach", 0);
|
|
|
| @@ -11191,6 +11597,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_ConditionalTracepoints],
|
| "ConditionalTracepoints",
|
| "conditional-tracepoints", 0);
|
| +
|
| + add_packet_config_cmd (&remote_protocol_packets[PACKET_ConditionalBreakpoints],
|
| + "ConditionalBreakpoints",
|
| + "conditional-breakpoints", 0);
|
| +
|
| + add_packet_config_cmd (&remote_protocol_packets[PACKET_BreakpointCommands],
|
| + "BreakpointCommands",
|
| + "breakpoint-commands", 0);
|
| +
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
|
| "FastTracepoints", "fast-tracepoints", 0);
|
|
|
| @@ -11215,6 +11630,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
|
| add_packet_config_cmd (&remote_protocol_packets[PACKET_QDisableRandomization],
|
| "QDisableRandomization", "disable-randomization", 0);
|
|
|
| + add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
|
| + "QAgent", "agent", 0);
|
| +
|
| /* Keep the old ``set remote Z-packet ...'' working. Each individual
|
| Z sub-packet has its own set and show commands, but users may
|
| have sets to this variable in their .gdbinit files (or in their
|
|
|