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]

Re: RFC: remote.c incoming packet cleanups


On Fri, Feb 24, 2006 at 09:42:17AM +0200, Eli Zaretskii wrote:
> This is fine with me, but you wrote this code in get_memory_packet_size:
> 
> > @@ -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;
> >  }
> 
> I wonder whether it would be better to expand by multiplying the
> previous size by 2, instead of just making enough room for the current
> packet.  The latter could cause bad memory fragmentation under some
> pathological patterns of packet size sequences.  (And in read_frame you
> indeed multiply by two when you realloc the buffer.)

This only happens, basically, once - it doesn't depend on the size of
packets received from the inferior except for the 'g' packet, which
should always be of a constant size.  But it does no harm to be
generous with memory here; we're talking about 2K - 4K on typical
targets, and this is in the GDB client.  Changed.

> > 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.
> 
> Would it make sense to add gdb_assert in strategic places to make sure
> any overlapping uses will be caught red-handed?

I spent a little while trying to find a way to do this, but I couldn't.

I've committed this version.  Thank you both for the comments!

-- 
Daniel Jacobowitz
CodeSourcery

2006-03-30  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.203
diff -u -p -r1.203 remote.c
--- remote.c	17 Mar 2006 00:25:45 -0000	1.203
+++ remote.c	30 Mar 2006 16:24:27 -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;
 }
 
@@ -435,6 +454,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 = 2 * what_they_get;
+      rs->buf = xrealloc (rs->buf, 2 * what_they_get);
+    }
+
   return what_they_get;
 }
 
@@ -884,7 +912,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)
@@ -902,7 +930,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
@@ -914,15 +942,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');
 }
 
@@ -1331,7 +1360,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.  */
@@ -1422,11 +1451,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;
@@ -1460,7 +1489,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);
@@ -1483,21 +1512,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))
@@ -1602,10 +1629,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
@@ -1641,7 +1668,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;
 
@@ -1651,8 +1677,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 */
@@ -1671,8 +1697,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 */
 	}
@@ -1702,7 +1728,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 */
@@ -1711,10 +1736,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));
@@ -1760,17 +1787,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.  */
@@ -1789,14 +1815,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
@@ -1955,14 +1981,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)
     {
@@ -1977,7 +2006,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);
     }
 }
 
@@ -2123,9 +2152,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);
@@ -2143,14 +2171,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 ())
@@ -2244,11 +2271,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)
@@ -2302,17 +2331,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
@@ -2360,7 +2383,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);
 
@@ -2379,7 +2402,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;
@@ -2649,7 +2672,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;
 
@@ -2661,7 +2684,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
@@ -2838,7 +2861,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;
 
@@ -2857,7 +2880,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);
 
@@ -3041,7 +3064,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;
 
@@ -3049,7 +3072,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.  */
@@ -3086,7 +3109,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);
@@ -3129,7 +3152,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
@@ -3151,7 +3174,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
@@ -3250,7 +3273,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;
 
@@ -3258,7 +3281,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';
 }
@@ -3271,7 +3294,6 @@ static void
 remote_store_registers (int regnum)
 {
   struct remote_state *rs = get_remote_state ();
-  char *buf;
   gdb_byte *regs;
   char *p;
 
@@ -3322,12 +3344,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);
 }
 
 
@@ -3413,7 +3434,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;
@@ -3425,7 +3446,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')
 	  {
@@ -3458,10 +3479,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;
@@ -3473,10 +3494,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".
@@ -3583,7 +3603,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')
     {
@@ -3618,15 +3638,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)
@@ -3648,7 +3668,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])
@@ -3747,18 +3767,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
@@ -3791,8 +3813,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;
@@ -3874,7 +3894,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 +.  */
 	      }
@@ -3908,29 +3928,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)
 	{
@@ -3997,51 +4053,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;
@@ -4051,22 +4109,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)
     {
@@ -4118,7 +4175,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);
@@ -4323,8 +4380,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';
@@ -4334,10 +4390,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;
@@ -4375,8 +4431,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';
@@ -4387,10 +4442,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
@@ -4424,7 +4479,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);
 
@@ -4433,16 +4487,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:
@@ -4459,7 +4513,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);
 
@@ -4468,15 +4521,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:
@@ -4546,8 +4599,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.  */
@@ -4567,10 +4619,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:
@@ -4588,8 +4640,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.  */
@@ -4609,10 +4660,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:
@@ -4694,7 +4745,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;
@@ -4722,9 +4772,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.  */
@@ -4733,14 +4783,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: ",
@@ -4769,8 +4819,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.  */
@@ -4820,22 +4869,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);
@@ -4869,6 +4918,7 @@ remote_xfer_partial (struct target_ops *
   gdb_assert (annex != NULL);
   gdb_assert (readbuf != NULL);
 
+  p2 = rs->buf;
   *p2++ = 'q';
   *p2++ = query_type;
 
@@ -4888,11 +4938,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);
 }
@@ -4902,7 +4953,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)
@@ -4922,7 +4973,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 */
@@ -4930,7 +4981,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')
@@ -4958,7 +5009,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"));
@@ -4971,9 +5021,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");
 }
 
@@ -5143,8 +5193,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:");
@@ -5156,14 +5205,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	30 Mar 2006 16:24:27 -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.85
diff -u -p -r1.85 tracepoint.c
--- tracepoint.c	17 Mar 2006 00:38:19 -0000	1.85
+++ tracepoint.c	30 Mar 2006 16:24:27 -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]