[v2,1/3] GDBServer: introduce a stream dedicated to the server

Message ID 1427316472-20629-2-git-send-email-crosa@redhat.com
State New, archived
Headers

Commit Message

Cleber Rosa March 25, 2015, 8:47 p.m. UTC
  This dedicated stream, named server_output, is intended to be the
only stream written by the server itself to announce errors. At this
point it is just a pointer to the regular stderr.

gdb/gdbserver/Changelog:
2015-03-24  Cleber Rosa  <crosa@redhat.com>

	* ax.c: Define server_output as an alias of stderr
	when compiling the IPA.
	(ax_vdebug): Replace stderr with server_output.
	* debug.c (debug_vprintf): Replace stderr with server_output.
	(debug_flush): Likewise.
	* event-loop.c (handle_file_event): Likewise.
	* linux-aarch64-low.c (aarch64_show_debug_reg_state):
        Likewise.
	(debug_reg_change_callback): Likewise.
	(aarch64_handle_unaligned_watchpoint): Likewise.
	(aarch64_insert_point): Likewise.
	(aarch64_remove_point): Likewise.
	(aarch64_linux_prepare_to_resume): Likewise.
	* linux-low.c (linux_create_inferior): Likewise.
	(linux_attach): Likewise.
	(check_zombie_leaders): Likewise.
	(linux_resume_one_lwp_throw): Likewise.
	* lynx-low.c (lynx_debug): Likewise.
	(lynx_ptrace): Likewise.
	(lynx_create_inferior): Likewise.
	* mem-break.c (add_breakpoint_condition): Likewise.
	(add_breakpoint_commands): Likewise.
	* notif.c (handle_notif_ack): Likewise.
	(notif_event_enque): Likewise.
	* nto-low.c (nto_trace): Likewise.
	* remote-utils.c (handle_accept_event): Likewise.
	(remote_open): Likewise.
	(putpkt_binary_1): Likewise.
	(input_interrupt): Likewise.
	(readchar): Likewise.
	(getpkt): Likewise.
	* server.c: New server_output stream.
	(start_inferior): Replace stderr with server_output.
	(attach_inferior): Likewise.
	(handle_general_set): Likewise.
	(handle_v_requests): Likewise.
	(print_started_pid): Likewise.
	(print_attached_pid): Likewise.
	(detach_or_kill_for_exit): Likewise.
	(detach_or_kill_for_exit_cleanup): Likewise.
	(captured_main): Point server_output to standard stderr and
	replace stderr with server_output.
	(main): Replace stderr with server_output.
	(process_point_options): Likewise.
	(process_serial_event): Likewise.
	* server.h: New server_output stream definition.
	* spu-low.c (spu_create_inferior): Replace stderr with
        server_output.
	(spu_attach): Likewise.
	(spu_resume): Likewise.
	(spu_wait): Likewise.
	* target.c (mywait): Likewise.
	* thread-db.c (thread_db_create_event): Likewise.
	(try_thread_db_load): Likewise.
	* tracepoint.c: Define server_output as an alias of stderr
	when compiling the IPA.
	(trace_vdebug): Replace stderr with server_output.
	* utils.c: Define server_output as an alias of stderr when
	compiling the IPA.
	(malloc_failure): Replace stderr with gdbserver's own stderr.
	(verror): Likewise.
	(vwarning): Likewise.
	(internal_verror): Likewise.
	(internal_vwarning): Likewise.
	* win32-low.c (OUTMSG): Changed definition of macro to also
	use server_output instead of stderr.
	(OUTMSG2): Likewise.
	* wincecompat.c (perror): Likewise.
---
 gdb/gdbserver/ax.c                |  3 +-
 gdb/gdbserver/debug.c             |  6 +--
 gdb/gdbserver/event-loop.c        |  2 +-
 gdb/gdbserver/linux-aarch64-low.c | 28 ++++++-------
 gdb/gdbserver/linux-low.c         | 10 ++---
 gdb/gdbserver/lynx-low.c          | 14 +++----
 gdb/gdbserver/mem-break.c         |  4 +-
 gdb/gdbserver/notif.c             |  4 +-
 gdb/gdbserver/nto-low.c           |  4 +-
 gdb/gdbserver/remote-utils.c      | 54 ++++++++++++-------------
 gdb/gdbserver/server.c            | 83 ++++++++++++++++++++-------------------
 gdb/gdbserver/server.h            |  4 ++
 gdb/gdbserver/spu-low.c           | 14 +++----
 gdb/gdbserver/target.c            |  4 +-
 gdb/gdbserver/thread-db.c         |  4 +-
 gdb/gdbserver/tracepoint.c        |  4 +-
 gdb/gdbserver/utils.c             | 25 ++++++------
 gdb/gdbserver/win32-low.c         |  6 +--
 gdb/gdbserver/wincecompat.c       |  4 +-
 19 files changed, 144 insertions(+), 133 deletions(-)
  

Patch

diff --git a/gdb/gdbserver/ax.c b/gdb/gdbserver/ax.c
index c5b65fa..db94eb7 100644
--- a/gdb/gdbserver/ax.c
+++ b/gdb/gdbserver/ax.c
@@ -26,6 +26,7 @@  static void ax_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 #ifdef IN_PROCESS_AGENT
 int debug_agent = 0;
+#define server_output stderr
 #endif
 
 static void
@@ -36,7 +37,7 @@  ax_vdebug (const char *fmt, ...)
 
   va_start (ap, fmt);
   vsprintf (buf, fmt, ap);
-  fprintf (stderr, PROG "/ax: %s\n", buf);
+  fprintf (server_output, PROG "/ax: %s\n", buf);
   va_end (ap);
 }
 
diff --git a/gdb/gdbserver/debug.c b/gdb/gdbserver/debug.c
index 1a1e333..df59f8b 100644
--- a/gdb/gdbserver/debug.c
+++ b/gdb/gdbserver/debug.c
@@ -48,11 +48,11 @@  debug_vprintf (const char *format, va_list ap)
       /* If gettimeofday doesn't exist, and as a portability solution it has
 	 been replaced with, e.g., time, then it doesn't make sense to print
 	 the microseconds field.  Is there a way to check for that?  */
-      fprintf (stderr, "%ld:%06ld ", (long) tm.tv_sec, (long) tm.tv_usec);
+      fprintf (server_output, "%ld:%06ld ", (long) tm.tv_sec, (long) tm.tv_usec);
     }
 #endif
 
-  vfprintf (stderr, format, ap);
+  vfprintf (server_output, format, ap);
 
 #if !defined (IN_PROCESS_AGENT)
   if (*format)
@@ -67,7 +67,7 @@  debug_vprintf (const char *format, va_list ap)
 void
 debug_flush (void)
 {
-  fflush (stderr);
+  fflush (server_output);
 }
 
 /* Notify the user that the code is entering FUNCTION_NAME.
diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c
index 08a503f..d744602 100644
--- a/gdb/gdbserver/event-loop.c
+++ b/gdb/gdbserver/event-loop.c
@@ -412,7 +412,7 @@  handle_file_event (gdb_fildes_t event_file_desc)
 
 	  if (file_ptr->ready_mask & GDB_EXCEPTION)
 	    {
-	      fprintf (stderr, "Exception condition detected on fd %s\n",
+	      fprintf (server_output, "Exception condition detected on fd %s\n",
 		       pfildes (file_ptr->fd));
 	      file_ptr->error = 1;
 	    }
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index d44175e..f344ba1 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -323,26 +323,26 @@  aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state,
 {
   int i;
 
-  fprintf (stderr, "%s", func);
+  fprintf (server_output, "%s", func);
   if (addr || len)
-    fprintf (stderr, " (addr=0x%08lx, len=%d, type=%s)",
+    fprintf (server_output, " (addr=0x%08lx, len=%d, type=%s)",
 	     (unsigned long) addr, len,
 	     type == hw_write ? "hw-write-watchpoint"
 	     : (type == hw_read ? "hw-read-watchpoint"
 		: (type == hw_access ? "hw-access-watchpoint"
 		   : (type == hw_execute ? "hw-breakpoint"
 		      : "??unknown??"))));
-  fprintf (stderr, ":\n");
+  fprintf (server_output, ":\n");
 
-  fprintf (stderr, "\tBREAKPOINTs:\n");
+  fprintf (server_output, "\tBREAKPOINTs:\n");
   for (i = 0; i < aarch64_num_bp_regs; i++)
-    fprintf (stderr, "\tBP%d: addr=0x%s, ctrl=0x%08x, ref.count=%d\n",
+    fprintf (server_output, "\tBP%d: addr=0x%s, ctrl=0x%08x, ref.count=%d\n",
 	     i, paddress (state->dr_addr_bp[i]),
 	     state->dr_ctrl_bp[i], state->dr_ref_count_bp[i]);
 
-  fprintf (stderr, "\tWATCHPOINTs:\n");
+  fprintf (server_output, "\tWATCHPOINTs:\n");
   for (i = 0; i < aarch64_num_wp_regs; i++)
-    fprintf (stderr, "\tWP%d: addr=0x%s, ctrl=0x%08x, ref.count=%d\n",
+    fprintf (server_output, "\tWP%d: addr=0x%s, ctrl=0x%08x, ref.count=%d\n",
 	     i, paddress (state->dr_addr_wp[i]),
 	     state->dr_ctrl_wp[i], state->dr_ref_count_wp[i]);
 }
@@ -631,8 +631,8 @@  debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
 
   if (show_debug_regs)
     {
-      fprintf (stderr, "debug_reg_change_callback: \n\tOn entry:\n");
-      fprintf (stderr, "\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
+      fprintf (server_output, "debug_reg_change_callback: \n\tOn entry:\n");
+      fprintf (server_output, "\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
 	       "dr_changed_wp=0x%llx\n",
 	       pid, lwpid_of (thread), info->dr_changed_bp,
 	       info->dr_changed_wp);
@@ -682,7 +682,7 @@  debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
 
   if (show_debug_regs)
     {
-      fprintf (stderr, "\tOn exit:\n\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
+      fprintf (server_output, "\tOn exit:\n\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
 	       "dr_changed_wp=0x%llx\n",
 	       pid, lwpid_of (thread), info->dr_changed_bp,
 	       info->dr_changed_wp);
@@ -921,7 +921,7 @@  aarch64_handle_unaligned_watchpoint (enum target_hw_bp_type type,
 						 aligned_len);
 
       if (show_debug_regs)
-	fprintf (stderr,
+	fprintf (server_output,
  "handle_unaligned_watchpoint: is_insert: %d\n"
  "                             aligned_addr: 0x%s, aligned_len: %d\n"
  "                                next_addr: 0x%s,    next_len: %d\n",
@@ -977,7 +977,7 @@  aarch64_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
   enum target_hw_bp_type targ_type;
 
   if (show_debug_regs)
-    fprintf (stderr, "insert_point on entry (addr=0x%08lx, len=%d)\n",
+    fprintf (server_output, "insert_point on entry (addr=0x%08lx, len=%d)\n",
 	     (unsigned long) addr, len);
 
   /* Determine the type from the raw breakpoint type.  */
@@ -1013,7 +1013,7 @@  aarch64_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
   enum target_hw_bp_type targ_type;
 
   if (show_debug_regs)
-    fprintf (stderr, "remove_point on entry (addr=0x%08lx, len=%d)\n",
+    fprintf (server_output, "remove_point on entry (addr=0x%08lx, len=%d)\n",
 	     (unsigned long) addr, len);
 
   /* Determine the type from the raw breakpoint type.  */
@@ -1154,7 +1154,7 @@  aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
 	= &proc->priv->arch_private->debug_reg_state;
 
       if (show_debug_regs)
-	fprintf (stderr, "prepare_to_resume thread %ld\n", lwpid_of (thread));
+	fprintf (server_output, "prepare_to_resume thread %ld\n", lwpid_of (thread));
 
       /* Watchpoints.  */
       if (DR_HAS_CHANGED (info->dr_changed_wp))
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index e4c5420..c1bf202 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -724,9 +724,9 @@  linux_create_inferior (char *program, char **allargs)
       if (errno == ENOENT)
 	execvp (program, allargs);
 
-      fprintf (stderr, "Cannot exec %s: %s.\n", program,
+      fprintf (server_output, "Cannot exec %s: %s.\n", program,
 	       strerror (errno));
-      fflush (stderr);
+      fflush (server_output);
       _exit (0177);
     }
 
@@ -1560,7 +1560,7 @@  check_zombie_leaders (void)
 	     thread execs).  */
 
 	  if (debug_threads)
-	    fprintf (stderr,
+	    fprintf (server_output,
 		     "CZL: Thread group leader %d zombie "
 		     "(it exited, or another thread execd).\n",
 		     leader_pid);
@@ -3584,9 +3584,9 @@  linux_resume_one_lwp_throw (struct lwp_info *lwp,
 	  if (fast_tp_collecting == 0)
 	    {
 	      if (step == 0)
-		fprintf (stderr, "BAD - reinserting but not stepping.\n");
+		fprintf (server_output, "BAD - reinserting but not stepping.\n");
 	      if (lwp->suspended)
-		fprintf (stderr, "BAD - reinserting and suspended(%d).\n",
+		fprintf (server_output, "BAD - reinserting and suspended(%d).\n",
 			 lwp->suspended);
 	    }
 
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index 2f85829..0257f3d 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -53,9 +53,9 @@  lynx_debug (char *string, ...)
     return;
 
   va_start (args, string);
-  fprintf (stderr, "DEBUG(lynx): ");
-  vfprintf (stderr, string, args);
-  fprintf (stderr, "\n");
+  fprintf (server_output, "DEBUG(lynx): ");
+  vfprintf (server_output, string, args);
+  fprintf (server_output, "\n");
   va_end (args);
 }
 
@@ -195,14 +195,14 @@  lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2)
   int saved_errno;
 
   if (debug_threads)
-    fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, "
+    fprintf (server_output, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, "
              "data=0x%x, addr2=0x%x)",
              ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid),
              addr, data, addr2);
   result = ptrace (request, pid, addr, data, addr2);
   saved_errno = errno;
   if (debug_threads)
-    fprintf (stderr, " -> %d (=0x%x)\n", result, result);
+    fprintf (server_output, " -> %d (=0x%x)\n", result, result);
 
   errno = saved_errno;
   return result;
@@ -250,8 +250,8 @@  lynx_create_inferior (char *program, char **allargs)
       ioctl (0, TIOCSPGRP, &pgrp);
       lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0);
       execv (program, allargs);
-      fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno));
-      fflush (stderr);
+      fprintf (server_output, "Cannot exec %s: %s.\n", program, strerror (errno));
+      fflush (server_output);
       _exit (0177);
     }
 
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index 70fab2e..e2fa503 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -1179,7 +1179,7 @@  add_breakpoint_condition (struct breakpoint *bp, char **condition)
 
   if (cond == NULL)
     {
-      fprintf (stderr, "Condition evaluation failed. "
+      fprintf (server_output, "Condition evaluation failed. "
 	       "Assuming unconditional.\n");
       return 0;
     }
@@ -1279,7 +1279,7 @@  add_breakpoint_commands (struct breakpoint *bp, char **command,
 
   if (cmd == NULL)
     {
-      fprintf (stderr, "Command evaluation failed. "
+      fprintf (server_output, "Command evaluation failed. "
 	       "Disabling.\n");
       return 0;
     }
diff --git a/gdb/gdbserver/notif.c b/gdb/gdbserver/notif.c
index 436c1b8..af10a14 100644
--- a/gdb/gdbserver/notif.c
+++ b/gdb/gdbserver/notif.c
@@ -104,7 +104,7 @@  handle_notif_ack (char *own_buf, int packet_len)
 	= QUEUE_deque (notif_event_p, np->queue);
 
       if (remote_debug)
-	fprintf (stderr, "%s: acking %d\n", np->ack_name,
+	fprintf (server_output, "%s: acking %d\n", np->ack_name,
 		 QUEUE_length (notif_event_p, np->queue));
 
       xfree (head);
@@ -124,7 +124,7 @@  notif_event_enque (struct notif_server *notif,
   QUEUE_enque (notif_event_p, notif->queue, event);
 
   if (remote_debug)
-    fprintf (stderr, "pending events: %s %d\n", notif->notif_name,
+    fprintf (server_output, "pending events: %s %d\n", notif->notif_name,
 	     QUEUE_length (notif_event_p, notif->queue));
 
 }
diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c
index 801d76a..f3d52dd 100644
--- a/gdb/gdbserver/nto-low.c
+++ b/gdb/gdbserver/nto-low.c
@@ -44,9 +44,9 @@  nto_trace (const char *fmt, ...)
 
   if (debug_threads == 0)
     return;
-  fprintf (stderr, "nto:");
+  fprintf (server_output, "nto:");
   va_start (arg_list, fmt);
-  vfprintf (stderr, fmt, arg_list);
+  vfprintf (server_output, fmt, arg_list);
   va_end (arg_list);
 }
 
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 1de86be..34f3a07 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -194,7 +194,7 @@  handle_accept_event (int err, gdb_client_data client_data)
   delete_file_handler (listen_desc);
 
   /* Convert IP address to string.  */
-  fprintf (stderr, "Remote debugging from host %s\n",
+  fprintf (server_output, "Remote debugging from host %s\n",
 	   inet_ntoa (sockaddr.sin_addr));
 
   enable_async_notification (remote_desc);
@@ -296,7 +296,7 @@  remote_open (char *name)
 
   if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
     {
-      fprintf (stderr, "Remote debugging using stdio\n");
+      fprintf (server_output, "Remote debugging using stdio\n");
 
       /* Use stdin as the handle of the connection.
 	 We only select on reads, for example.  */
@@ -368,7 +368,7 @@  remote_open (char *name)
       }
 #endif
 
-      fprintf (stderr, "Remote debugging using %s\n", name);
+      fprintf (server_output, "Remote debugging using %s\n", name);
 
       enable_async_notification (remote_desc);
 
@@ -389,8 +389,8 @@  remote_open (char *name)
 	perror_with_name ("Can't determine port");
       port = ntohs (sockaddr.sin_port);
 
-      fprintf (stderr, "Listening on port %d\n", port);
-      fflush (stderr);
+      fprintf (server_output, "Listening on port %d\n", port);
+      fflush (server_output);
 
       /* Register the event loop handler.  */
       add_file_handler (listen_desc, handle_accept_event, NULL);
@@ -658,18 +658,18 @@  putpkt_binary_1 (char *buf, int cnt, int is_notif)
 	  if (remote_debug)
 	    {
 	      if (is_notif)
-		fprintf (stderr, "putpkt (\"%s\"); [notif]\n", buf2);
+		fprintf (server_output, "putpkt (\"%s\"); [notif]\n", buf2);
 	      else
-		fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2);
-	      fflush (stderr);
+		fprintf (server_output, "putpkt (\"%s\"); [noack mode]\n", buf2);
+	      fflush (server_output);
 	    }
 	  break;
 	}
 
       if (remote_debug)
 	{
-	  fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
-	  fflush (stderr);
+	  fprintf (server_output, "putpkt (\"%s\"); [looking for ack]\n", buf2);
+	  fflush (server_output);
 	}
 
       cc = readchar ();
@@ -682,8 +682,8 @@  putpkt_binary_1 (char *buf, int cnt, int is_notif)
 
       if (remote_debug)
 	{
-	  fprintf (stderr, "[received '%c' (0x%x)]\n", cc, cc);
-	  fflush (stderr);
+	  fprintf (server_output, "[received '%c' (0x%x)]\n", cc, cc);
+	  fflush (server_output);
 	}
 
       /* Check for an input interrupt while we're here.  */
@@ -744,16 +744,16 @@  input_interrupt (int unused)
 
       if (cc == 0)
 	{
-	  fprintf (stderr, "client connection closed\n");
+	  fprintf (server_output, "client connection closed\n");
 	  return;
 	}
       else if (cc != 1 || c != '\003' || current_thread == NULL)
 	{
-	  fprintf (stderr, "input_interrupt, count = %d c = %d ", cc, c);
+	  fprintf (server_output, "input_interrupt, count = %d c = %d ", cc, c);
 	  if (isprint (c))
-	    fprintf (stderr, "('%c')\n", c);
+	    fprintf (server_output, "('%c')\n", c);
 	  else
-	    fprintf (stderr, "('\\x%02x')\n", c & 0xff);
+	    fprintf (server_output, "('\\x%02x')\n", c & 0xff);
 	  return;
 	}
 
@@ -881,7 +881,7 @@  readchar (void)
       if (readchar_bufcnt <= 0)
 	{
 	  if (readchar_bufcnt == 0)
-	    fprintf (stderr, "readchar: Got EOF\n");
+	    fprintf (server_output, "readchar: Got EOF\n");
 	  else
 	    perror ("readchar");
 
@@ -959,8 +959,8 @@  getpkt (char *buf)
 	    break;
 	  if (remote_debug)
 	    {
-	      fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
-	      fflush (stderr);
+	      fprintf (server_output, "[getpkt: discarding char '%c']\n", c);
+	      fflush (server_output);
 	    }
 
 	  if (c < 0)
@@ -988,7 +988,7 @@  getpkt (char *buf)
 
       if (noack_mode)
 	{
-	  fprintf (stderr,
+	  fprintf (server_output,
 		   "Bad checksum, sentsum=0x%x, csum=0x%x, "
 		   "buf=%s [no-ack-mode, Bad medium?]\n",
 		   (c1 << 4) + c2, csum, buf);
@@ -996,7 +996,7 @@  getpkt (char *buf)
 	  break;
 	}
 
-      fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
+      fprintf (server_output, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
 	       (c1 << 4) + c2, csum, buf);
       if (write_prim ("-", 1) != 1)
 	return -1;
@@ -1006,8 +1006,8 @@  getpkt (char *buf)
     {
       if (remote_debug)
 	{
-	  fprintf (stderr, "getpkt (\"%s\");  [sending ack] \n", buf);
-	  fflush (stderr);
+	  fprintf (server_output, "getpkt (\"%s\");  [sending ack] \n", buf);
+	  fflush (server_output);
 	}
 
       if (write_prim ("+", 1) != 1)
@@ -1015,16 +1015,16 @@  getpkt (char *buf)
 
       if (remote_debug)
 	{
-	  fprintf (stderr, "[sent ack]\n");
-	  fflush (stderr);
+	  fprintf (server_output, "[sent ack]\n");
+	  fflush (server_output);
 	}
     }
   else
     {
       if (remote_debug)
 	{
-	  fprintf (stderr, "getpkt (\"%s\");  [no ack sent] \n", buf);
-	  fflush (stderr);
+	  fprintf (server_output, "getpkt (\"%s\");  [no ack sent] \n", buf);
+	  fflush (server_output);
 	}
     }
 
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 96b31b8..73f9f6c 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -60,6 +60,7 @@  int multi_process;
 int non_stop;
 int swbreak_feature;
 int hwbreak_feature;
+FILE *server_output;
 
 /* Whether we should attempt to disable the operating system's address
    space randomization feature before starting an inferior.  */
@@ -231,9 +232,9 @@  start_inferior (char **argv)
 
   /* FIXME: we don't actually know at this point that the create
      actually succeeded.  We won't know that until we wait.  */
-  fprintf (stderr, "Process %s created; pid = %ld\n", argv[0],
+  fprintf (server_output, "Process %s created; pid = %ld\n", argv[0],
 	   signal_pid);
-  fflush (stderr);
+  fflush (server_output);
 
 #ifdef SIGTTOU
   signal (SIGTTOU, SIG_IGN);
@@ -297,8 +298,8 @@  attach_inferior (int pid)
   if (myattach (pid) != 0)
     return -1;
 
-  fprintf (stderr, "Attached; pid = %d\n", pid);
-  fflush (stderr);
+  fprintf (server_output, "Attached; pid = %d\n", pid);
+  fflush (server_output);
 
   /* FIXME - It may be that we should get the SIGNAL_PID from the
      attach function, so that it can be the main thread instead of
@@ -578,8 +579,8 @@  handle_general_set (char *own_buf)
     {
       if (remote_debug)
 	{
-	  fprintf (stderr, "[noack mode enabled]\n");
-	  fflush (stderr);
+	  fprintf (server_output, "[noack mode enabled]\n");
+	  fflush (server_output);
 	}
 
       noack_mode = 1;
@@ -601,7 +602,7 @@  handle_general_set (char *own_buf)
 	{
 	  /* We don't know what this mode is, so complain to
 	     GDB.  */
-	  fprintf (stderr, "Unknown non-stop mode requested: %s\n",
+	  fprintf (server_output, "Unknown non-stop mode requested: %s\n",
 		   own_buf);
 	  write_enn (own_buf);
 	  return;
@@ -610,7 +611,7 @@  handle_general_set (char *own_buf)
       req_str = req ? "non-stop" : "all-stop";
       if (start_non_stop (req) != 0)
 	{
-	  fprintf (stderr, "Setting %s mode failed\n", req_str);
+	  fprintf (server_output, "Setting %s mode failed\n", req_str);
 	  write_enn (own_buf);
 	  return;
 	}
@@ -618,7 +619,7 @@  handle_general_set (char *own_buf)
       non_stop = req;
 
       if (remote_debug)
-	fprintf (stderr, "[%s mode enabled]\n", req_str);
+	fprintf (server_output, "[%s mode enabled]\n", req_str);
 
       write_ok (own_buf);
       return;
@@ -635,9 +636,9 @@  handle_general_set (char *own_buf)
       if (remote_debug)
 	{
 	  if (disable_randomization)
-	    fprintf (stderr, "[address space randomization disabled]\n");
+	    fprintf (server_output, "[address space randomization disabled]\n");
 	  else
-	    fprintf (stderr, "[address space randomization enabled]\n");
+	    fprintf (server_output, "[address space randomization enabled]\n");
 	}
 
       write_ok (own_buf);
@@ -667,7 +668,7 @@  handle_general_set (char *own_buf)
       /* Update the flag.  */
       use_agent = req;
       if (remote_debug)
-	fprintf (stderr, "[%s agent]\n", req ? "Enable" : "Disable");
+	fprintf (server_output, "[%s agent]\n", req ? "Enable" : "Disable");
       write_ok (own_buf);
       return;
     }
@@ -2696,7 +2697,7 @@  handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
     {
       if ((!extended_protocol || !multi_process) && target_running ())
 	{
-	  fprintf (stderr, "Already debugging a process\n");
+	  fprintf (server_output, "Already debugging a process\n");
 	  write_enn (own_buf);
 	  return;
 	}
@@ -2708,7 +2709,7 @@  handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
     {
       if ((!extended_protocol || !multi_process) && target_running ())
 	{
-	  fprintf (stderr, "Already debugging a process\n");
+	  fprintf (server_output, "Already debugging a process\n");
 	  write_enn (own_buf);
 	  return;
 	}
@@ -2720,7 +2721,7 @@  handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
     {
       if (!target_running ())
 	{
-	  fprintf (stderr, "No process to kill\n");
+	  fprintf (server_output, "No process to kill\n");
 	  write_enn (own_buf);
 	  return;
 	}
@@ -3088,7 +3089,7 @@  print_started_pid (struct inferior_list_entry *entry)
   if (! process->attached)
     {
       int pid = ptid_get_pid (process->entry.id);
-      fprintf (stderr, " %d", pid);
+      fprintf (server_output, " %d", pid);
     }
 }
 
@@ -3103,7 +3104,7 @@  print_attached_pid (struct inferior_list_entry *entry)
   if (process->attached)
     {
       int pid = ptid_get_pid (process->entry.id);
-      fprintf (stderr, " %d", pid);
+      fprintf (server_output, " %d", pid);
     }
 }
 
@@ -3120,15 +3121,15 @@  detach_or_kill_for_exit (void)
 
   if (have_started_inferiors_p ())
     {
-      fprintf (stderr, "Killing process(es):");
+      fprintf (server_output, "Killing process(es):");
       for_each_inferior (&all_processes, print_started_pid);
-      fprintf (stderr, "\n");
+      fprintf (server_output, "\n");
     }
   if (have_attached_inferiors_p ())
     {
-      fprintf (stderr, "Detaching process(es):");
+      fprintf (server_output, "Detaching process(es):");
       for_each_inferior (&all_processes, print_attached_pid);
-      fprintf (stderr, "\n");
+      fprintf (server_output, "\n");
     }
 
   /* Now we can kill or detach the inferiors.  */
@@ -3153,7 +3154,7 @@  detach_or_kill_for_exit_cleanup (void *ignore)
   CATCH (exception, RETURN_MASK_ALL)
     {
       fflush (stdout);
-      fprintf (stderr, "Detach or kill failed: %s\n", exception.message);
+      fprintf (server_output, "Detach or kill failed: %s\n", exception.message);
       exit_code = 1;
     }
   END_CATCH
@@ -3173,6 +3174,8 @@  captured_main (int argc, char *argv[])
   volatile int attach = 0;
   int was_running;
 
+  server_output = stderr;
+
   while (*next_arg != NULL && **next_arg == '-')
     {
       if (strcmp (*next_arg, "--version") == 0)
@@ -3199,7 +3202,7 @@  captured_main (int argc, char *argv[])
 
 	  if (next_arg == wrapper_argv || *next_arg == NULL)
 	    {
-	      gdbserver_usage (stderr);
+	      gdbserver_usage (server_output);
 	      exit (1);
 	    }
 
@@ -3216,7 +3219,7 @@  captured_main (int argc, char *argv[])
 
 	  if (error_msg != NULL)
 	    {
-	      fprintf (stderr, "%s", error_msg);
+	      fprintf (server_output, "%s", error_msg);
 	      exit (1);
 	    }
 	}
@@ -3253,9 +3256,9 @@  captured_main (int argc, char *argv[])
 		}
 	      else
 		{
-		  fprintf (stderr, "Don't know how to disable \"%s\".\n\n",
+		  fprintf (server_output, "Don't know how to disable \"%s\".\n\n",
 			   tok);
-		  gdbserver_show_disableable (stderr);
+		  gdbserver_show_disableable (server_output);
 		  exit (1);
 		}
 	    }
@@ -3275,7 +3278,7 @@  captured_main (int argc, char *argv[])
 	run_once = 1;
       else
 	{
-	  fprintf (stderr, "Unknown argument: %s\n", *next_arg);
+	  fprintf (server_output, "Unknown argument: %s\n", *next_arg);
 	  exit (1);
 	}
 
@@ -3287,7 +3290,7 @@  captured_main (int argc, char *argv[])
   next_arg++;
   if (port == NULL || (!attach && !multi_mode && *next_arg == NULL))
     {
-      gdbserver_usage (stderr);
+      gdbserver_usage (server_output);
       exit (1);
     }
 
@@ -3322,7 +3325,7 @@  captured_main (int argc, char *argv[])
 
   if (bad_attach)
     {
-      gdbserver_usage (stderr);
+      gdbserver_usage (server_output);
       exit (1);
     }
 
@@ -3410,7 +3413,7 @@  captured_main (int argc, char *argv[])
 	  if (exit_requested || run_once)
 	    throw_quit ("Quit");
 
-	  fprintf (stderr,
+	  fprintf (server_output,
 		   "Remote side has terminated connection.  "
 		   "GDBserver will reopen the connection.\n");
 
@@ -3442,7 +3445,7 @@  captured_main (int argc, char *argv[])
 		}
 	      else
 		{
-		  fprintf (stderr,
+		  fprintf (server_output,
 			   "Disconnected tracing disabled; "
 			   "stopping trace run.\n");
 		  stop_tracing ();
@@ -3476,8 +3479,8 @@  main (int argc, char *argv[])
       if (exception.reason == RETURN_ERROR)
 	{
 	  fflush (stdout);
-	  fprintf (stderr, "%s\n", exception.message);
-	  fprintf (stderr, "Exiting\n");
+	  fprintf (server_output, "%s\n", exception.message);
+	  fprintf (server_output, "Exiting\n");
 	  exit_code = 1;
 	}
 
@@ -3538,7 +3541,7 @@  process_point_options (struct breakpoint *bp, char **packet)
 	}
       else
 	{
-	  fprintf (stderr, "Unknown token %c, ignoring.\n",
+	  fprintf (server_output, "Unknown token %c, ignoring.\n",
 		   *dataptr);
 	  /* Skip tokens until we find one that we recognize.  */
 	  skip_to_semicolon (&dataptr);
@@ -3618,12 +3621,12 @@  process_serial_event (void)
 	    }
 
 	  if (tracing && disconnected_tracing)
-	    fprintf (stderr,
+	    fprintf (server_output,
 		     "Disconnected tracing in effect, "
 		     "leaving gdbserver attached to the process\n");
 
 	  if (any_persistent_commands ())
-	    fprintf (stderr,
+	    fprintf (server_output,
 		     "Persistent commands are present, "
 		     "leaving gdbserver attached to the process\n");
 
@@ -3653,7 +3656,7 @@  process_serial_event (void)
 	  break; /* from switch/case */
 	}
 
-      fprintf (stderr, "Detaching from process %d\n", pid);
+      fprintf (server_output, "Detaching from process %d\n", pid);
       stop_tracing ();
       if (detach_inferior (pid) != 0)
 	write_enn (own_buf);
@@ -3907,7 +3910,7 @@  process_serial_event (void)
 	   reply to it, either.  */
 	return 0;
 
-      fprintf (stderr, "Killing all inferiors\n");
+      fprintf (server_output, "Killing all inferiors\n");
       for_each_inferior (&all_processes, kill_inferior_callback);
 
       /* When using the extended protocol, we wait with no program
@@ -3951,7 +3954,7 @@  process_serial_event (void)
 	  if (target_running ())
 	    for_each_inferior (&all_processes,
 			       kill_inferior_callback);
-	  fprintf (stderr, "GDBserver restarting\n");
+	  fprintf (server_output, "GDBserver restarting\n");
 
 	  /* Wait till we are at 1st instruction in prog.  */
 	  if (program_argv != NULL)
@@ -4000,7 +4003,7 @@  process_serial_event (void)
 	  /* Be transparent when GDB is connected through stdio -- no
 	     need to spam GDB's console.  */
 	  if (!remote_connection_is_stdio ())
-	    fprintf (stderr, "GDBserver exiting\n");
+	    fprintf (server_output, "GDBserver exiting\n");
 	  remote_close ();
 	  exit (0);
 	}
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 91d4080..4c5c916 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -86,6 +86,10 @@  extern int run_once;
 extern int multi_process;
 extern int non_stop;
 
+/* dedicated stream for the server error messages so that the inferior
+   stderr is not mixed with server's own.  */
+extern FILE *server_output;
+
 /* True if the "swbreak+" feature is active.  In that case, GDB wants
    us to report whether a trap is explained by a software breakpoint
    and for the server to handle PC adjustment if necessary on this
diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c
index 73f1786..dda5a79 100644
--- a/gdb/gdbserver/spu-low.c
+++ b/gdb/gdbserver/spu-low.c
@@ -281,9 +281,9 @@  spu_create_inferior (char *program, char **allargs)
       if (errno == ENOENT)
 	execvp (program, allargs);
 
-      fprintf (stderr, "Cannot exec %s: %s.\n", program,
+      fprintf (server_output, "Cannot exec %s: %s.\n", program,
 	       strerror (errno));
-      fflush (stderr);
+      fflush (server_output);
       _exit (0177);
     }
 
@@ -304,9 +304,9 @@  spu_attach (unsigned long  pid)
 
   if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
     {
-      fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid,
+      fprintf (server_output, "Cannot attach to process %ld: %s (%d)\n", pid,
 	       strerror (errno), errno);
-      fflush (stderr);
+      fflush (server_output);
       _exit (0177);
     }
 
@@ -396,7 +396,7 @@  spu_resume (struct thread_resume *resume_info, size_t n)
   /* We don't support hardware single-stepping right now, assume
      GDB knows to use software single-stepping.  */
   if (resume_info[i].kind == resume_step)
-    fprintf (stderr, "Hardware single-step not supported.\n");
+    fprintf (server_output, "Hardware single-step not supported.\n");
 
   regcache_invalidate ();
 
@@ -445,7 +445,7 @@  spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
 
   if (WIFEXITED (w))
     {
-      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+      fprintf (server_output, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
       ourstatus->kind =  TARGET_WAITKIND_EXITED;
       ourstatus->value.integer = WEXITSTATUS (w);
       clear_inferiors ();
@@ -453,7 +453,7 @@  spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
     }
   else if (!WIFSTOPPED (w))
     {
-      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+      fprintf (server_output, "\nChild terminated with signal = %x \n", WTERMSIG (w));
       ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
       ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
       clear_inferiors ();
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index 14999e6..708a43a 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -120,10 +120,10 @@  mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
   if (!remote_connection_is_stdio ())
     {
       if (ourstatus->kind == TARGET_WAITKIND_EXITED)
-	fprintf (stderr,
+	fprintf (server_output,
 		 "\nChild exited with status %d\n", ourstatus->value.integer);
       else if (ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
-	fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
+	fprintf (server_output, "\nChild terminated with signal = 0x%x (%s)\n",
 		 gdb_signal_to_host (ourstatus->value.sig),
 		 gdb_signal_to_name (ourstatus->value.sig));
     }
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 5bf808e..e0e25df 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -205,7 +205,7 @@  thread_db_create_event (CORE_ADDR where)
      (except for its own creation, of course).  */
   err = thread_db->td_ta_event_getmsg_p (thread_db->thread_agent, &msg);
   if (err != TD_OK)
-    fprintf (stderr, "thread getmsg err: %s\n",
+    fprintf (server_output, "thread getmsg err: %s\n",
 	     thread_db_err_str (err));
 
   /* If we do not know about the main thread yet, this would be a good time to
@@ -726,7 +726,7 @@  try_thread_db_load (const char *library)
 	  const char *const libpath = dladdr_to_soname (td_init);
 
 	  if (libpath != NULL)
-	    fprintf (stderr, "Host %s resolved to: %s.\n",
+	    fprintf (server_output, "Host %s resolved to: %s.\n",
 		     library, libpath);
 	}
     }
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 3ce9580..f3639be 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -63,6 +63,8 @@ 
 
 #ifdef IN_PROCESS_AGENT
 
+#define server_output stderr
+
 static void trace_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 static void
@@ -73,7 +75,7 @@  trace_vdebug (const char *fmt, ...)
 
   va_start (ap, fmt);
   vsprintf (buf, fmt, ap);
-  fprintf (stderr, PROG "/tracepoint: %s\n", buf);
+  fprintf (server_output, PROG "/tracepoint: %s\n", buf);
   va_end (ap);
 }
 
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
index e89a862..d11f101 100644
--- a/gdb/gdbserver/utils.c
+++ b/gdb/gdbserver/utils.c
@@ -21,6 +21,7 @@ 
 #ifdef IN_PROCESS_AGENT
 #  define PREFIX "ipa: "
 #  define TOOLNAME "GDBserver in-process agent"
+#  define server_output stderr
 #else
 #  define PREFIX "gdbserver: "
 #  define TOOLNAME "GDBserver"
@@ -31,7 +32,7 @@ 
 void
 malloc_failure (long size)
 {
-  fprintf (stderr,
+  fprintf (server_output,
 	   PREFIX "ran out of memory while trying to allocate %lu bytes\n",
 	   (unsigned long) size);
   exit (1);
@@ -78,8 +79,8 @@  verror (const char *string, va_list args)
 {
 #ifdef IN_PROCESS_AGENT
   fflush (stdout);
-  vfprintf (stderr, string, args);
-  fprintf (stderr, "\n");
+  vfprintf (server_output, string, args);
+  fprintf (server_output, "\n");
   exit (1);
 #else
   throw_verror (GENERIC_ERROR, string, args);
@@ -89,9 +90,9 @@  verror (const char *string, va_list args)
 void
 vwarning (const char *string, va_list args)
 {
-  fprintf (stderr, PREFIX);
-  vfprintf (stderr, string, args);
-  fprintf (stderr, "\n");
+  fprintf (server_output, PREFIX);
+  vfprintf (server_output, string, args);
+  fprintf (server_output, "\n");
 }
 
 /* Report a problem internal to GDBserver, and exit.  */
@@ -99,10 +100,10 @@  vwarning (const char *string, va_list args)
 void
 internal_verror (const char *file, int line, const char *fmt, va_list args)
 {
-  fprintf (stderr,  "\
+  fprintf (server_output,  "\
 %s:%d: A problem internal to " TOOLNAME " has been detected.\n", file, line);
-  vfprintf (stderr, fmt, args);
-  fprintf (stderr, "\n");
+  vfprintf (server_output, fmt, args);
+  fprintf (server_output, "\n");
   exit (1);
 }
 
@@ -111,10 +112,10 @@  internal_verror (const char *file, int line, const char *fmt, va_list args)
 void
 internal_vwarning (const char *file, int line, const char *fmt, va_list args)
 {
-  fprintf (stderr,  "\
+  fprintf (server_output,  "\
 %s:%d: A problem internal to " TOOLNAME " has been detected.\n", file, line);
-  vfprintf (stderr, fmt, args);
-  fprintf (stderr, "\n");
+  vfprintf (server_output, fmt, args);
+  fprintf (server_output, "\n");
 }
 
 /* Convert a CORE_ADDR into a HEX string, like %lx.
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index 6c86765..80e3a97 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -39,15 +39,15 @@ 
 #include <sys/cygwin.h>
 #endif
 
-#define OUTMSG(X) do { printf X; fflush (stderr); } while (0)
+#define OUTMSG(X) do { fprintf (server_output, X); fflush (server_output); } while (0)
 
 #define OUTMSG2(X) \
   do						\
     {						\
       if (debug_threads)			\
 	{					\
-	  printf X;				\
-	  fflush (stderr);			\
+	  fprintf (server_output, X);		\
+	  fflush (server_output);		\
 	}					\
     } while (0)
 
diff --git a/gdb/gdbserver/wincecompat.c b/gdb/gdbserver/wincecompat.c
index 269015b..7dff15f 100644
--- a/gdb/gdbserver/wincecompat.c
+++ b/gdb/gdbserver/wincecompat.c
@@ -24,9 +24,9 @@  void
 perror (const char *s)
 {
   if (s && *s)
-    fprintf (stderr, "%s: %s\n", s, strwinerror (GetLastError ()));
+    fprintf (server_output, "%s: %s\n", s, strwinerror (GetLastError ()));
   else
-    fprintf (stderr, "%s\n", strwinerror (GetLastError ()));
+    fprintf (server_output, "%s\n", strwinerror (GetLastError ()));
 }
 
 void