This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: remote.c incoming packet cleanups


This patch does two things that I've wanted to do for ages.

First of all, it slays almost all of the uses of alloca in remote.c
for huge packet-sized buffers.  There's two left, plus a couple uses of
alloca for other things; the remaining packet-sized buffer allocations
can be pretty easily converted to xmalloc, but I didn't want to mix it
with this patch.

Motivations:
  - Alloca for large buffers is just a bad idea.
  - I want to support making these buffers larger, in a future
    patch which adds a to-be-determined remote query command
    for the largest acceptable size.  Alloca for even larger
    buffers is an even worse idea!  I'm doing this because
    a lot of stub communications are latency bound rather
    than bandwidth bound; being able to send larger requests
    for e.g. "load" is a huge performance boost.

Secondly, it removes the limits on the length of incoming packets.
I applied "be conservative in what you generate and liberal in what
you expect" - there are often memory constraints in remote stubs,
so we continue to limit outgoing packets to rs->remote_packet_size,
but the size of an incoming packet is tiny relative to a symbol
table, so we ought to accept anything we have enough RAM for.

The basic change is to convert getpkt from (char *buf, int len,
int forever) to (char **buf_p, int *len, int forever) and allocate
*buf_p with xmalloc, so that we can pass it to xrealloc.  All
the rest is cascading changes.

I proofread as best I could that there are no overlapping uses
of the global buffer (there was exactly one overlap, which is
one of the alloca uses I left).  I also tested using gdbserver
and the gdb testsuite, and by hand receiving an oversized (20K)
packet.

It all looks good, but I'd appreciate both comments on the approach and
additional pairs of eyes looking over the changes - it was very
mechanical, but not quite enough so to automate.

Look OK?

-- 
Daniel Jacobowitz
CodeSourcery

2006-02-23  Daniel Jacobowitz  <dan@codesourcery.com>

	* remote.c (struct remote_state): Add BUF and BUF_SIZE.
	(init_remote_state): Initialize the new fields.
	(get_memory_packet_size): Update BUF and BUF_SIZE if necessary.
	(set_thread, remote_thread_alive, remote_unpack_thread_info_response)
	(remote_get_threadinfo, parse_threadlist_response)
	(remote_get_threadlist, remote_current_thread, remote_threads_info)
	(remote_threads_extra_info, extended_remote_restart, get_offsets)
	(remote_check_symbols, remote_open_1, remote_detach)
	(remove_vcont_probe, remote_vcont_resume, remote_resume)
	(remote_wait, remote_async_wait, fetch_register_using_p)
	(remote_fetch_registers, store_register_using_P)
	(remote_store_registers, check_binary_download, remote_write_bytes)
	(remote_read_bytes, remote_insert_breakpoint)
	(remote_remove_breakpoint, remote_insert_watchpoint)
	(remote_remove_watchpoint, remote_insert_hw_breakpoint)
	(remote_remove_hw_breakpoint, compare_sections_command)
	(remote_xfer_partial, remote_rcmd, packet_command)
	(remote_get_thread_local_address): Use the global incoming buffer
	instead of alloca or xmalloc.  Limit outgoing packets to
	rs->remote_packet_size and incoming packets to rs->buf_size.
	Update calls to getpkt and remote_send.
	(remote_send): Take arguments by reference.
	(putpkt_binary): Eliminate junkbuf.  Use skip_frame.
	(skip_frame): New function.
	(read_frame): Take arguments by reference.  Expand the packet
	buffer instead of issuing an error.
	(getpkt, getpkt_sane): Take arguments by reference.
	* remote.h (getpkt): Update prototype and doc.
	* tracepoint.c (remote_get_noisy_reply): Take arguments by
	reference.
	(target_buf): Change from array to pointer.
	(target_buf_size): New variable.
	(remote_set_transparent_ranges): Update call to getpkt.
	(trace_start_command, trace_stop_command, trace_status_command):
	Update calls to remote_get_noisy_reply.
	(finish_tfind_command): Take arguments by reference.
	(trace_find_command, trace_find_pc_command)
	(trace_find_tracepoint_command, trace_find_line_command):
	(trace_find_range_command, trace_find_outside_command): Update
	calls to finish_tfind_command.
	(_initialize_tracepoint): Initialize target_buf_size and target_buf.

Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.202
diff -u -p -r1.202 remote.c
--- remote.c	20 Feb 2006 15:19:06 -0000	1.202
+++ remote.c	23 Feb 2006 14:23:12 -0000
@@ -63,7 +63,7 @@
 /* Prototypes for local functions.  */
 static void cleanup_sigint_signal_handler (void *dummy);
 static void initialize_sigint_signal_handler (void);
-static int getpkt_sane (char *buf, long sizeof_buf, int forever);
+static int getpkt_sane (char **buf, long *sizeof_buf, int forever);
 
 static void handle_remote_sigint (int);
 static void handle_remote_sigint_twice (int);
@@ -104,7 +104,7 @@ static void extended_remote_mourn (void)
 
 static void remote_mourn_1 (struct target_ops *);
 
-static void remote_send (char *buf, long sizeof_buf);
+static void remote_send (char **buf, long *sizeof_buf_p);
 
 static int readchar (int timeout);
 
@@ -132,7 +132,9 @@ static int remote_thread_alive (ptid_t);
 
 static void get_offsets (void);
 
-static long read_frame (char *buf, long sizeof_buf);
+static void skip_frame (void);
+
+static long read_frame (char **buf_p, long *sizeof_buf);
 
 static int remote_insert_breakpoint (CORE_ADDR, bfd_byte *);
 
@@ -228,6 +230,15 @@ struct remote_state
   /* This is the maximum size (in chars) of a non read/write packet.
      It is also used as a cap on the size of read/write packets.  */
   long remote_packet_size;
+
+  /* A buffer to use for incoming packets, and its current size.  The
+     buffer is grown dynamically for larger incoming packets.
+     Outgoing packets may also be constructed in this buffer.
+     BUF_SIZE is always at least REMOTE_PACKET_SIZE;
+     REMOTE_PACKET_SIZE should be used to limit the length of outgoing
+     packets.  */
+  char *buf;
+  long buf_size;
 };
 
 
@@ -286,6 +297,14 @@ init_remote_state (struct gdbarch *gdbar
   /* This one is filled in when a ``g'' packet is received.  */
   rs->actual_register_packet_size = 0;
 
+  /* Create the buffer at a default size.  Note that this would
+     leak memory if the gdbarch were ever destroyed; there's no
+     way to register a destructor for it, and we can't realloc
+     using the gdbarch obstack.  But gdbarches are never
+     destroyed.  */
+  rs->buf_size = rs->remote_packet_size;
+  rs->buf = xmalloc (rs->buf_size);
+
   return rs;
 }
 
@@ -436,6 +455,15 @@ get_memory_packet_size (struct memory_pa
     what_they_get = MAX_REMOTE_PACKET_SIZE;
   if (what_they_get < MIN_REMOTE_PACKET_SIZE)
     what_they_get = MIN_REMOTE_PACKET_SIZE;
+
+  /* Make sure there is room in the global buffer for this packet
+     (including its trailing NUL byte).  */
+  if (rs->buf_size < what_they_get + 1)
+    {
+      rs->buf_size = what_they_get + 1;
+      rs->buf = xrealloc (rs->buf, what_they_get + 1);
+    }
+
   return what_they_get;
 }
 
@@ -885,7 +913,7 @@ static void
 set_thread (int th, int gen)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   int state = gen ? general_thread : continue_thread;
 
   if (state == th)
@@ -903,7 +931,7 @@ set_thread (int th, int gen)
   else
     xsnprintf (&buf[2], rs->remote_packet_size - 2, "%x", th);
   putpkt (buf);
-  getpkt (buf, rs->remote_packet_size, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
   if (gen)
     general_thread = th;
   else
@@ -915,15 +943,16 @@ set_thread (int th, int gen)
 static int
 remote_thread_alive (ptid_t ptid)
 {
+  struct remote_state *rs = get_remote_state ();
   int tid = PIDGET (ptid);
-  char buf[16];
+  char *buf = rs->buf;
 
   if (tid < 0)
-    xsnprintf (buf, sizeof (buf), "T-%08x", -tid);
+    xsnprintf (buf, rs->remote_packet_size, "T-%08x", -tid);
   else
-    xsnprintf (buf, sizeof (buf), "T%08x", tid);
+    xsnprintf (buf, rs->remote_packet_size, "T%08x", tid);
   putpkt (buf);
-  getpkt (buf, sizeof (buf), 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
   return (buf[0] == 'O' && buf[1] == 'K');
 }
 
@@ -1332,7 +1361,7 @@ remote_unpack_thread_info_response (char
   int mask, length;
   int tag;
   threadref ref;
-  char *limit = pkt + rs->remote_packet_size; /* Plausible parsing limit.  */
+  char *limit = pkt + rs->buf_size; /* Plausible parsing limit.  */
   int retval = 1;
 
   /* info->threadid = 0; FIXME: implement zero_threadref.  */
@@ -1423,11 +1452,11 @@ remote_get_threadinfo (threadref *thread
 {
   struct remote_state *rs = get_remote_state ();
   int result;
-  char *threadinfo_pkt = alloca (rs->remote_packet_size);
+  char *threadinfo_pkt = rs->buf;
 
   pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
   putpkt (threadinfo_pkt);
-  getpkt (threadinfo_pkt, rs->remote_packet_size, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
   result = remote_unpack_thread_info_response (threadinfo_pkt + 2,
 					       threadid, info);
   return result;
@@ -1461,7 +1490,7 @@ parse_threadlist_response (char *pkt, in
 
   resultcount = 0;
   /* Assume the 'q' and 'M chars have been stripped.  */
-  limit = pkt + (rs->remote_packet_size - BUF_THREAD_ID_SIZE);
+  limit = pkt + (rs->buf_size - BUF_THREAD_ID_SIZE);
   /* done parse past here */
   pkt = unpack_byte (pkt, &count);	/* count field */
   pkt = unpack_nibble (pkt, &done);
@@ -1484,21 +1513,19 @@ remote_get_threadlist (int startflag, th
 {
   struct remote_state *rs = get_remote_state ();
   static threadref echo_nextthread;
-  char *threadlist_packet = alloca (rs->remote_packet_size);
-  char *t_response = alloca (rs->remote_packet_size);
+  char *threadlist_packet = rs->buf;
   int result = 1;
 
   /* Trancate result limit to be smaller than the packet size.  */
   if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= rs->remote_packet_size)
     result_limit = (rs->remote_packet_size / BUF_THREAD_ID_SIZE) - 2;
 
-  pack_threadlist_request (threadlist_packet,
-			   startflag, result_limit, nextthread);
-  putpkt (threadlist_packet);
-  getpkt (t_response, rs->remote_packet_size, 0);
+  pack_threadlist_request (rs->buf, startflag, result_limit, nextthread);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
   *result_count =
-    parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
+    parse_threadlist_response (rs->buf + 2, result_limit, &echo_nextthread,
 			       threadlist, done);
 
   if (!threadmatch (&echo_nextthread, nextthread))
@@ -1603,10 +1630,10 @@ static ptid_t
 remote_current_thread (ptid_t oldpid)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
 
   putpkt ("qC");
-  getpkt (buf, rs->remote_packet_size, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
   if (buf[0] == 'Q' && buf[1] == 'C')
     /* Use strtoul here, so we'll correctly parse values whose highest
        bit is set.  The protocol carries them as a simple series of
@@ -1642,7 +1669,6 @@ static void
 remote_threads_info (void)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
   char *bufp;
   int tid;
 
@@ -1652,8 +1678,8 @@ remote_threads_info (void)
   if (use_threadinfo_query)
     {
       putpkt ("qfThreadInfo");
-      bufp = buf;
-      getpkt (bufp, rs->remote_packet_size, 0);
+      bufp = rs->buf;
+      getpkt (&rs->buf, &rs->buf_size, 0);
       if (bufp[0] != '\0')		/* q packet recognized */
 	{
 	  while (*bufp++ == 'm')	/* reply contains one or more TID */
@@ -1672,8 +1698,8 @@ remote_threads_info (void)
 		}
 	      while (*bufp++ == ',');	/* comma-separated list */
 	      putpkt ("qsThreadInfo");
-	      bufp = buf;
-	      getpkt (bufp, rs->remote_packet_size, 0);
+	      bufp = rs->buf;
+	      getpkt (&rs->buf, &rs->buf_size, 0);
 	    }
 	  return;	/* done */
 	}
@@ -1703,7 +1729,6 @@ remote_threads_extra_info (struct thread
   threadref id;
   struct gdb_ext_thread_info threadinfo;
   static char display_buf[100];	/* arbitrary...  */
-  char *bufp = alloca (rs->remote_packet_size);
   int n = 0;                    /* position in display_buf */
 
   if (remote_desc == 0)		/* paranoia */
@@ -1712,10 +1737,12 @@ remote_threads_extra_info (struct thread
 
   if (use_threadextra_query)
     {
+      char *bufp = rs->buf;
+
       xsnprintf (bufp, rs->remote_packet_size, "qThreadExtraInfo,%x", 
 		 PIDGET (tp->ptid));
       putpkt (bufp);
-      getpkt (bufp, rs->remote_packet_size, 0);
+      getpkt (&rs->buf, &rs->buf_size, 0);
       if (bufp[0] != 0)
 	{
 	  n = min (strlen (bufp) / 2, sizeof (display_buf));
@@ -1761,17 +1788,16 @@ static void
 extended_remote_restart (void)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
 
   /* Send the restart command; for reasons I don't understand the
      remote side really expects a number after the "R".  */
-  xsnprintf (buf, rs->remote_packet_size, "R%x", 0);
-  putpkt (buf);
+  xsnprintf (rs->buf, rs->remote_packet_size, "R%x", 0);
+  putpkt (rs->buf);
 
   /* Now query for status so this looks just like we restarted
      gdbserver from scratch.  */
   putpkt ("?");
-  getpkt (buf, rs->remote_packet_size, 0);
+  getpkt (&rs->buf, &rs->remote_packet_size, 0);
 }
 
 /* Clean up connection to a remote debugger.  */
@@ -1790,14 +1816,14 @@ static void
 get_offsets (void)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   char *ptr;
   int lose;
   CORE_ADDR text_addr, data_addr, bss_addr;
   struct section_offsets *offs;
 
   putpkt ("qOffsets");
-  getpkt (buf, rs->remote_packet_size, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
   if (buf[0] == '\000')
     return;			/* Return silently.  Stub doesn't support
@@ -1956,14 +1982,17 @@ remote_check_symbols (struct objfile *ob
   if (remote_protocol_packets[PACKET_qSymbol].support == PACKET_DISABLE)
     return;
 
-  msg   = alloca (rs->remote_packet_size);
-  reply = alloca (rs->remote_packet_size);
+  /* Allocate a message buffer.  We can't reuse the input buffer in RS,
+     because we need both at the same time.  */
+  msg = alloca (rs->remote_packet_size);
+
+  reply = rs->buf;
 
   /* Invite target to request symbol lookups.  */
 
   putpkt ("qSymbol::");
-  getpkt (reply, rs->remote_packet_size, 0);
-  packet_ok (reply, &remote_protocol_packets[PACKET_qSymbol]);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+  packet_ok (rs->buf, &remote_protocol_packets[PACKET_qSymbol]);
 
   while (strncmp (reply, "qSymbol:", 8) == 0)
     {
@@ -1978,7 +2007,7 @@ remote_check_symbols (struct objfile *ob
 		   paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
 		   &reply[8]);
       putpkt (msg);
-      getpkt (reply, rs->remote_packet_size, 0);
+      getpkt (&rs->buf, &rs->buf_size, 0);
     }
 }
 
@@ -2124,9 +2153,8 @@ remote_open_1 (char *name, int from_tty,
   if (extended_p)
     {
       /* Tell the remote that we are using the extended protocol.  */
-      char *buf = alloca (rs->remote_packet_size);
       putpkt ("!");
-      getpkt (buf, rs->remote_packet_size, 0);
+      getpkt (&rs->buf, &rs->buf_size, 0);
     }
 
   post_create_inferior (&current_target, from_tty);
@@ -2144,14 +2172,13 @@ static void
 remote_detach (char *args, int from_tty)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
 
   if (args)
     error (_("Argument given to \"detach\" when remotely debugging."));
 
   /* Tell the remote target to detach.  */
-  strcpy (buf, "D");
-  remote_send (buf, rs->remote_packet_size);
+  strcpy (rs->buf, "D");
+  remote_send (&rs->buf, &rs->buf_size);
 
   /* Unregister the file descriptor from the event loop.  */
   if (target_is_async_p ())
@@ -2245,11 +2272,13 @@ bin2hex (const gdb_byte *bin, char *hex,
    the response.  */
 
 static void
-remote_vcont_probe (struct remote_state *rs, char *buf)
+remote_vcont_probe (struct remote_state *rs)
 {
+  char *buf = rs->buf;
+
   strcpy (buf, "vCont?");
   putpkt (buf);
-  getpkt (buf, rs->remote_packet_size, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
   /* Make sure that the features we assume are supported.  */
   if (strncmp (buf, "vCont", 5) == 0)
@@ -2303,17 +2332,11 @@ remote_vcont_resume (ptid_t ptid, int st
   char *buf = NULL, *outbuf;
   struct cleanup *old_cleanup;
 
-  buf = xmalloc (rs->remote_packet_size);
-  old_cleanup = make_cleanup (xfree, buf);
-
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
-    remote_vcont_probe (rs, buf);
+    remote_vcont_probe (rs);
 
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_DISABLE)
-    {
-      do_cleanups (old_cleanup);
-      return 0;
-    }
+    return 0;
 
   /* If we could generate a wider range of packets, we'd have to worry
      about overflowing BUF.  Should there be a generic
@@ -2361,7 +2384,7 @@ remote_vcont_resume (ptid_t ptid, int st
     }
 
   gdb_assert (outbuf && strlen (outbuf) < rs->remote_packet_size);
-  make_cleanup (xfree, outbuf);
+  old_cleanup = make_cleanup (xfree, outbuf);
 
   putpkt (outbuf);
 
@@ -2380,7 +2403,7 @@ static void
 remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   int pid = PIDGET (ptid);
 
   last_sent_signal = siggnal;
@@ -2650,7 +2673,7 @@ static ptid_t
 remote_wait (ptid_t ptid, struct target_waitstatus *status)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   ULONGEST thread_num = -1;
   ULONGEST addr;
 
@@ -2662,7 +2685,7 @@ remote_wait (ptid_t ptid, struct target_
       char *p;
 
       ofunc = signal (SIGINT, remote_interrupt);
-      getpkt (buf, rs->remote_packet_size, 1);
+      getpkt (&rs->buf, &rs->buf_size, 1);
       signal (SIGINT, ofunc);
 
       /* This is a hook for when we need to do something (perhaps the
@@ -2839,7 +2862,7 @@ static ptid_t
 remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   ULONGEST thread_num = -1;
   ULONGEST addr;
 
@@ -2858,7 +2881,7 @@ remote_async_wait (ptid_t ptid, struct t
          _never_ wait for ever -> test on target_is_async_p().
          However, before we do that we need to ensure that the caller
          knows how to take the target into/out of async mode.  */
-      getpkt (buf, rs->remote_packet_size, wait_forever_enabled_p);
+      getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
       if (!target_is_async_p ())
 	signal (SIGINT, ofunc);
 
@@ -3042,7 +3065,7 @@ static int
 fetch_register_using_p (int regnum)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size), *p;
+  char *buf = rs->buf, *p;
   char regp[MAX_REGISTER_SIZE];
   int i;
 
@@ -3050,7 +3073,7 @@ fetch_register_using_p (int regnum)
   *p++ = 'p';
   p += hexnumstr (p, regnum);
   *p++ = '\0';
-  remote_send (buf, rs->remote_packet_size);
+  remote_send (&rs->buf, &rs->buf_size);
 
   /* If the stub didn't recognize the packet, or if we got an error,
      tell our caller.  */
@@ -3087,7 +3110,7 @@ static void
 remote_fetch_registers (int regnum)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   int i;
   char *p;
   char *regs = alloca (rs->sizeof_g_packet);
@@ -3130,7 +3153,7 @@ remote_fetch_registers (int regnum)
 	}
 
   sprintf (buf, "g");
-  remote_send (buf, rs->remote_packet_size);
+  remote_send (&rs->buf, &rs->buf_size);
 
   /* Save the size of the packet sent to us by the target.  Its used
      as a heuristic when determining the max size of packets that the
@@ -3152,7 +3175,7 @@ remote_fetch_registers (int regnum)
       if (remote_debug)
 	fprintf_unfiltered (gdb_stdlog,
 			    "Bad register packet; fetching a new packet\n");
-      getpkt (buf, rs->remote_packet_size, 0);
+      getpkt (&rs->buf, &rs->buf_size, 0);
     }
 
   /* Reply describes registers byte by byte, each byte encoded as two
@@ -3251,7 +3274,7 @@ store_register_using_P (int regnum)
   struct remote_state *rs = get_remote_state ();
   struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
   /* Try storing a single register.  */
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   gdb_byte regp[MAX_REGISTER_SIZE];
   char *p;
 
@@ -3259,7 +3282,7 @@ store_register_using_P (int regnum)
   p = buf + strlen (buf);
   regcache_raw_collect (current_regcache, reg->regnum, regp);
   bin2hex (regp, p, register_size (current_gdbarch, reg->regnum));
-  remote_send (buf, rs->remote_packet_size);
+  remote_send (&rs->buf, &rs->buf_size);
 
   return buf[0] != '\0';
 }
@@ -3272,7 +3295,6 @@ static void
 remote_store_registers (int regnum)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf;
   gdb_byte *regs;
   char *p;
 
@@ -3323,12 +3345,11 @@ remote_store_registers (int regnum)
 
   /* Command describes registers byte by byte,
      each byte encoded as two hex characters.  */
-  buf = alloca (rs->remote_packet_size);
-  p = buf;
+  p = rs->buf;
   *p++ = 'G';
   /* remote_prepare_to_store insures that register_bytes_found gets set.  */
   bin2hex (regs, p, register_bytes_found);
-  remote_send (buf, rs->remote_packet_size);
+  remote_send (&rs->buf, &rs->buf_size);
 }
 
 
@@ -3414,7 +3435,7 @@ check_binary_download (CORE_ADDR addr)
       break;
     case PACKET_SUPPORT_UNKNOWN:
       {
-	char *buf = alloca (rs->remote_packet_size);
+	char *buf = rs->buf;
 	char *p;
 
 	p = buf;
@@ -3426,7 +3447,7 @@ check_binary_download (CORE_ADDR addr)
 	*p = '\0';
 
 	putpkt_binary (buf, (int) (p - buf));
-	getpkt (buf, rs->remote_packet_size, 0);
+	getpkt (&rs->buf, &rs->buf_size, 0);
 
 	if (buf[0] == '\0')
 	  {
@@ -3459,10 +3480,10 @@ check_binary_download (CORE_ADDR addr)
 int
 remote_write_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
 {
+  struct remote_state *rs = get_remote_state ();
   char *buf;
   char *p;
   char *plen;
-  long sizeof_buf;
   int plenlen;
   int todo;
   int nr_bytes;
@@ -3474,10 +3495,9 @@ remote_write_bytes (CORE_ADDR memaddr, g
 
   payload_size = get_memory_write_packet_size ();
   
-  /* Compute the size, and then allocate space for the largest
-     possible packet.  Include space for an extra trailing NUL.  */
-  sizeof_buf = payload_size + 1;
-  buf = alloca (sizeof_buf);
+  /* The packet buffer will be large enough for the payload;
+     get_memory_packet_size ensures this.  */
+  buf = rs->buf;
 
   /* Compute the size of the actual payload by subtracting out the
      packet header and footer overhead: "$M<memaddr>,<len>:...#nn".
@@ -3584,7 +3604,7 @@ remote_write_bytes (CORE_ADDR memaddr, g
     }
 
   putpkt_binary (buf, (int) (p - buf));
-  getpkt (buf, sizeof_buf, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
   if (buf[0] == 'E')
     {
@@ -3619,15 +3639,15 @@ remote_write_bytes (CORE_ADDR memaddr, g
 int
 remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
 {
+  struct remote_state *rs = get_remote_state ();
   char *buf;
   int max_buf_size;		/* Max size of packet output buffer.  */
-  long sizeof_buf;
   int origlen;
 
-  /* Create a buffer big enough for this packet.  */
   max_buf_size = get_memory_read_packet_size ();
-  sizeof_buf = max_buf_size + 1; /* Space for trailing NULL.  */
-  buf = alloca (sizeof_buf);
+  /* The packet buffer will be large enough for the payload;
+     get_memory_packet_size ensures this.  */
+  buf = rs->buf;
 
   origlen = len;
   while (len > 0)
@@ -3649,7 +3669,7 @@ remote_read_bytes (CORE_ADDR memaddr, gd
       *p = '\0';
 
       putpkt (buf);
-      getpkt (buf, sizeof_buf, 0);
+      getpkt (&rs->buf, &rs->buf_size, 0);
 
       if (buf[0] == 'E'
 	  && isxdigit (buf[1]) && isxdigit (buf[2])
@@ -3748,18 +3768,20 @@ readchar (int timeout)
   return ch;
 }
 
-/* Send the command in BUF to the remote machine, and read the reply
-   into BUF.  Report an error if we get an error reply.  */
+/* Send the command in *BUF to the remote machine, and read the reply
+   into *BUF.  Report an error if we get an error reply.  Resize
+   *BUF using xrealloc if necessary to hold the result, and update
+   *SIZEOF_BUF.  */
 
 static void
-remote_send (char *buf,
-	     long sizeof_buf)
+remote_send (char **buf,
+	     long *sizeof_buf)
 {
-  putpkt (buf);
+  putpkt (*buf);
   getpkt (buf, sizeof_buf, 0);
 
-  if (buf[0] == 'E')
-    error (_("Remote failure reply: %s"), buf);
+  if ((*buf)[0] == 'E')
+    error (_("Remote failure reply: %s"), *buf);
 }
 
 /* Display a null-terminated packet on stdout, for debugging, using C
@@ -3792,8 +3814,6 @@ putpkt_binary (char *buf, int cnt)
   int i;
   unsigned char csum = 0;
   char *buf2 = alloca (cnt + 6);
-  long sizeof_junkbuf = rs->remote_packet_size;
-  char *junkbuf = alloca (sizeof_junkbuf);
 
   int ch;
   int tcount = 0;
@@ -3875,7 +3895,7 @@ putpkt_binary (char *buf, int cnt)
 		   was lost.  Gobble up the packet and ack it so it
 		   doesn't get retransmitted when we resend this
 		   packet.  */
-		read_frame (junkbuf, sizeof_junkbuf);
+		skip_frame ();
 		serial_write (remote_desc, "+", 1);
 		continue;	/* Now, go look for +.  */
 	      }
@@ -3909,29 +3929,65 @@ putpkt_binary (char *buf, int cnt)
     }
 }
 
+/* Come here after finding the start of a frame when we expected an
+   ack.  Do our best to discard the rest of this packet.  */
+
+static void
+skip_frame (void)
+{
+  int c;
+
+  while (1)
+    {
+      c = readchar (remote_timeout);
+      switch (c)
+	{
+	case SERIAL_TIMEOUT:
+	  /* Nothing we can do.  */
+	  return;
+	case '#':
+	  /* Discard the two bytes of checksum and stop.  */
+	  c = readchar (remote_timeout);
+	  if (c >= 0)
+	    c = readchar (remote_timeout);
+
+	  return;
+	case '*':		/* Run length encoding.  */
+	  /* Discard the repeat count.  */
+	  c = readchar (remote_timeout);
+	  if (c < 0)
+	    return;
+	  break;
+	default:
+	  /* A regular character.  */
+	  break;
+	}
+    }
+}
+
 /* Come here after finding the start of the frame.  Collect the rest
-   into BUF, verifying the checksum, length, and handling run-length
-   compression.  No more than sizeof_buf-1 characters are read so that
-   the buffer can be NUL terminated.
+   into *BUF, verifying the checksum, length, and handling run-length
+   compression.  NUL terminate the buffer.  If there is not enough room,
+   expand *BUF using xrealloc.
 
    Returns -1 on error, number of characters in buffer (ignoring the
    trailing NULL) on success. (could be extended to return one of the
    SERIAL status indications).  */
 
 static long
-read_frame (char *buf,
-	    long sizeof_buf)
+read_frame (char **buf_p,
+	    long *sizeof_buf)
 {
   unsigned char csum;
   long bc;
   int c;
+  char *buf = *buf_p;
 
   csum = 0;
   bc = 0;
 
   while (1)
     {
-      /* ASSERT (bc < sizeof_buf - 1) - space for trailing NULL.  */
       c = readchar (remote_timeout);
       switch (c)
 	{
@@ -3998,51 +4054,53 @@ read_frame (char *buf,
 
 	    /* The character before ``*'' is repeated.  */
 
-	    if (repeat > 0 && repeat <= 255
-		&& bc > 0
-                && bc + repeat - 1 < sizeof_buf - 1)
+	    if (repeat > 0 && repeat <= 255 && bc > 0)
 	      {
+		if (bc + repeat - 1 >= *sizeof_buf - 1)
+		  {
+		    /* Make some more room in the buffer.  */
+		    *sizeof_buf += repeat;
+		    *buf_p = xrealloc (*buf_p, *sizeof_buf);
+		    buf = *buf_p;
+		  }
+
 		memset (&buf[bc], buf[bc - 1], repeat);
 		bc += repeat;
 		continue;
 	      }
 
 	    buf[bc] = '\0';
-	    printf_filtered (_("Repeat count %d too large for buffer: "), 
-			     repeat);
-	    puts_filtered (buf);
-	    puts_filtered ("\n");
+	    printf_filtered (_("Invalid run length encoding: %s\n"), buf);
 	    return -1;
 	  }
 	default:
-	  if (bc < sizeof_buf - 1)
+	  if (bc >= *sizeof_buf - 1)
 	    {
-	      buf[bc++] = c;
-	      csum += c;
-	      continue;
+	      /* Make some more room in the buffer.  */
+	      *sizeof_buf *= 2;
+	      *buf_p = xrealloc (*buf_p, *sizeof_buf);
+	      buf = *buf_p;
 	    }
 
-	  buf[bc] = '\0';
-	  puts_filtered ("Remote packet too long: ");
-	  puts_filtered (buf);
-	  puts_filtered ("\n");
-
-	  return -1;
+	  buf[bc++] = c;
+	  csum += c;
+	  continue;
 	}
     }
 }
 
 /* Read a packet from the remote machine, with error checking, and
-   store it in BUF.  If FOREVER, wait forever rather than timing out;
-   this is used (in synchronous mode) to wait for a target that is is
-   executing user code to stop.  */
+   store it in *BUF.  Resize *BUF using xrealloc if necessary to hold
+   the result, and update *SIZEOF_BUF.  If FOREVER, wait forever
+   rather than timing out; this is used (in synchronous mode) to wait
+   for a target that is is executing user code to stop.  */
 /* FIXME: ezannoni 2000-02-01 this wrapper is necessary so that we
    don't have to change all the calls to getpkt to deal with the
    return value, because at the moment I don't know what the right
    thing to do it for those.  */
 void
-getpkt (char *buf,
-	long sizeof_buf,
+getpkt (char **buf,
+	long *sizeof_buf,
 	int forever)
 {
   int timed_out;
@@ -4052,22 +4110,21 @@ getpkt (char *buf,
 
 
 /* Read a packet from the remote machine, with error checking, and
-   store it in BUF.  If FOREVER, wait forever rather than timing out;
-   this is used (in synchronous mode) to wait for a target that is is
-   executing user code to stop. If FOREVER == 0, this function is
-   allowed to time out gracefully and return an indication of this to
-   the caller.  */
+   store it in *BUF.  Resize *BUF using xrealloc if necessary to hold
+   the result, and update *SIZEOF_BUF.  If FOREVER, wait forever
+   rather than timing out; this is used (in synchronous mode) to wait
+   for a target that is is executing user code to stop.  If FOREVER ==
+   0, this function is allowed to time out gracefully and return an
+   indication of this to the caller.  */
 static int
-getpkt_sane (char *buf,
-	long sizeof_buf,
-	int forever)
+getpkt_sane (char **buf, long *sizeof_buf, int forever)
 {
   int c;
   int tries;
   int timeout;
   int val;
 
-  strcpy (buf, "timeout");
+  strcpy (*buf, "timeout");
 
   if (forever)
     {
@@ -4119,7 +4176,7 @@ getpkt_sane (char *buf,
 	  if (remote_debug)
 	    {
 	      fprintf_unfiltered (gdb_stdlog, "Packet received: ");
-	      fputstr_unfiltered (buf, 0, gdb_stdlog);
+	      fputstr_unfiltered (*buf, 0, gdb_stdlog);
 	      fprintf_unfiltered (gdb_stdlog, "\n");
 	    }
 	  serial_write (remote_desc, "+", 1);
@@ -4324,8 +4381,7 @@ remote_insert_breakpoint (CORE_ADDR addr
 
   if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
     {
-      char *buf = alloca (rs->remote_packet_size);
-      char *p = buf;
+      char *p = rs->buf;
 
       addr = remote_address_masked (addr);
       *(p++) = 'Z';
@@ -4335,10 +4391,10 @@ remote_insert_breakpoint (CORE_ADDR addr
       BREAKPOINT_FROM_PC (&addr, &bp_size);
       sprintf (p, ",%d", bp_size);
 
-      putpkt (buf);
-      getpkt (buf, rs->remote_packet_size, 0);
+      putpkt (rs->buf);
+      getpkt (&rs->buf, &rs->buf_size, 0);
 
-      switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z0]))
+      switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0]))
 	{
 	case PACKET_ERROR:
 	  return -1;
@@ -4376,8 +4432,7 @@ remote_remove_breakpoint (CORE_ADDR addr
 
   if (remote_protocol_packets[PACKET_Z0].support != PACKET_DISABLE)
     {
-      char *buf = alloca (rs->remote_packet_size);
-      char *p = buf;
+      char *p = rs->buf;
 
       *(p++) = 'z';
       *(p++) = '0';
@@ -4388,10 +4443,10 @@ remote_remove_breakpoint (CORE_ADDR addr
       BREAKPOINT_FROM_PC (&addr, &bp_size);
       sprintf (p, ",%d", bp_size);
 
-      putpkt (buf);
-      getpkt (buf, rs->remote_packet_size, 0);
+      putpkt (rs->buf);
+      getpkt (&rs->buf, &rs->buf_size, 0);
 
-      return (buf[0] == 'E');
+      return (rs->buf[0] == 'E');
     }
 
 #ifdef DEPRECATED_REMOTE_BREAKPOINT
@@ -4425,7 +4480,6 @@ static int
 remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
   char *p;
   enum Z_packet_type packet = watchpoint_to_Z_packet (type);
 
@@ -4434,16 +4488,16 @@ remote_insert_watchpoint (CORE_ADDR addr
 	   remote_protocol_packets[PACKET_Z0 + packet].name,
 	   remote_protocol_packets[PACKET_Z0 + packet].title);
 
-  sprintf (buf, "Z%x,", packet);
-  p = strchr (buf, '\0');
+  sprintf (rs->buf, "Z%x,", packet);
+  p = strchr (rs->buf, '\0');
   addr = remote_address_masked (addr);
   p += hexnumstr (p, (ULONGEST) addr);
   sprintf (p, ",%x", len);
 
-  putpkt (buf);
-  getpkt (buf, rs->remote_packet_size, 0);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
-  switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
     {
     case PACKET_ERROR:
     case PACKET_UNKNOWN:
@@ -4460,7 +4514,6 @@ static int
 remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
   char *p;
   enum Z_packet_type packet = watchpoint_to_Z_packet (type);
 
@@ -4469,15 +4522,15 @@ remote_remove_watchpoint (CORE_ADDR addr
 	   remote_protocol_packets[PACKET_Z0 + packet].name,
 	   remote_protocol_packets[PACKET_Z0 + packet].title);
 
-  sprintf (buf, "z%x,", packet);
-  p = strchr (buf, '\0');
+  sprintf (rs->buf, "z%x,", packet);
+  p = strchr (rs->buf, '\0');
   addr = remote_address_masked (addr);
   p += hexnumstr (p, (ULONGEST) addr);
   sprintf (p, ",%x", len);
-  putpkt (buf);
-  getpkt (buf, rs->remote_packet_size, 0);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
-  switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z0 + packet]))
+  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z0 + packet]))
     {
     case PACKET_ERROR:
     case PACKET_UNKNOWN:
@@ -4547,8 +4600,7 @@ remote_insert_hw_breakpoint (CORE_ADDR a
 {
   int len = 0;
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
-  char *p = buf;
+  char *p = rs->buf;
 
   /* The length field should be set to the size of a breakpoint
      instruction.  */
@@ -4568,10 +4620,10 @@ remote_insert_hw_breakpoint (CORE_ADDR a
   p += hexnumstr (p, (ULONGEST) addr);
   sprintf (p, ",%x", len);
 
-  putpkt (buf);
-  getpkt (buf, rs->remote_packet_size, 0);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
-  switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z1]))
+  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
     {
     case PACKET_ERROR:
     case PACKET_UNKNOWN:
@@ -4589,8 +4641,7 @@ remote_remove_hw_breakpoint (CORE_ADDR a
 {
   int len;
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
-  char *p = buf;
+  char *p = rs->buf;
 
   /* The length field should be set to the size of a breakpoint
      instruction.  */
@@ -4610,10 +4661,10 @@ remote_remove_hw_breakpoint (CORE_ADDR a
   p += hexnumstr (p, (ULONGEST) addr);
   sprintf (p, ",%x", len);
 
-  putpkt(buf);
-  getpkt (buf, rs->remote_packet_size, 0);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
 
-  switch (packet_ok (buf, &remote_protocol_packets[PACKET_Z1]))
+  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_Z1]))
     {
     case PACKET_ERROR:
     case PACKET_UNKNOWN:
@@ -4695,7 +4746,6 @@ compare_sections_command (char *args, in
   char *tmp;
   char *sectdata;
   const char *sectname;
-  char *buf = alloca (rs->remote_packet_size);
   bfd_size_type size;
   bfd_vma lma;
   int matched = 0;
@@ -4723,9 +4773,9 @@ compare_sections_command (char *args, in
       matched = 1;		/* do this section */
       lma = s->lma;
       /* FIXME: assumes lma can fit into long.  */
-      xsnprintf (buf, rs->remote_packet_size, "qCRC:%lx,%lx", 
+      xsnprintf (rs->buf, rs->remote_packet_size, "qCRC:%lx,%lx",
 		 (long) lma, (long) size);
-      putpkt (buf);
+      putpkt (rs->buf);
 
       /* Be clever; compute the host_crc before waiting for target
 	 reply.  */
@@ -4734,14 +4784,14 @@ compare_sections_command (char *args, in
       bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
       host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
 
-      getpkt (buf, rs->remote_packet_size, 0);
-      if (buf[0] == 'E')
+      getpkt (&rs->buf, &rs->buf_size, 0);
+      if (rs->buf[0] == 'E')
 	error (_("target memory fault, section %s, range 0x%s -- 0x%s"),
 	       sectname, paddr (lma), paddr (lma + size));
-      if (buf[0] != 'C')
+      if (rs->buf[0] != 'C')
 	error (_("remote target does not support this operation"));
 
-      for (target_crc = 0, tmp = &buf[1]; *tmp; tmp++)
+      for (target_crc = 0, tmp = &rs->buf[1]; *tmp; tmp++)
 	target_crc = target_crc * 16 + fromhex (*tmp);
 
       printf_filtered ("Section %s, range 0x%s -- 0x%s: ",
@@ -4770,8 +4820,7 @@ remote_xfer_partial (struct target_ops *
 {
   struct remote_state *rs = get_remote_state ();
   int i;
-  char *buf2 = alloca (rs->remote_packet_size);
-  char *p2 = &buf2[0];
+  char *p2;
   char query_type;
 
   /* Handle memory using remote_xfer_memory.  */
@@ -4821,22 +4870,22 @@ remote_xfer_partial (struct target_ops *
 	  while (len > 0)
 	    {
 	      LONGEST n = min ((rs->remote_packet_size - 2) / 2, len);
-	      snprintf (buf2, rs->remote_packet_size,
+	      snprintf (rs->buf, rs->remote_packet_size,
 			"qPart:auxv:read::%s,%s",
 			phex_nz (offset, sizeof offset),
 			phex_nz (n, sizeof n));
-	      i = putpkt (buf2);
+	      i = putpkt (rs->buf);
 	      if (i < 0)
 		return total > 0 ? total : i;
-	      buf2[0] = '\0';
-	      getpkt (buf2, rs->remote_packet_size, 0);
-	      if (packet_ok (buf2, &remote_protocol_packets[PACKET_qPart_auxv])
+	      rs->buf[0] = '\0';
+	      getpkt (&rs->buf, &rs->buf_size, 0);
+	      if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_qPart_auxv])
 		  != PACKET_OK)
 		return total > 0 ? total : -1;
-	      if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
+	      if (strcmp (rs->buf, "OK") == 0)
 		break;		/* Got EOF indicator.  */
 	      /* Got some data.  */
-	      i = hex2bin (buf2, readbuf, len);
+	      i = hex2bin (rs->buf, readbuf, len);
 	      if (i > 0)
 		{
 		  readbuf = (void *) ((char *) readbuf + i);
@@ -4870,6 +4919,7 @@ remote_xfer_partial (struct target_ops *
   gdb_assert (annex != NULL);
   gdb_assert (readbuf != NULL);
 
+  p2 = rs->buf;
   *p2++ = 'q';
   *p2++ = query_type;
 
@@ -4889,11 +4939,12 @@ remote_xfer_partial (struct target_ops *
   *p2 = '\0';
   gdb_assert (annex[i] == '\0');
 
-  i = putpkt (buf2);
+  i = putpkt (rs->buf);
   if (i < 0)
     return i;
 
-  getpkt ((char *) readbuf, len, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+  strcpy ((char *) readbuf, rs->buf);
 
   return strlen ((char *) readbuf);
 }
@@ -4903,7 +4954,7 @@ remote_rcmd (char *command,
 	     struct ui_file *outbuf)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
+  char *buf = rs->buf;
   char *p = buf;
 
   if (!remote_desc)
@@ -4923,7 +4974,7 @@ remote_rcmd (char *command,
   /* Encode the actual command.  */
   bin2hex ((gdb_byte *) command, p, 0);
 
-  if (putpkt (buf) < 0)
+  if (putpkt (rs->buf) < 0)
     error (_("Communication problem with target."));
 
   /* get/display the response */
@@ -4931,7 +4982,7 @@ remote_rcmd (char *command,
     {
       /* XXX - see also tracepoint.c:remote_get_noisy_reply().  */
       buf[0] = '\0';
-      getpkt (buf, rs->remote_packet_size, 0);
+      getpkt (&rs->buf, &rs->buf_size, 0);
       if (buf[0] == '\0')
 	error (_("Target does not support this command."));
       if (buf[0] == 'O' && buf[1] != 'K')
@@ -4959,7 +5010,6 @@ static void
 packet_command (char *args, int from_tty)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf = alloca (rs->remote_packet_size);
 
   if (!remote_desc)
     error (_("command can only be used with remote target"));
@@ -4972,9 +5022,9 @@ packet_command (char *args, int from_tty
   puts_filtered ("\n");
   putpkt (args);
 
-  getpkt (buf, rs->remote_packet_size, 0);
+  getpkt (&rs->buf, &rs->buf_size, 0);
   puts_filtered ("received: ");
-  print_packet (buf);
+  print_packet (rs->buf);
   puts_filtered ("\n");
 }
 
@@ -5144,8 +5194,7 @@ remote_get_thread_local_address (ptid_t 
   if (remote_protocol_packets[PACKET_qGetTLSAddr].support != PACKET_DISABLE)
     {
       struct remote_state *rs = get_remote_state ();
-      char *buf = alloca (rs->remote_packet_size);
-      char *p = buf;
+      char *p = rs->buf;
       enum packet_result result;
 
       strcpy (p, "qGetTLSAddr:");
@@ -5157,14 +5206,14 @@ remote_get_thread_local_address (ptid_t 
       p += hexnumstr (p, lm);
       *p++ = '\0';
 
-      putpkt (buf);
-      getpkt (buf, rs->remote_packet_size, 0);
-      result = packet_ok (buf, &remote_protocol_packets[PACKET_qGetTLSAddr]);
+      putpkt (rs->buf);
+      getpkt (&rs->buf, &rs->buf_size, 0);
+      result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_qGetTLSAddr]);
       if (result == PACKET_OK)
 	{
 	  ULONGEST result;
 
-	  unpack_varlen_hex (buf, &result);
+	  unpack_varlen_hex (rs->buf, &result);
 	  return result;
 	}
       else if (result == PACKET_UNKNOWN)
Index: remote.h
===================================================================
RCS file: /cvs/src/src/gdb/remote.h,v
retrieving revision 1.8
diff -u -p -r1.8 remote.h
--- remote.h	17 Jan 2006 14:47:31 -0000	1.8
+++ remote.h	23 Feb 2006 14:23:12 -0000
@@ -24,11 +24,12 @@
 /* FIXME?: move this interface down to tgt vector) */
 
 /* Read a packet from the remote machine, with error checking, and
-   store it in BUF.  BUF is expected to be of size PBUFSIZ.  If
-   FOREVER, wait forever rather than timing out; this is used while
-   the target is executing user code.  */
+   store it in *BUF.  Resize *BUF using xrealloc if necessary to hold
+   the result, and update *SIZEOF_BUF.  If FOREVER, wait forever
+   rather than timing out; this is used (in synchronous mode) to wait
+   for a target that is is executing user code to stop.  */
 
-extern void getpkt (char *buf, long sizeof_buf, int forever);
+extern void getpkt (char **buf, long *sizeof_buf, int forever);
 
 /* Send a packet to the remote machine, with error checking.  The data
    of the packet is in BUF.  The string in BUF can be at most PBUFSIZ
Index: tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.c,v
retrieving revision 1.84
diff -u -p -r1.84 tracepoint.c
--- tracepoint.c	1 Feb 2006 23:14:10 -0000	1.84
+++ tracepoint.c	23 Feb 2006 14:23:13 -0000
@@ -194,13 +194,15 @@ trace_error (char *buf)
 
 /* Utility: wait for reply from stub, while accepting "O" packets.  */
 static char *
-remote_get_noisy_reply (char *buf,
-			long sizeof_buf)
+remote_get_noisy_reply (char **buf_p,
+			long *sizeof_buf)
 {
   do				/* Loop on reply from remote stub.  */
     {
+      char *buf;
       QUIT;			/* allow user to bail out with ^C */
-      getpkt (buf, sizeof_buf, 0);
+      getpkt (buf_p, sizeof_buf, 0);
+      buf = *buf_p;
       if (buf[0] == 0)
 	error (_("Target does not support this command."));
       else if (buf[0] == 'E')
@@ -1700,7 +1702,8 @@ add_aexpr (struct collection_list *colle
   collect->next_aexpr_elt++;
 }
 
-static char target_buf[2048];
+static char *target_buf;
+static long target_buf_size;
 
 /* Set "transparent" memory ranges
 
@@ -1742,7 +1745,7 @@ remote_set_transparent_ranges (void)
   if (anysecs)
     {
       putpkt (target_buf);
-      getpkt (target_buf, sizeof (target_buf), 0);
+      getpkt (&target_buf, &target_buf_size, 0);
     }
 }
 
@@ -1768,7 +1771,7 @@ trace_start_command (char *args, int fro
   if (target_is_remote ())
     {
       putpkt ("QTinit");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
       if (strcmp (target_buf, "OK"))
 	error (_("Target does not support this command."));
 
@@ -1785,7 +1788,7 @@ trace_start_command (char *args, int fro
 	if (t->actions)
 	  strcat (buf, "-");
 	putpkt (buf);
-	remote_get_noisy_reply (target_buf, sizeof (target_buf));
+	remote_get_noisy_reply (&target_buf, &target_buf_size);
 	if (strcmp (target_buf, "OK"))
 	  error (_("Target does not support tracepoints."));
 
@@ -1809,8 +1812,8 @@ trace_start_command (char *args, int fro
 			     ((tdp_actions[ndx + 1] || stepping_actions)
 			      ? '-' : 0));
 		    putpkt (buf);
-		    remote_get_noisy_reply (target_buf, 
-					    sizeof (target_buf));
+		    remote_get_noisy_reply (&target_buf,
+					    &target_buf_size);
 		    if (strcmp (target_buf, "OK"))
 		      error (_("Error on target while setting tracepoints."));
 		  }
@@ -1826,8 +1829,8 @@ trace_start_command (char *args, int fro
 			     stepping_actions[ndx],
 			     (stepping_actions[ndx + 1] ? "-" : ""));
 		    putpkt (buf);
-		    remote_get_noisy_reply (target_buf, 
-					    sizeof (target_buf));
+		    remote_get_noisy_reply (&target_buf,
+					    &target_buf_size);
 		    if (strcmp (target_buf, "OK"))
 		      error (_("Error on target while setting tracepoints."));
 		  }
@@ -1840,7 +1843,7 @@ trace_start_command (char *args, int fro
       remote_set_transparent_ranges ();
       /* Now insert traps and begin collecting data.  */
       putpkt ("QTStart");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
       if (strcmp (target_buf, "OK"))
 	error (_("Bogus reply from target: %s"), target_buf);
       set_traceframe_num (-1);	/* All old traceframes invalidated.  */
@@ -1862,7 +1865,7 @@ trace_stop_command (char *args, int from
   if (target_is_remote ())
     {
       putpkt ("QTStop");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
       if (strcmp (target_buf, "OK"))
 	error (_("Bogus reply from target: %s"), target_buf);
       trace_running_p = 0;
@@ -1882,7 +1885,7 @@ trace_status_command (char *args, int fr
   if (target_is_remote ())
     {
       putpkt ("qTStatus");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
 
       if (target_buf[0] != 'T' ||
 	  (target_buf[1] != '0' && target_buf[1] != '1'))
@@ -1897,8 +1900,8 @@ trace_status_command (char *args, int fr
 
 /* Worker function for the various flavors of the tfind command.  */
 static void
-finish_tfind_command (char *msg,
-		      long sizeof_msg,
+finish_tfind_command (char **msg,
+		      long *sizeof_msg,
 		      int from_tty)
 {
   int target_frameno = -1, target_tracept = -1;
@@ -1909,7 +1912,7 @@ finish_tfind_command (char *msg,
   old_frame_addr = get_frame_base (get_current_frame ());
   old_func = find_pc_function (read_pc ());
 
-  putpkt (msg);
+  putpkt (*msg);
   reply = remote_get_noisy_reply (msg, sizeof_msg);
 
   while (reply && *reply)
@@ -2054,7 +2057,7 @@ trace_find_command (char *args, int from
 	error (_("invalid input (%d is less than zero)"), frameno);
 
       sprintf (target_buf, "QTFrame:%x", frameno);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2097,7 +2100,7 @@ trace_find_pc_command (char *args, int f
 
       sprintf_vma (tmp, pc);
       sprintf (target_buf, "QTFrame:pc:%s", tmp);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2122,7 +2125,7 @@ trace_find_tracepoint_command (char *arg
 	tdp = parse_and_eval_long (args);
 
       sprintf (target_buf, "QTFrame:tdp:%x", tdp);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2220,7 +2223,7 @@ trace_find_line_command (char *args, int
       else
 	sprintf (target_buf, "QTFrame:outside:%s:%s", 
 		 startpc_str, endpc_str);
-      finish_tfind_command (target_buf, sizeof (target_buf), 
+      finish_tfind_command (&target_buf, &target_buf_size,
 			    from_tty);
       do_cleanups (old_chain);
     }
@@ -2261,7 +2264,7 @@ trace_find_range_command (char *args, in
       sprintf_vma (start_str, start);
       sprintf_vma (stop_str, stop);
       sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2300,7 +2303,7 @@ trace_find_outside_command (char *args, 
       sprintf_vma (start_str, start);
       sprintf_vma (stop_str, stop);
       sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2867,4 +2870,7 @@ Do \"help tracepoints\" for info on othe
   add_com_alias ("tr", "trace", class_alias, 1);
   add_com_alias ("tra", "trace", class_alias, 1);
   add_com_alias ("trac", "trace", class_alias, 1);
+
+  target_buf_size = 2048;
+  target_buf = xmalloc (target_buf_size);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]