public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 4/6] gdbserver: Delimit debugging output for readability
@ 2013-12-17 21:47 Doug Evans
  2013-12-18 11:17 ` Pedro Alves
  0 siblings, 1 reply; 26+ messages in thread
From: Doug Evans @ 2013-12-17 21:47 UTC (permalink / raw)
  To: gdb-patches

Hi.

This patch adds some delimiters to the output of the major pieces
I found use for, namely linux_resume/wait, and stop/unstop_all_lwps.
These are important steps in the control of the inferior, and can
produce a lot of output: It's helpful to be able to identify
when these steps begin and when they end.

2013-12-17  Doug Evans  <dje@google.com>

	* linux-low.c (linux_wait_1): Surround debugging printf output with
	"====".  Ensure all exit paths have debugging printfs for result.
	(linux_wait): Delete debugging printf, duplicates one in linux_wait_1.
	(linux_resume): Surround debugging printf output with "====".
	(stop_all_lwps): Surround debugging printf output with "----".
	(unstop_all_lwps): Ditto.

---
 gdb/gdbserver/linux-low.c | 66 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 58 insertions(+), 8 deletions(-)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 3883e50..61744a3 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -16,6 +16,18 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+/* Notes:
+   Debugging printf output is delimited to make it easier to read.
+   There's a lot of it (which is good), but without the delimiters it's
+   hard to see where the entry and exit points are.  High level routines
+   that are useful enough to mark this way are delimited with "====".
+   Lower level routines that are useful enough to mark this way are
+   delimited with "----".
+   We could also use indentation, but that's adds more complexity.
+   Using ==== vs ---- vs nothing works well in practice.
+   Functions are free to use indentation internally, but there is no
+   convention yet for this.  */
+
 #include "server.h"
 #include "linux-low.h"
 #include "linux-osdata.h"
@@ -2268,6 +2278,10 @@ linux_wait_1 (ptid_t ptid,
   int trace_event;
   int in_step_range;
 
+  /* Debugging output is delimited with ==== to make it easier to read.  */
+  if (debug_threads)
+    fprintf (stderr, "====\nlinux_wait_1: [%s]\n", target_pid_to_str (ptid));
+
   /* Translate generic target options into linux options.  */
   options = __WALL;
   if (target_options & TARGET_WNOHANG)
@@ -2318,7 +2332,11 @@ retry:
     }
 
   if (pid == 0) /* only if TARGET_WNOHANG */
-    return null_ptid;
+    {
+      if (debug_threads)
+	fprintf (stderr, "linux_wait_1 ret = null_ptid\n====\n");
+      return null_ptid;
+    }
 
   event_child = get_thread_lwp (current_inferior);
 
@@ -2345,7 +2363,9 @@ retry:
 
 	      if (debug_threads)
 		fprintf (stderr,
-			 "\nChild exited with retcode = %x \n",
+			 "linux_wait_1 ret = %s, exited with retcode %d\n"
+			 "====\n",
+			 target_pid_to_str (ptid_of (event_child)),
 			 WEXITSTATUS (w));
 	    }
 	  else
@@ -2355,9 +2375,10 @@ retry:
 
 	      if (debug_threads)
 		fprintf (stderr,
-			 "\nChild terminated with signal = %x \n",
+			 "linux_wait_1 ret = %s, terminated with signal %d\n"
+			 "====\n",
+			 target_pid_to_str (ptid_of (event_child)),
 			 WTERMSIG (w));
-
 	    }
 
 	  return ptid_of (event_child);
@@ -2524,6 +2545,13 @@ Check if we're already there.\n",
 		{
 		  ourstatus->kind = TARGET_WAITKIND_STOPPED;
 		  ourstatus->value.sig = GDB_SIGNAL_0;
+
+		  if (debug_threads)
+		    fprintf (stderr,
+			     "linux_wait_1 ret = %s, stopped "
+			     "while stabilizing threads\n====\n",
+			     target_pid_to_str (ptid_of (event_child)));
+
 		  return ptid_of (event_child);
 		}
 	    }
@@ -2733,7 +2761,7 @@ Check if we're already there.\n",
   gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait ret = %s, %d, %d\n",
+    fprintf (stderr, "linux_wait_1 ret = %s, %d, %d\n====\n",
 	     target_pid_to_str (ptid_of (event_child)),
 	     ourstatus->kind,
 	     ourstatus->value.sig);
@@ -2775,9 +2803,6 @@ linux_wait (ptid_t ptid,
 {
   ptid_t event_ptid;
 
-  if (debug_threads)
-    fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
-
   /* Flush the async file first.  */
   if (target_is_async_p ())
     async_file_flush ();
@@ -3079,6 +3104,13 @@ stop_all_lwps (int suspend, struct lwp_info *except)
   /* Should not be called recursively.  */
   gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
 
+  if (debug_threads)
+    {
+      fprintf (stderr, "----\nstop_all_lwps (%s, except=%s)\n",
+	       suspend ? "stop-and-suspend" : "stop",
+	       except != NULL ? target_pid_to_str (ptid_of (except)) : "none");
+    }
+
   stopping_threads = (suspend
 		      ? STOPPING_AND_SUSPENDING_THREADS
 		      : STOPPING_THREADS);
@@ -3089,6 +3121,13 @@ stop_all_lwps (int suspend, struct lwp_info *except)
     find_inferior (&all_lwps, send_sigstop_callback, except);
   for_each_inferior (&all_lwps, wait_for_sigstop);
   stopping_threads = NOT_STOPPING_THREADS;
+
+  if (debug_threads)
+    {
+      fprintf (stderr,
+	       "stop_all_lwps done, setting stopping_threads "
+	       "back to !stopping\n----\n");
+    }
 }
 
 /* Resume execution of the inferior process.
@@ -3792,6 +3831,10 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   int any_pending;
   int leave_all_stopped;
 
+  /* Debugging output is delimited with ==== to make it easier to read.  */
+  if (debug_threads)
+    fprintf (stderr, "====\nlinux_resume:\n");
+
   find_inferior (&all_threads, linux_set_resume_request, &array);
 
   /* If there is a thread which would otherwise be resumed, which has
@@ -3835,6 +3878,9 @@ linux_resume (struct thread_resume *resume_info, size_t n)
 
   if (need_step_over)
     start_step_over (need_step_over);
+
+  if (debug_threads)
+    fprintf (stderr, "linux_resume done\n====\n");
 }
 
 /* This function is called once per thread.  We check the thread's
@@ -3984,6 +4030,7 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
 {
   if (debug_threads)
     {
+      fprintf (stderr, "----\n");
       if (except)
 	fprintf (stderr,
 		 "unstopping all lwps, except=(LWP %ld)\n", lwpid_of (except));
@@ -3996,6 +4043,9 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
     find_inferior (&all_lwps, unsuspend_and_proceed_one_lwp, except);
   else
     find_inferior (&all_lwps, proceed_one_lwp, except);
+
+  if (debug_threads)
+    fprintf (stderr, "unstop_all_lwps done\n----\n");
 }
 
 
-- 
1.8.5.1

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2013-12-17 21:47 [PATCH 4/6] gdbserver: Delimit debugging output for readability Doug Evans
@ 2013-12-18 11:17 ` Pedro Alves
  2014-01-15  0:47   ` Doug Evans
  0 siblings, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2013-12-18 11:17 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

On 12/17/2013 09:47 PM, Doug Evans wrote:
> +   We could also use indentation, but that's adds more complexity.

"but that adds"

Looks good to me, though I think it'd be better to write it as:

linux_wait_1 ()
...
/* Debugging output is delimited to make it easier to read.  */
#define DELIMITER "====\n"
  if (debug_threads)
    fprintf (stderr, DELIMITER "linux_wait_1: [%s]\n", target_pid_to_str (ptid));
  ...
  ...
  if (debug_threads)
    fprintf (stderr, "linux_wait_1 ret = null_ptid\n" DELIMITER);

#undef DELIMITER
}

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2013-12-18 11:17 ` Pedro Alves
@ 2014-01-15  0:47   ` Doug Evans
  2014-01-16 17:22     ` Pedro Alves
  2014-01-16 18:39     ` [PATCH 4/6] gdbserver: Delimit debugging output for readability Yao Qi
  0 siblings, 2 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-15  0:47 UTC (permalink / raw)
  To: Pedro Alves, yao; +Cc: gdb-patches

Pedro Alves writes:
 > On 12/17/2013 09:47 PM, Doug Evans wrote:
 > > +   We could also use indentation, but that's adds more complexity.
 > 
 > "but that adds"
 > 
 > Looks good to me, though I think it'd be better to write it as:
 > 
 > linux_wait_1 ()
 > ...
 > /* Debugging output is delimited to make it easier to read.  */
 > #define DELIMITER "====\n"
 >   if (debug_threads)
 >     fprintf (stderr, DELIMITER "linux_wait_1: [%s]\n", target_pid_to_str (ptid));
 >   ...
 >   ...
 >   if (debug_threads)
 >     fprintf (stderr, "linux_wait_1 ret = null_ptid\n" DELIMITER);
 > 
 > #undef DELIMITER
 > }

Hi.
While going through the reviews, I found myself wanting something more,
namely timestamps (like "set debug timestamp on" in gdb).

This patch adds a check for gettimeofday and doesn't fall back to using one
in libiberty or gnulib, leaving that for another day.

It also adds macro FUNCTION_NAME, based on the implementation in gdb_assert.h.
A subsequent patch will use this when replacing abbreviations with
function names.

Unlike gdb, I didn't add an option to enable timestamps, you get them
automagically with --debug.  I can do that if people want.

I had a version of this patch that used indentation to represent
the heirarchy of debug_level_{enter,exit}.  I left the basic support
in thinking it might be useful.  I can either remove it or add the indentation,
but I found myself not really wanting the indentation.

2014-01-13  Doug Evans  <dje@google.com>

	* configure.ac (AC_CHECK_FUNCS): Add test for gettimeofday.
	* configure: Regenerate.
	* config.in: Regenerate.
	* linux-aarch64-low.c (*): Update all debugging printfs to use
	debug_printf instead of fprintf.
	* linux-arm-low.c (*): Ditto.
	* linux-cris-low.c (*): Ditto.
	* linux-crisv32-low.c (*): Ditto.
	* linux-m32r-low.c (*): Ditto.
	* linux-low.c (*): Ditto.
	* linux-sparc-low.c (*): Ditto.
	* linux-x86-low.c (*): Ditto.
	(linux_wait_1): Add calls to debug_level_enter, debug_level_exit.
	(linux_wait): Remove redundant debugging printf.
	(stop_all_lwps): Add calls to debug_level_enter, debug_level_exit.
	(linux_resume, unstop_all_lwps): Ditto.
	* mem-break.c (*): Update all debugging printfs to use
	debug_printf instead of fprintf.
	* remote-utils.c (*): Ditto.
	* thread-db.c (*): Ditto.
	* server.c (*): Ditto.
	(start_inferior): Replace call to fflush with call to debug_flush.
	(main): Add calls to debug_level_reset.
	* tracepoint.c (trace_debug_1 [!IN_PROCESS_AGENT]): Add version of
	trace_debug_1 that uses debug_printf.
	(tracepoint_look_up_symbols): Update all debugging printfs to use
	debug_printf instead of fprintf.
	* utils.c: #include <sys/time.h>.
	(debug_nesting_level): New static global.
	(debug_printf, debug_flush): New functions.
	(debug_level_reset, debug_level_incr): New functions.
	* utils.h (FUNCTION_NAME): New macro.
	(debug_printf, debug_flush): Declare.
	(debug_level_reset, debug_level_incr): Declare.
	(debug_level_enter, debug_level_exit): New macros.

diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index e33cdea..1b9751f 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -66,6 +66,9 @@
 /* Define to 1 if you have the `getrlimit' function. */
 #undef HAVE_GETRLIMIT
 
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index fac7fb3..6d8a6a7 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4728,7 +4728,7 @@ fi
 
 done
 
-for ac_func in pread pwrite pread64 readlink
+for ac_func in gettimeofday pread pwrite pread64 readlink
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index dc8131c..0dfa4a9 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -82,7 +82,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 errno.h fcntl.h signal.h sys/file.h malloc.h dnl
 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
 		 netinet/tcp.h arpa/inet.h)
-AC_CHECK_FUNCS(pread pwrite pread64 readlink)
+AC_CHECK_FUNCS(gettimeofday pread pwrite pread64 readlink)
 AC_REPLACE_FUNCS(vasprintf vsnprintf)
 
 GDB_AC_COMMON
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index 1b0da6c..e7d3e4f 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -323,7 +323,7 @@ aarch64_get_pc (struct regcache *regcache)
 
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index da5085c..fb6ff68 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -256,7 +256,7 @@ arm_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-cris-low.c b/gdb/gdbserver/linux-cris-low.c
index d229d43..2abd987 100644
--- a/gdb/gdbserver/linux-cris-low.c
+++ b/gdb/gdbserver/linux-cris-low.c
@@ -67,7 +67,7 @@ cris_get_pc (struct regcache *regcache, void)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-crisv32-low.c b/gdb/gdbserver/linux-crisv32-low.c
index e4ebb62..a16a656 100644
--- a/gdb/gdbserver/linux-crisv32-low.c
+++ b/gdb/gdbserver/linux-crisv32-low.c
@@ -63,7 +63,7 @@ cris_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 2bc619a..6ab0966 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -475,7 +475,7 @@ get_pc (struct lwp_info *lwp)
   pc = (*the_low_target.get_pc) (regcache);
 
   if (debug_threads)
-    fprintf (stderr, "pc is 0x%lx\n", (long) pc);
+    debug_printf ("pc is 0x%lx\n", (long) pc);
 
   current_inferior = saved_inferior;
   return pc;
@@ -520,7 +520,7 @@ get_stop_pc (struct lwp_info *lwp)
     stop_pc -= the_low_target.decr_pc_after_break;
 
   if (debug_threads)
-    fprintf (stderr, "stop pc is 0x%lx\n", (long) stop_pc);
+    debug_printf ("stop pc is 0x%lx\n", (long) stop_pc);
 
   return stop_pc;
 }
@@ -692,8 +692,7 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
   if (linux_proc_pid_is_stopped (lwpid))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Attached to a stopped process\n");
+	debug_printf ("Attached to a stopped process\n");
 
       /* The process is definitely stopped.  It is in a job control
 	 stop, unless the kernel predates the TASK_STOPPED /
@@ -824,8 +823,8 @@ linux_attach (unsigned long pid)
 		      new_threads_found++;
 
 		      if (debug_threads)
-			fprintf (stderr, "\
-Found and attached to new lwp %ld\n", lwp);
+			debug_printf ("Found and attached to new lwp %ld\n",
+				      lwp);
 		    }
 		}
 
@@ -898,18 +897,16 @@ linux_kill_one_lwp (struct lwp_info *lwp)
   errno = 0;
   kill (pid, SIGKILL);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 
   errno = 0;
   ptrace (PTRACE_KILL, pid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 }
 
 /* Callback for `find_inferior'.  Kills an lwp of a given process,
@@ -934,8 +931,8 @@ kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
   if (lwpid_of (lwp) == pid)
     {
       if (debug_threads)
-	fprintf (stderr, "lkop: is last of process %s\n",
-		 target_pid_to_str (entry->id));
+	debug_printf ("lkop: is last of process %s\n",
+		      target_pid_to_str (entry->id));
       return 0;
     }
 
@@ -975,14 +972,14 @@ linux_kill (int pid)
   if (lwp == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: cannot find lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: cannot find lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: killing lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: killing lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
 
       do
 	{
@@ -1031,9 +1028,8 @@ get_detach_signal (struct thread_info *thread)
   if (!WIFSTOPPED (status))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s hasn't stopped: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s hasn't stopped: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1041,10 +1037,9 @@ get_detach_signal (struct thread_info *thread)
   if (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had stopped with extended "
-		 "status: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s had stopped with extended "
+		      "status: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1053,10 +1048,9 @@ get_detach_signal (struct thread_info *thread)
   if (program_signals_p && !program_signals[signo])
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, but it is in nopass state\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else if (!program_signals_p
@@ -1066,20 +1060,19 @@ get_detach_signal (struct thread_info *thread)
 	   && (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, "
-		 "but we don't know if we should pass it.  Default to not.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, "
+		      "but we don't know if we should pass it. "
+		      "Default to not.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s has pending signal %s: delivering it.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s has pending signal %s: delivering it.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
 
       return WSTOPSIG (status);
     }
@@ -1100,9 +1093,8 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Sending SIGCONT to %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("Sending SIGCONT to %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       kill_lwp (lwpid_of (lwp), SIGCONT);
       lwp->stop_expected = 0;
@@ -1276,7 +1268,7 @@ linux_wait_for_lwp (ptid_t ptid, int *wstatp, int options)
   struct lwp_info *child = NULL;
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
+    debug_printf ("linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
 
   if (ptid_equal (ptid, minus_one_ptid))
     to_wait_for = -1;			/* any child */
@@ -1297,7 +1289,7 @@ retry:
       && (!WIFSTOPPED (*wstatp)
 	  || (WSTOPSIG (*wstatp) != 32
 	      && WSTOPSIG (*wstatp) != 33)))
-    fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp);
+    debug_printf ("Got an event from %d (%x)\n", ret, *wstatp);
 
   child = find_lwp_pid (pid_to_ptid (ret));
 
@@ -1404,7 +1396,7 @@ retry:
       current_inferior = get_lwp_thread (child);
       regcache = get_thread_regcache (current_inferior, 1);
       pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
+      debug_printf ("linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
       current_inferior = saved_inferior;
     }
 
@@ -1450,7 +1442,7 @@ handle_tracepoints (struct lwp_info *lwp)
   if (tpoint_related_event)
     {
       if (debug_threads)
-	fprintf (stderr, "got a tracepoint event\n");
+	debug_printf ("got a tracepoint event\n");
       return 1;
     }
 
@@ -1501,9 +1493,9 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
       int r;
 
       if (debug_threads)
-	fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Checking whether LWP %ld needs to move out of the "
+		      "jump pad.\n",
+		      lwpid_of (lwp));
 
       r = linux_fast_tracepoint_collecting (lwp, &status);
 
@@ -1527,9 +1519,9 @@ Checking whether LWP %ld needs to move out of the jump pad.\n",
 		}
 
 	      if (debug_threads)
-		fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...it does\n",
-		 lwpid_of (lwp));
+		debug_printf ("Checking whether LWP %ld needs to move out of "
+			      "the jump pad...it does\n",
+			      lwpid_of (lwp));
 	      current_inferior = saved_inferior;
 
 	      return 1;
@@ -1582,9 +1574,8 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
 	  if (lwp->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Cancelling fast exit-jump-pad: removing bkpt. "
-			 "stopping all threads momentarily.\n");
+		debug_printf ("Cancelling fast exit-jump-pad: removing bkpt. "
+			      "stopping all threads momentarily.\n");
 
 	      stop_all_lwps (1, lwp);
 	      cancel_breakpoints ();
@@ -1600,9 +1591,9 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
     }
 
   if (debug_threads)
-    fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...no\n",
-	     lwpid_of (lwp));
+    debug_printf ("Checking whether LWP %ld needs to move out of the "
+		  "jump pad...no\n",
+		  lwpid_of (lwp));
 
   current_inferior = saved_inferior;
   return 0;
@@ -1617,8 +1608,8 @@ enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
   struct pending_signals *p_sig;
 
   if (debug_threads)
-    fprintf (stderr, "\
-Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
+    debug_printf ("Deferring signal %d for LWP %ld.\n",
+		  WSTOPSIG (*wstat), lwpid_of (lwp));
 
   if (debug_threads)
     {
@@ -1627,11 +1618,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
       for (sig = lwp->pending_signals_to_report;
 	   sig != NULL;
 	   sig = sig->prev)
-	fprintf (stderr,
-		 "   Already queued %d\n",
-		 sig->signal);
+	debug_printf ("   Already queued %d\n",
+		      sig->signal);
 
-      fprintf (stderr, "   (no more currently queued signals)\n");
+      debug_printf ("   (no more currently queued signals)\n");
     }
 
   /* Don't enqueue non-RT signals if they are already in the deferred
@@ -1648,11 +1638,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
 	  if (sig->signal == WSTOPSIG (*wstat))
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Not requeuing already queued non-RT signal %d"
-			 " for LWP %ld\n",
-			 sig->signal,
-			 lwpid_of (lwp));
+		debug_printf ("Not requeuing already queued non-RT signal %d"
+			      " for LWP %ld\n",
+			      sig->signal,
+			      lwpid_of (lwp));
 	      return;
 	    }
 	}
@@ -1690,8 +1679,8 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
       *p_sig = NULL;
 
       if (debug_threads)
-	fprintf (stderr, "Reporting deferred signal %d for LWP %ld.\n",
-		 WSTOPSIG (*wstat), lwpid_of (lwp));
+	debug_printf ("Reporting deferred signal %d for LWP %ld.\n",
+		      WSTOPSIG (*wstat), lwpid_of (lwp));
 
       if (debug_threads)
 	{
@@ -1700,11 +1689,10 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 	  for (sig = lwp->pending_signals_to_report;
 	       sig != NULL;
 	       sig = sig->prev)
-	    fprintf (stderr,
-		     "   Still queued %d\n",
-		     sig->signal);
+	    debug_printf ("   Still queued %d\n",
+			  sig->signal);
 
-	  fprintf (stderr, "   (no more queued signals)\n");
+	  debug_printf ("   (no more queued signals)\n");
 	}
 
       return 1;
@@ -1734,9 +1722,8 @@ cancel_breakpoint (struct lwp_info *lwp)
   if ((*the_low_target.breakpoint_at) (lwp->stop_pc))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: Push back breakpoint for %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: Push back breakpoint for %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       /* Back up the PC if necessary.  */
       if (the_low_target.decr_pc_after_break)
@@ -1752,10 +1739,9 @@ cancel_breakpoint (struct lwp_info *lwp)
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: No breakpoint found at %s for [%s]\n",
-		 paddress (lwp->stop_pc),
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: No breakpoint found at %s for [%s]\n",
+		      paddress (lwp->stop_pc),
+		      target_pid_to_str (ptid_of (lwp)));
     }
 
   current_inferior = saved_inferior;
@@ -1788,7 +1774,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       event_child = (struct lwp_info *)
 	find_inferior (&all_lwps, status_pending_p_callback, &ptid);
       if (debug_threads && event_child)
-	fprintf (stderr, "Got a pending child %ld\n", lwpid_of (event_child));
+	debug_printf ("Got a pending child %ld\n", lwpid_of (event_child));
     }
   else
     {
@@ -1816,8 +1802,8 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
   if (event_child != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
-		 lwpid_of (event_child), event_child->status_pending);
+	debug_printf ("Got an event from pending child %ld (%04x)\n",
+		      lwpid_of (event_child), event_child->status_pending);
       *wstat = event_child->status_pending;
       event_child->status_pending_p = 0;
       event_child->status_pending = 0;
@@ -1847,7 +1833,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if ((options & WNOHANG) && event_child == NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "WNOHANG set, no event found\n");
+	    debug_printf ("WNOHANG set, no event found\n");
 	  return 0;
 	}
 
@@ -1873,14 +1859,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if (! WIFSTOPPED (*wstat))
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld exiting\n", lwpid_of (event_child));
+	    debug_printf ("LWP %ld exiting\n", lwpid_of (event_child));
 
 	  /* If the last thread is exiting, just return.  */
 	  if (last_thread_of_process_p (current_inferior))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "LWP %ld is last lwp of process\n",
-			 lwpid_of (event_child));
+		debug_printf ("LWP %ld is last lwp of process\n",
+			      lwpid_of (event_child));
 	      return lwpid_of (event_child);
 	    }
 
@@ -1888,14 +1874,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	    {
 	      current_inferior = (struct thread_info *) all_threads.head;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now %ld\n",
-			 lwpid_of (get_thread_lwp (current_inferior)));
+		debug_printf ("Current inferior is now %ld\n",
+			      lwpid_of (get_thread_lwp (current_inferior)));
 	    }
 	  else
 	    {
 	      current_inferior = NULL;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now <NULL>\n");
+		debug_printf ("Current inferior is now <NULL>\n");
 	    }
 
 	  /* If we were waiting for this particular child to do something...
@@ -1938,7 +1924,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	  int should_stop;
 
 	  if (debug_threads)
-	    fprintf (stderr, "Expected stop.\n");
+	    debug_printf ("Expected stop.\n");
 	  event_child->stop_expected = 0;
 
 	  should_stop = (current_inferior->last_resume_kind == resume_stop
@@ -2082,9 +2068,8 @@ select_event_lwp (struct lwp_info **orig_lp)
   if (event_lp != NULL)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "SEL: Select single-step %s\n",
-		 target_pid_to_str (ptid_of (event_lp)));
+	debug_printf ("SEL: Select single-step %s\n",
+		      target_pid_to_str (ptid_of (event_lp)));
     }
   else
     {
@@ -2099,9 +2084,8 @@ select_event_lwp (struct lwp_info **orig_lp)
 	((num_events * (double) rand ()) / (RAND_MAX + 1.0));
 
       if (debug_threads && num_events > 1)
-	fprintf (stderr,
-		 "SEL: Found %d SIGTRAP events, selecting #%d\n",
-		 num_events, random_selector);
+	debug_printf ("SEL: Found %d SIGTRAP events, selecting #%d\n",
+		      num_events, random_selector);
 
       event_lp = (struct lwp_info *) find_inferior (&all_lwps,
 						    select_event_lwp_callback,
@@ -2191,8 +2175,8 @@ linux_stabilize_threads (void)
   if (lwp_stuck != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "can't stabilize, LWP %ld is stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("can't stabilize, LWP %ld is stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
       return;
     }
 
@@ -2243,8 +2227,8 @@ linux_stabilize_threads (void)
 	= (struct lwp_info *) find_inferior (&all_lwps,
 					 stuck_in_jump_pad_callback, NULL);
       if (lwp_stuck != NULL)
-	fprintf (stderr, "couldn't stabilize, LWP %ld got stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
     }
 }
 
@@ -2265,6 +2249,12 @@ linux_wait_1 (ptid_t ptid,
   int trace_event;
   int in_step_range;
 
+  if (debug_threads)
+    {
+      debug_level_enter ();
+      debug_printf ("linux_wait_1: [%s]\n", target_pid_to_str (ptid));
+    }
+
   /* Translate generic target options into linux options.  */
   options = __WALL;
   if (target_options & TARGET_WNOHANG)
@@ -2309,13 +2299,20 @@ retry:
   else
     {
       if (debug_threads)
-	fprintf (stderr, "step_over_bkpt set [%s], doing a blocking wait\n",
-		 target_pid_to_str (step_over_bkpt));
+	debug_printf ("step_over_bkpt set [%s], doing a blocking wait\n",
+		      target_pid_to_str (step_over_bkpt));
       pid = linux_wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
     }
 
   if (pid == 0) /* only if TARGET_WNOHANG */
-    return null_ptid;
+    {
+      if (debug_threads)
+	{
+	  debug_printf ("linux_wait_1 ret = null_ptid\n");
+	  debug_level_exit ();
+	}
+      return null_ptid;
+    }
 
   event_child = get_thread_lwp (current_inferior);
 
@@ -2341,9 +2338,13 @@ retry:
 	      ourstatus->value.integer = WEXITSTATUS (w);
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild exited with retcode = %x \n",
-			 WEXITSTATUS (w));
+		{
+		  debug_printf ("linux_wait_1 ret = %s, exited with "
+				"retcode %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WEXITSTATUS (w));
+		  debug_level_exit ();
+		}
 	    }
 	  else
 	    {
@@ -2351,10 +2352,13 @@ retry:
 	      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild terminated with signal = %x \n",
-			 WTERMSIG (w));
-
+		{
+		  debug_printf ("linux_wait_1 ret = %s, terminated with "
+				"signal %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WTERMSIG (w));
+		  debug_level_exit ();
+		}
 	    }
 
 	  return ptid_of (event_child);
@@ -2409,7 +2413,7 @@ retry:
 	     already handled it.  So next time we resume (from this
 	     PC), we should step over it.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 
 	  if (breakpoint_here (event_child->stop_pc))
 	    event_child->need_step_over = 1;
@@ -2435,10 +2439,9 @@ retry:
       && agent_loaded_p ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Got signal %d for LWP %ld.  Check if we need "
-		 "to defer or adjust it.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Got signal %d for LWP %ld.  Check if we need "
+		      "to defer or adjust it.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       /* Allow debugging the jump pad itself.  */
       if (current_inferior->last_resume_kind != resume_step
@@ -2447,9 +2450,8 @@ retry:
 	  enqueue_one_deferred_signal (event_child, &w);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred (in jump pad)\n",
-		     WSTOPSIG (w), lwpid_of (event_child));
+	    debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n",
+			  WSTOPSIG (w), lwpid_of (event_child));
 
 	  linux_resume_one_lwp (event_child, 0, 0, NULL);
 	  goto retry;
@@ -2459,11 +2461,10 @@ retry:
   if (event_child->collecting_fast_tracepoint)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-LWP %ld was trying to move out of the jump pad (%d).  \
-Check if we're already there.\n",
-		 lwpid_of (event_child),
-		 event_child->collecting_fast_tracepoint);
+	debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
+		      "Check if we're already there.\n",
+		      lwpid_of (event_child),
+		      event_child->collecting_fast_tracepoint);
 
       trace_event = 1;
 
@@ -2476,9 +2477,8 @@ Check if we're already there.\n",
 	  if (event_child->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "No longer need exit-jump-pad bkpt; removing it."
-			 "stopping all threads momentarily.\n");
+		debug_printf ("No longer need exit-jump-pad bkpt; removing it."
+			      "stopping all threads momentarily.\n");
 
 	      /* Other running threads could hit this breakpoint.
 		 We don't handle moribund locations like GDB does,
@@ -2502,25 +2502,33 @@ Check if we're already there.\n",
       if (event_child->collecting_fast_tracepoint == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "fast tracepoint finished "
-		     "collecting successfully.\n");
+	    debug_printf ("fast tracepoint finished "
+			  "collecting successfully.\n");
 
 	  /* We may have a deferred signal to report.  */
 	  if (dequeue_one_deferred_signal (event_child, &w))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "dequeued one signal.\n");
+		debug_printf ("dequeued one signal.\n");
 	    }
 	  else
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "no deferred signals.\n");
+		debug_printf ("no deferred signals.\n");
 
 	      if (stabilizing_threads)
 		{
 		  ourstatus->kind = TARGET_WAITKIND_STOPPED;
 		  ourstatus->value.sig = GDB_SIGNAL_0;
+
+		  if (debug_threads)
+		    {
+		      debug_printf ("linux_wait_1 ret = %s, stopped "
+				    "while stabilizing threads\n",
+				    target_pid_to_str (ptid_of (event_child)));
+		      debug_level_exit ();
+		    }
+
 		  return ptid_of (event_child);
 		}
 	    }
@@ -2554,8 +2562,8 @@ Check if we're already there.\n",
       siginfo_t info, *info_p;
 
       if (debug_threads)
-	fprintf (stderr, "Ignored signal %d for LWP %ld.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Ignored signal %d for LWP %ld.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       if (ptrace (PTRACE_GETSIGINFO, lwpid_of (event_child),
 		  (PTRACE_TYPE_ARG3) 0, &info) == 0)
@@ -2600,16 +2608,16 @@ Check if we're already there.\n",
       if (debug_threads)
 	{
 	  if (bp_explains_trap)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 	  if (step_over_finished)
-	    fprintf (stderr, "Step-over finished.\n");
+	    debug_printf ("Step-over finished.\n");
 	  if (trace_event)
-	    fprintf (stderr, "Tracepoint event.\n");
+	    debug_printf ("Tracepoint event.\n");
 	  if (lwp_in_step_range (event_child))
-	    fprintf (stderr, "Range stepping pc 0x%s [0x%s, 0x%s).\n",
-		     paddress (event_child->stop_pc),
-		     paddress (event_child->step_range_start),
-		     paddress (event_child->step_range_end));
+	    debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).\n",
+			  paddress (event_child->stop_pc),
+			  paddress (event_child->step_range_start),
+			  paddress (event_child->step_range_end));
 	}
 
       /* We're not reporting this breakpoint to GDB, so apply the
@@ -2629,7 +2637,7 @@ Check if we're already there.\n",
 	 going to keep waiting, so use proceed, which handles stepping
 	 over the next breakpoint.  */
       if (debug_threads)
-	fprintf (stderr, "proceeding all threads.\n");
+	debug_printf ("proceeding all threads.\n");
 
       if (step_over_finished)
 	unsuspend_all_lwps (event_child);
@@ -2643,16 +2651,16 @@ Check if we're already there.\n",
       if (current_inferior->last_resume_kind == resume_step)
 	{
 	  if (event_child->step_range_start == event_child->step_range_end)
-	    fprintf (stderr, "GDB wanted to single-step, reporting event.\n");
+	    debug_printf ("GDB wanted to single-step, reporting event.\n");
 	  else if (!lwp_in_step_range (event_child))
-	    fprintf (stderr, "Out of step range, reporting event.\n");
+	    debug_printf ("Out of step range, reporting event.\n");
 	}
       if (event_child->stopped_by_watchpoint)
-	fprintf (stderr, "Stopped by watchpoint.\n");
+	debug_printf ("Stopped by watchpoint.\n");
       if (gdb_breakpoint_here (event_child->stop_pc))
-	fprintf (stderr, "Stopped by GDB breakpoint.\n");
+	debug_printf ("Stopped by GDB breakpoint.\n");
       if (debug_threads)
-	fprintf (stderr, "Hit a non-gdbserver trap event.\n");
+	debug_printf ("Hit a non-gdbserver trap event.\n");
     }
 
   /* Alright, we're going to report a stop.  */
@@ -2730,10 +2738,12 @@ Check if we're already there.\n",
   gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait ret = %s, %d, %d\n",
-	     target_pid_to_str (ptid_of (event_child)),
-	     ourstatus->kind,
-	     ourstatus->value.sig);
+    {
+      debug_printf ("linux_wait_1 ret = %s, %d, %d\n",
+		    target_pid_to_str (ptid_of (event_child)),
+		    ourstatus->kind, ourstatus->value.sig);
+      debug_level_exit ();
+    }
 
   return ptid_of (event_child);
 }
@@ -2772,9 +2782,6 @@ linux_wait (ptid_t ptid,
 {
   ptid_t event_ptid;
 
-  if (debug_threads)
-    fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
-
   /* Flush the async file first.  */
   if (target_is_async_p ())
     async_file_flush ();
@@ -2837,13 +2844,13 @@ send_sigstop (struct lwp_info *lwp)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr, "Have pending sigstop for lwp %d\n", pid);
+	debug_printf ("Have pending sigstop for lwp %d\n", pid);
 
       return;
     }
 
   if (debug_threads)
-    fprintf (stderr, "Sending sigstop to lwp %d\n", pid);
+    debug_printf ("Sending sigstop to lwp %d\n", pid);
 
   lwp->stop_expected = 1;
   kill_lwp (pid, SIGSTOP);
@@ -2912,8 +2919,8 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "wait_for_sigstop: LWP %ld already stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("wait_for_sigstop: LWP %ld already stopped\n",
+		      lwpid_of (lwp));
       return;
     }
 
@@ -2926,7 +2933,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   ptid = lwp->head.id;
 
   if (debug_threads)
-    fprintf (stderr, "wait_for_sigstop: pulling one event\n");
+    debug_printf ("wait_for_sigstop: pulling one event\n");
 
   pid = linux_wait_for_event (ptid, &wstat, __WALL);
 
@@ -2936,14 +2943,14 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (WIFSTOPPED (wstat))
     {
       if (debug_threads)
-	fprintf (stderr, "LWP %ld stopped with signal %d\n",
-		 lwpid_of (lwp), WSTOPSIG (wstat));
+	debug_printf ("LWP %ld stopped with signal %d\n",
+		      lwpid_of (lwp), WSTOPSIG (wstat));
 
       if (WSTOPSIG (wstat) != SIGSTOP)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n",
-		     lwpid_of (lwp), wstat);
+	    debug_printf ("LWP %ld stopped with non-sigstop status %06x\n",
+			  lwpid_of (lwp), wstat);
 
 	  lwp->status_pending_p = 1;
 	  lwp->status_pending = wstat;
@@ -2952,7 +2959,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Process %d exited while stopping LWPs\n", pid);
+	debug_printf ("Process %d exited while stopping LWPs\n", pid);
 
       lwp = find_lwp_pid (pid_to_ptid (pid));
       if (lwp)
@@ -2973,7 +2980,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Previously current thread died.\n");
+	debug_printf ("Previously current thread died.\n");
 
       if (non_stop)
 	{
@@ -3032,9 +3039,8 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
       && maybe_move_out_of_jump_pad (lwp, wstat))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "LWP %ld needs stabilizing (in jump pad)\n",
-		 lwpid_of (lwp));
+	debug_printf ("LWP %ld needs stabilizing (in jump pad)\n",
+		      lwpid_of (lwp));
 
       if (wstat)
 	{
@@ -3042,10 +3048,9 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
 	  enqueue_one_deferred_signal (lwp, wstat);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred "
-		     "(in jump pad)\n",
-		     WSTOPSIG (*wstat), lwpid_of (lwp));
+	    debug_printf ("Signal %d for LWP %ld deferred "
+			  "(in jump pad)\n",
+			  WSTOPSIG (*wstat), lwpid_of (lwp));
 	}
 
       linux_resume_one_lwp (lwp, 0, 0, NULL);
@@ -3076,6 +3081,16 @@ stop_all_lwps (int suspend, struct lwp_info *except)
   /* Should not be called recursively.  */
   gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
 
+  if (debug_threads)
+    {
+      debug_level_enter ();
+      debug_printf ("stop_all_lwps (%s, except=%s)\n",
+		    suspend ? "stop-and-suspend" : "stop",
+		    except != NULL
+		    ? target_pid_to_str (ptid_of (except))
+		    : "none");
+    }
+
   stopping_threads = (suspend
 		      ? STOPPING_AND_SUSPENDING_THREADS
 		      : STOPPING_THREADS);
@@ -3086,6 +3101,13 @@ stop_all_lwps (int suspend, struct lwp_info *except)
     find_inferior (&all_lwps, send_sigstop_callback, except);
   for_each_inferior (&all_lwps, wait_for_sigstop);
   stopping_threads = NOT_STOPPING_THREADS;
+
+  if (debug_threads)
+    {
+      debug_printf ("stop_all_lwps done, setting stopping_threads "
+		    "back to !stopping\n");
+      debug_level_exit ();
+    }
 }
 
 /* Resume execution of the inferior process.
@@ -3138,10 +3160,10 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "Not resuming lwp %ld (%s, signal %d, stop %s);"
-		 " has pending status\n",
-		 lwpid_of (lwp), step ? "step" : "continue", signal,
-		 lwp->stop_expected ? "expected" : "not expected");
+	debug_printf ("Not resuming lwp %ld (%s, signal %d, stop %s);"
+		      " has pending status\n",
+		      lwpid_of (lwp), step ? "step" : "continue", signal,
+		      lwp->stop_expected ? "expected" : "not expected");
       return;
     }
 
@@ -3149,9 +3171,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   current_inferior = get_lwp_thread (lwp);
 
   if (debug_threads)
-    fprintf (stderr, "Resuming lwp %ld (%s, signal %d, stop %s)\n",
-	     lwpid_of (lwp), step ? "step" : "continue", signal,
-	     lwp->stop_expected ? "expected" : "not expected");
+    debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)\n",
+		  lwpid_of (lwp), step ? "step" : "continue", signal,
+		  lwp->stop_expected ? "expected" : "not expected");
 
   /* This bit needs some thinking about.  If we get a signal that
      we must report while a single-step reinsert is still pending,
@@ -3166,8 +3188,8 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "  pending reinsert at 0x%s\n",
-		 paddress (lwp->bp_reinsert));
+	debug_printf ("  pending reinsert at 0x%s\n",
+		      paddress (lwp->bp_reinsert));
 
       if (can_hardware_single_step ())
 	{
@@ -3190,9 +3212,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (fast_tp_collecting == 1)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " (exit-jump-pad-bkpt)\n",
+		      lwpid_of (lwp));
 
       /* Postpone any pending signal.  It was enqueued above.  */
       signal = 0;
@@ -3200,9 +3222,9 @@ lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
   else if (fast_tp_collecting == 2)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " single-stepping\n",
+		      lwpid_of (lwp));
 
       if (can_hardware_single_step ())
 	step = 1;
@@ -3226,9 +3248,8 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
       && can_hardware_single_step ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "lwp %ld has a while-stepping action -> forcing step.\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld has a while-stepping action -> forcing step.\n",
+		      lwpid_of (lwp));
       step = 1;
     }
 
@@ -3236,7 +3257,7 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
     {
       struct regcache *regcache = get_thread_regcache (current_inferior, 1);
       CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "  resuming from pc 0x%lx\n", (long) pc);
+      debug_printf ("  resuming from pc 0x%lx\n", (long) pc);
     }
 
   /* If we have pending signals, consume one unless we are trying to
@@ -3334,11 +3355,12 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      && thread->last_resume_kind == resume_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "already %s LWP %ld at GDB's request\n",
-			 thread->last_status.kind == TARGET_WAITKIND_STOPPED
-			 ? "stopped"
-			 : "stopping",
-			 lwpid_of (lwp));
+		debug_printf ("already %s LWP %ld at GDB's request\n",
+			      (thread->last_status.kind
+			       == TARGET_WAITKIND_STOPPED)
+			      ? "stopped"
+			      : "stopping",
+			      lwpid_of (lwp));
 
 	      continue;
 	    }
@@ -3359,10 +3381,9 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      lwp->status_pending_p = 1;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Dequeueing deferred signal %d for LWP %ld, "
-			 "leaving status pending.\n",
-			 WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
+		debug_printf ("Dequeueing deferred signal %d for LWP %ld, "
+			      "leaving status pending.\n",
+			      WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
 	    }
 
 	  return 0;
@@ -3413,9 +3434,8 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, not stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3424,9 +3444,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (thread->last_resume_kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, should remain stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, should remain"
+		      " stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3435,25 +3455,23 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, suspended\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, suspended\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (!lwp->need_step_over)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? No\n", lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? No\n", lwpid_of (lwp));
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, has pending status.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
+		      " status.\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3469,10 +3487,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (pc != lwp->stop_pc)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Cancelling, PC was changed.  "
-		 "Old stop_pc was 0x%s, PC is now 0x%s\n",
-		 lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
+	debug_printf ("Need step over [LWP %ld]? Cancelling, PC was changed. "
+		      "Old stop_pc was 0x%s, PC is now 0x%s\n",
+		      lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
 
       lwp->need_step_over = 0;
       return 0;
@@ -3492,10 +3509,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
 	  && gdb_no_commands_at_breakpoint (pc))
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, but found"
-		     " GDB breakpoint at 0x%s; skipping step over\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, but found"
+			  " GDB breakpoint at 0x%s; skipping step over\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  current_inferior = saved_inferior;
 	  return 0;
@@ -3503,10 +3519,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, "
-		     "found breakpoint at 0x%s\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, "
+			  "found breakpoint at 0x%s\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  /* We've found an lwp that needs stepping over --- return 1 so
 	     that find_inferior stops looking.  */
@@ -3521,9 +3536,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   current_inferior = saved_inferior;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Need step over [LWP %ld]? No, no breakpoint found at 0x%s\n",
-	     lwpid_of (lwp), paddress (pc));
+    debug_printf ("Need step over [LWP %ld]? No, no breakpoint found"
+		  " at 0x%s\n",
+		  lwpid_of (lwp), paddress (pc));
 
   return 0;
 }
@@ -3554,15 +3569,14 @@ start_step_over (struct lwp_info *lwp)
   int step;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Starting step-over on LWP %ld.  Stopping all threads\n",
-	     lwpid_of (lwp));
+    debug_printf ("Starting step-over on LWP %ld.  Stopping all threads\n",
+		  lwpid_of (lwp));
 
   stop_all_lwps (1, lwp);
   gdb_assert (lwp->suspended == 0);
 
   if (debug_threads)
-    fprintf (stderr, "Done stopping all threads for step-over.\n");
+    debug_printf ("Done stopping all threads for step-over.\n");
 
   /* Note, we should always reach here with an already adjusted PC,
      either by GDB (if we're resuming due to GDB's request), or by our
@@ -3607,7 +3621,7 @@ finish_step_over (struct lwp_info *lwp)
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "Finished step over.\n");
+	debug_printf ("Finished step over.\n");
 
       /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
 	 may be no breakpoint to reinsert there by now.  */
@@ -3662,12 +3676,12 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (lwp->resume->kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr, "resume_stop request for LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resume_stop request for LWP %ld\n", lwpid_of (lwp));
 
       if (!lwp->stopped)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "stopping LWP %ld\n", lwpid_of (lwp));
+	    debug_printf ("stopping LWP %ld\n", lwpid_of (lwp));
 
 	  /* Stop the thread, and wait for the event asynchronously,
 	     through the event loop.  */
@@ -3676,8 +3690,8 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "already stopped LWP %ld\n",
-		     lwpid_of (lwp));
+	    debug_printf ("already stopped LWP %ld\n",
+			  lwpid_of (lwp));
 
 	  /* The LWP may have been stopped in an internal event that
 	     was not meant to be notified back to GDB (e.g., gdbserver
@@ -3719,7 +3733,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (!leave_pending)
     {
       if (debug_threads)
-	fprintf (stderr, "resuming LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resuming LWP %ld\n", lwpid_of (lwp));
 
       step = (lwp->resume->kind == resume_step);
       linux_resume_one_lwp (lwp, step, lwp->resume->sig, NULL);
@@ -3727,7 +3741,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "leaving LWP %ld stopped\n", lwpid_of (lwp));
+	debug_printf ("leaving LWP %ld stopped\n", lwpid_of (lwp));
 
       /* If we have a new signal, enqueue the signal.  */
       if (lwp->resume->sig != 0)
@@ -3764,6 +3778,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   int any_pending;
   int leave_all_stopped;
 
+  if (debug_threads)
+    {
+      debug_level_enter ();
+      debug_printf ("linux_resume:\n");
+    }
+
   find_inferior (&all_threads, linux_set_resume_request, &array);
 
   /* If there is a thread which would otherwise be resumed, which has
@@ -3792,13 +3812,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   if (debug_threads)
     {
       if (need_step_over != NULL)
-	fprintf (stderr, "Not resuming all, need step over\n");
+	debug_printf ("Not resuming all, need step over\n");
       else if (any_pending)
-	fprintf (stderr,
-		 "Not resuming, all-stop and found "
-		 "an LWP with pending status\n");
+	debug_printf ("Not resuming, all-stop and found "
+		      "an LWP with pending status\n");
       else
-	fprintf (stderr, "Resuming, no pending status or step over needed\n");
+	debug_printf ("Resuming, no pending status or step over needed\n");
     }
 
   /* Even if we're leaving threads stopped, queue all signals we'd
@@ -3807,6 +3826,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
 
   if (need_step_over)
     start_step_over (need_step_over);
+
+  if (debug_threads)
+    {
+      debug_printf ("linux_resume done\n");
+      debug_level_exit ();
+    }
 }
 
 /* This function is called once per thread.  We check the thread's
@@ -3829,13 +3854,12 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
+    debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
 
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld already running\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld already running\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3845,16 +3869,16 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
       && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
     {
       if (debug_threads)
-	fprintf (stderr, "   client wants LWP to remain %ld stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   client wants LWP to remain %ld stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld has pending status, leaving stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   LWP %ld has pending status, leaving stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3863,7 +3887,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld is suspended\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld is suspended\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3882,10 +3906,9 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
 	 pending, this is a no-op.  */
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Client wants LWP %ld to stop. "
-		 "Making sure it has a SIGSTOP pending\n",
-		 lwpid_of (lwp));
+	debug_printf ("Client wants LWP %ld to stop. "
+		      "Making sure it has a SIGSTOP pending\n",
+		      lwpid_of (lwp));
 
       send_sigstop (lwp);
     }
@@ -3932,9 +3955,9 @@ proceed_all_lwps (void)
       if (need_step_over != NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "proceed_all_lwps: found "
-		     "thread %ld needing a step-over\n",
-		     lwpid_of (need_step_over));
+	    debug_printf ("proceed_all_lwps: found "
+			  "thread %ld needing a step-over\n",
+			  lwpid_of (need_step_over));
 
 	  start_step_over (need_step_over);
 	  return;
@@ -3942,7 +3965,7 @@ proceed_all_lwps (void)
     }
 
   if (debug_threads)
-    fprintf (stderr, "Proceeding, no step-over needed\n");
+    debug_printf ("Proceeding, no step-over needed\n");
 
   find_inferior (&all_lwps, proceed_one_lwp, NULL);
 }
@@ -3956,18 +3979,24 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
 {
   if (debug_threads)
     {
+      debug_level_enter ();
       if (except)
-	fprintf (stderr,
-		 "unstopping all lwps, except=(LWP %ld)\n", lwpid_of (except));
+	debug_printf ("unstopping all lwps, except=(LWP %ld)\n",
+		      lwpid_of (except));
       else
-	fprintf (stderr,
-		 "unstopping all lwps\n");
+	debug_printf ("unstopping all lwps\n");
     }
 
   if (unsuspend)
     find_inferior (&all_lwps, unsuspend_and_proceed_one_lwp, except);
   else
     find_inferior (&all_lwps, proceed_one_lwp, except);
+
+  if (debug_threads)
+    {
+      debug_printf ("unstop_all_lwps done\n");
+      debug_level_exit ();
+    }
 }
 
 
@@ -4533,8 +4562,8 @@ linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 	val = val & 0xffff;
       else if (len == 3)
 	val = val & 0xffffff;
-      fprintf (stderr, "Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
-	       val, (long)memaddr);
+      debug_printf ("Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
+		    val, (long)memaddr);
     }
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
@@ -4777,9 +4806,9 @@ linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
   pid = lwpid_of (get_thread_lwp (current_inferior));
 
   if (debug_threads)
-    fprintf (stderr, "%s siginfo for lwp %d.\n",
-	     readbuf != NULL ? "Reading" : "Writing",
-	     pid);
+    debug_printf ("%s siginfo for lwp %d.\n",
+		  readbuf != NULL ? "Reading" : "Writing",
+		  pid);
 
   if (offset >= sizeof (siginfo))
     return -1;
@@ -4851,8 +4880,8 @@ linux_async (int enable)
   int previous = (linux_event_pipe[0] != -1);
 
   if (debug_threads)
-    fprintf (stderr, "linux_async (%d), previous=%d\n",
-	     enable, previous);
+    debug_printf ("linux_async (%d), previous=%d\n",
+		  enable, previous);
 
   if (previous != enable)
     {
diff --git a/gdb/gdbserver/linux-m32r-low.c b/gdb/gdbserver/linux-m32r-low.c
index e208523..477e185 100644
--- a/gdb/gdbserver/linux-m32r-low.c
+++ b/gdb/gdbserver/linux-m32r-low.c
@@ -59,7 +59,7 @@ m32r_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-sparc-low.c b/gdb/gdbserver/linux-sparc-low.c
index fcffe05..75c97dd 100644
--- a/gdb/gdbserver/linux-sparc-low.c
+++ b/gdb/gdbserver/linux-sparc-low.c
@@ -231,7 +231,7 @@ sparc_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 04fa3c9..b141c2b 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -2022,8 +2022,8 @@ add_insns (unsigned char *start, int len)
   CORE_ADDR buildaddr = current_insn_ptr;
 
   if (debug_threads)
-    fprintf (stderr, "Adding %d bytes of insn at %s\n",
-	     len, paddress (buildaddr));
+    debug_printf ("Adding %d bytes of insn at %s\n",
+		  len, paddress (buildaddr));
 
   append_insns (&buildaddr, len, start);
   current_insn_ptr = buildaddr;
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index fd706e9..b77ce10 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -197,10 +197,9 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -211,9 +210,8 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -334,10 +332,9 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert fast tracepoint jump "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert fast tracepoint jump "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -398,10 +395,9 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " fast tracepoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " fast tracepoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (jp);
       return NULL;
     }
@@ -424,9 +420,8 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert fast tracepoint jump at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
 
       /* Unlink it.  */
       proc->fast_tracepoint_jumps = jp->next;
@@ -450,10 +445,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -480,9 +474,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
 	  jp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert fast tracepoint jump at 0x%s (%s).\n",
-		     paddress (pc), strerror (err));
+	    debug_printf ("Failed to uninsert fast tracepoint jump at"
+			  " 0x%s (%s).\n",
+			  paddress (pc), strerror (err));
 	}
     }
 }
@@ -500,10 +494,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       /* This can happen when we remove breakpoints when a tracepoint
 	 hit causes a tracing stop, while handling a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (where));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (where));
       return;
     }
 
@@ -528,9 +521,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       jp->inserted = 0;
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to reinsert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to reinsert fast tracepoint jump at"
+		      " 0x%s (%s).\n",
+		      paddress (where), strerror (err));
     }
 }
 
@@ -598,10 +591,9 @@ delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert raw breakpoint "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert raw breakpoint "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -932,9 +924,9 @@ gdb_no_commands_at_breakpoint (CORE_ADDR where)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr, "at 0x%s, bp command_list is 0x%s\n",
-	     paddress (where),
-	     phex_nz ((uintptr_t) bp->command_list, 0));
+    debug_printf ("at 0x%s, bp command_list is 0x%s\n",
+		  paddress (where),
+		  phex_nz ((uintptr_t) bp->command_list, 0));
   return (bp->command_list == NULL);
 }
 
@@ -1034,9 +1026,8 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
 	  bp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
-		     paddress (bp->pc), strerror (err));
+	    debug_printf ("Failed to uninsert raw breakpoint at 0x%s (%s).\n",
+			  paddress (bp->pc), strerror (err));
 	}
     }
 }
@@ -1052,10 +1043,9 @@ uninsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find breakpoint at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find breakpoint at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -1087,9 +1077,8 @@ reinsert_raw_breakpoint (struct raw_breakpoint *bp)
   if (err == 0)
     bp->inserted = 1;
   else if (debug_threads)
-    fprintf (stderr,
-	     "Failed to reinsert breakpoint at 0x%s (%s).\n",
-	     paddress (bp->pc), strerror (err));
+    debug_printf ("Failed to reinsert breakpoint at 0x%s (%s).\n",
+		  paddress (bp->pc), strerror (err));
 }
 
 void
@@ -1103,10 +1092,9 @@ reinsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find raw breakpoint at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find raw breakpoint at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (pc));
       return;
     }
 
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 75ace6e..3b88995 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -161,7 +161,7 @@ handle_accept_event (int err, gdb_client_data client_data)
   socklen_t tmp;
 
   if (debug_threads)
-    fprintf (stderr, "handling possible accept event\n");
+    debug_printf ("handling possible accept event\n");
 
   tmp = sizeof (sockaddr);
   remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
@@ -1315,8 +1315,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
 		      struct target_waitstatus *status)
 {
   if (debug_threads)
-    fprintf (stderr, "Writing resume reply for %s:%d\n",
-	     target_pid_to_str (ptid), status->kind);
+    debug_printf ("Writing resume reply for %s:%d\n",
+		  target_pid_to_str (ptid), status->kind);
 
   switch (status->kind)
     {
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index c9d9eec..da8161c 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -222,8 +222,8 @@ start_inferior (char **argv)
     {
       int i;
       for (i = 0; new_argv[i]; ++i)
-	fprintf (stderr, "new_argv[%d] = \"%s\"\n", i, new_argv[i]);
-      fflush (stderr);
+	debug_printf ("new_argv[%d] = \"%s\"\n", i, new_argv[i]);
+      debug_flush ();
     }
 
 #ifdef SIGTTOU
@@ -2528,10 +2528,9 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
 	      char *status_string
 		= target_waitstatus_to_string (&thread->last_status);
 
-	      fprintf (stderr,
-		       "Reporting thread %s as already stopped with %s\n",
-		       target_pid_to_str (entry->id),
-		       status_string);
+	      debug_printf ("Reporting thread %s as already stopped with %s\n",
+			    target_pid_to_str (entry->id),
+			    status_string);
 
 	      xfree (status_string);
 	    }
@@ -3064,6 +3063,8 @@ main (int argc, char *argv[])
 
   if (setjmp (toplevel))
     {
+      debug_level_reset ();
+
       /* If something fails and longjmps while detaching or killing
 	 inferiors, we'd end up here again, stuck in an infinite loop
 	 trap.  Be sure that if that happens, we exit immediately
@@ -3106,6 +3107,8 @@ main (int argc, char *argv[])
 	    }
 	}
 
+      debug_level_reset ();
+
       /* Wait for events.  This will return when all event sources are
 	 removed from the event loop.  */
       start_event_loop ();
@@ -3197,14 +3200,14 @@ process_point_options (CORE_ADDR point_addr, char **packet)
 	{
 	  /* Conditional expression.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint condition.\n");
+	    debug_printf ("Found breakpoint condition.\n");
 	  add_breakpoint_condition (point_addr, &dataptr);
 	}
       else if (strncmp (dataptr, "cmds:", strlen ("cmds:")) == 0)
 	{
 	  dataptr += strlen ("cmds:");
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint commands %s.\n", dataptr);
+	    debug_printf ("Found breakpoint commands %s.\n", dataptr);
 	  persist = (*dataptr == '1');
 	  dataptr += 2;
 	  add_breakpoint_commands (point_addr, &dataptr, persist);
@@ -3309,7 +3312,7 @@ process_serial_event (void)
 	  if (!non_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "Forcing non-stop mode\n");
+		debug_printf ("Forcing non-stop mode\n");
 
 	      non_stop = 1;
 	      start_non_stop (1);
@@ -3702,7 +3705,7 @@ int
 handle_serial_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible serial event\n");
+    debug_printf ("handling possible serial event\n");
 
   /* Really handle it.  */
   if (process_serial_event () < 0)
@@ -3721,7 +3724,7 @@ int
 handle_target_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible target event\n");
+    debug_printf ("handling possible target event\n");
 
   last_ptid = mywait (minus_one_ptid, &last_status,
 		      TARGET_WNOHANG, 1);
@@ -3763,10 +3766,10 @@ handle_target_event (int err, gdb_client_data client_data)
 	      struct thread_resume resume_info;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "GDB not connected; forwarding event %d for [%s]\n",
-			 (int) last_status.kind,
-			 target_pid_to_str (last_ptid));
+		debug_printf ("GDB not connected; forwarding event %d for"
+			      " [%s]\n",
+			      (int) last_status.kind,
+			      target_pid_to_str (last_ptid));
 
 	      resume_info.thread = last_ptid;
 	      resume_info.kind = resume_continue;
@@ -3774,9 +3777,9 @@ handle_target_event (int err, gdb_client_data client_data)
 	      (*the_target->resume) (&resume_info, 1);
 	    }
 	  else if (debug_threads)
-	    fprintf (stderr, "GDB not connected; ignoring event %d for [%s]\n",
-		     (int) last_status.kind,
-		     target_pid_to_str (last_ptid));
+	    debug_printf ("GDB not connected; ignoring event %d for [%s]\n",
+			  (int) last_status.kind,
+			  target_pid_to_str (last_ptid));
 	}
       else
 	{
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 8b8f6ce..df06b9d 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -194,7 +194,7 @@ thread_db_create_event (CORE_ADDR where)
     fatal ("unexpected thread_db->td_ta_event_getmsg_p == NULL");
 
   if (debug_threads)
-    fprintf (stderr, "Thread creation event.\n");
+    debug_printf ("Thread creation event.\n");
 
   /* FIXME: This assumes we don't get another event.
      In the LinuxThreads implementation, this is safe,
@@ -289,8 +289,8 @@ find_one_thread (ptid_t ptid)
 	   lwpid, thread_db_err_str (err));
 
   if (debug_threads)
-    fprintf (stderr, "Found thread %ld (LWP %d)\n",
-	     ti.ti_tid, ti.ti_lid);
+    debug_printf ("Found thread %ld (LWP %d)\n",
+		  ti.ti_tid, ti.ti_lid);
 
   if (lwpid != ti.ti_lid)
     {
@@ -326,8 +326,8 @@ attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
   struct lwp_info *lwp;
 
   if (debug_threads)
-    fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
-	     ti_p->ti_tid, ti_p->ti_lid);
+    debug_printf ("Attaching to thread %ld (LWP %d)\n",
+		  ti_p->ti_tid, ti_p->ti_lid);
   linux_attach_lwp (ti_p->ti_lid);
   lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
   if (lwp == NULL)
@@ -432,8 +432,8 @@ thread_db_find_new_threads (void)
 					 TD_THR_LOWEST_PRIORITY,
 					 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
       if (debug_threads)
-	fprintf (stderr, "Found %d threads in iteration %d.\n",
-		 new_thread_count, iteration);
+	debug_printf ("Found %d threads in iteration %d.\n",
+		      new_thread_count, iteration);
 
       if (new_thread_count != 0)
 	{
@@ -546,7 +546,7 @@ thread_db_load_search (void)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -595,7 +595,7 @@ try_thread_db_load_1 (void *handle)
       if ((a) == NULL)						\
 	{							\
 	  if (debug_threads)					\
-	    fprintf (stderr, "dlsym: %s\n", dlerror ());	\
+	    debug_printf ("dlsym: %s\n", dlerror ());		\
 	  if (required)						\
 	    {							\
 	      free (tdb);					\
@@ -613,7 +613,7 @@ try_thread_db_load_1 (void *handle)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -663,13 +663,13 @@ try_thread_db_load (const char *library)
   void *handle;
 
   if (debug_threads)
-    fprintf (stderr, "Trying host libthread_db library: %s.\n",
-	     library);
+    debug_printf ("Trying host libthread_db library: %s.\n",
+		  library);
   handle = dlopen (library, RTLD_NOW);
   if (handle == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "dlopen failed: %s.\n", dlerror ());
+	debug_printf ("dlopen failed: %s.\n", dlerror ());
       return 0;
     }
 
@@ -786,7 +786,7 @@ thread_db_load_search (void)
 
   free_char_ptr_vec (dir_vec);
   if (debug_threads)
-    fprintf (stderr, "thread_db_load_search returning %d\n", rc);
+    debug_printf ("thread_db_load_search returning %d\n", rc);
   return rc;
 }
 
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 13b3ff6..3706577 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -61,6 +61,8 @@
 
 */
 
+#ifdef IN_PROCESS_AGENT
+
 static void trace_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 static void
@@ -81,6 +83,19 @@ trace_vdebug (const char *fmt, ...)
       trace_vdebug ((fmt), ##args);		\
   } while (0)
 
+#else
+
+#define trace_debug_1(level, fmt, args...)	\
+  do {						\
+    if (level <= debug_threads)			\
+      {						\
+	debug_printf ((fmt), ##args);		\
+	debug_printf ("\n");			\
+      }						\
+  } while (0)
+
+#endif
+
 #define trace_debug(FMT, args...)		\
   trace_debug_1 (1, FMT, ##args)
 
@@ -338,7 +353,7 @@ tracepoint_look_up_symbols (void)
       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name);
+	    debug_printf ("symbol `%s' not found\n", symbol_list[i].name);
 	  return;
 	}
     }
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
index eff4499..1ce5512 100644
--- a/gdb/gdbserver/utils.c
+++ b/gdb/gdbserver/utils.c
@@ -17,6 +17,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "server.h"
+#include <sys/time.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -32,6 +33,11 @@
 #  define TOOLNAME "GDBserver"
 #endif
 
+/* The current debug printf call nesting level.
+   This is used to add some heirarchy to the debug logging messages
+   and make them easier to read.  */
+static int debug_nesting_level = 0;
+
 /* Generally useful subroutines used throughout the program.  */
 
 void
@@ -165,6 +171,89 @@ internal_error (const char *file, int line, const char *fmt, ...)
   exit (1);
 }
 
+/* Print a debugging message.
+   If the text begins a new line it is preceded by a timestamp, if the
+   system has gettimeofday.
+   We don't get fancy with newline checking, we just check whether the
+   previous call ended with "\n".  */
+
+void
+debug_printf (const char *msg, ...)
+{
+  va_list args;
+#ifdef HAVE_GETTIMEOFDAY
+  static int new_line = 1;
+
+  if (new_line)
+    {
+      struct timeval tm;
+
+      gettimeofday (&tm, NULL);
+      fprintf (stderr, "%ld:%06ld ", (long) tm.tv_sec, (long) tm.tv_usec);
+    }
+#endif
+
+  va_start (args, msg);
+  vfprintf (stderr, msg, args);
+  va_end (args);
+
+#ifdef HAVE_GETTIMEOFDAY
+  if (*msg)
+    new_line = msg[strlen (msg) - 1] == '\n';
+#endif
+}
+
+/* Flush debugging output.
+   This is called, for example, when starting an inferior to ensure all debug
+   output thus far appears before any inferior output.  */
+
+void
+debug_flush (void)
+{
+  fflush (stderr);
+}
+
+/* Reset the debug printf call nesting level.
+   This is called from the top level error (setjmp) handler.  */
+
+void
+debug_level_reset (void)
+{
+  debug_nesting_level = 0;
+}
+
+/* Increase or decrease the debug printf call nesting level.
+   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
+   Call this when entering major routines that can trigger a lot of debug
+   output before it exits.  It allows the reader to associate subsequent
+   debug output to the call that ultimately triggered it.  */
+
+void
+debug_level_incr (int incr, const char *function_name)
+{
+  gdb_assert (incr == 1 || incr == -1);
+
+  /* Increment(/decrement) the level by one before printing the function name,
+     to distinguish this as an entry(/exit) point.
+     Then increment(/decrement) it again so that debugging printfs within
+     the function are recognized as such.  */
+  if (function_name != NULL)
+    {
+      debug_nesting_level += incr;
+      debug_printf ("%s %s\n",
+		    incr > 0 ? ">>>>entering" : "<<<<exiting",
+		    function_name);
+    }
+  debug_nesting_level += incr;
+
+  /* Don't crash on mismatched enter/exit, but still inform the user.  */
+  if (debug_nesting_level < 0)
+    {
+      debug_printf ("ERROR: mismatch in debug_level_enter/exit, level < 0\n");
+      debug_nesting_level = 0;
+    }
+}
+
 /* Temporary storage using circular buffer.  */
 #define NUMCELLS 10
 #define CELLSIZE 50
diff --git a/gdb/gdbserver/utils.h b/gdb/gdbserver/utils.h
index 6d3df71..6c781c0 100644
--- a/gdb/gdbserver/utils.h
+++ b/gdb/gdbserver/utils.h
@@ -19,10 +19,44 @@
 #ifndef UTILS_H
 #define UTILS_H
 
+/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
+   which contains the name of the function currently being defined.
+   This is broken in G++ before version 2.6.
+   C9x has a similar variable called __func__, but prefer the GCC one since
+   it demangles C++ function names.  */
+#if (GCC_VERSION >= 2004)
+#define FUNCTION_NAME __PRETTY_FUNCTION__
+#else
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#define FUNCTION_NAME __func__
+#endif
+#endif
+
 void perror_with_name (const char *string);
 void error (const char *string,...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
 void fatal (const char *string,...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
 void warning (const char *string,...) ATTRIBUTE_PRINTF (1, 2);
+
+void debug_printf (const char *msg, ...) ATTRIBUTE_PRINTF (1, 2);
+void debug_flush (void);
+void debug_level_reset (void);
+void debug_level_incr (int incr, const char *function_name);
+
+/* These macros are for use in major functions that produce a lot of
+   debugging output.  They help identify in the mass of debugging output
+   when these functions enter and exit.  */
+#ifdef FUNCTION_NAME
+#define debug_level_enter() \
+  do { debug_level_incr (1, FUNCTION_NAME); } while (0)
+#define debug_level_exit() \
+  do { debug_level_incr (-1, FUNCTION_NAME); } while (0)
+#else
+#define debug_level_enter() \
+  do { debug_level_incr (1, NULL); } while (0)
+#define debug_level_exit() \
+  do { debug_level_incr (-1, NULL); } while (0)
+#endif
+
 char *paddress (CORE_ADDR addr);
 char *pulongest (ULONGEST u);
 char *plongest (LONGEST l);

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-15  0:47   ` Doug Evans
@ 2014-01-16 17:22     ` Pedro Alves
  2014-01-16 18:43       ` Doug Evans
  2014-01-16 18:39     ` [PATCH 4/6] gdbserver: Delimit debugging output for readability Yao Qi
  1 sibling, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2014-01-16 17:22 UTC (permalink / raw)
  To: Doug Evans; +Cc: yao, gdb-patches

On 01/15/2014 12:47 AM, Doug Evans wrote:

> Hi.
> While going through the reviews, I found myself wanting something more,
> namely timestamps (like "set debug timestamp on" in gdb).
> 
> This patch adds a check for gettimeofday and doesn't fall back to using one
> in libiberty or gnulib, leaving that for another day.
> 
> It also adds macro FUNCTION_NAME, based on the implementation in gdb_assert.h.
> A subsequent patch will use this when replacing abbreviations with
> function names.
> 
> Unlike gdb, I didn't add an option to enable timestamps, you get them
> automagically with --debug.  I can do that if people want.

I'd like that.  I've had to diff logs (side by side in e.g., kdiff3)
more than once in the past to track tricky stuff, and timestamps
unfortunately make that impossible.

> I had a version of this patch that used indentation to represent
> the heirarchy of debug_level_{enter,exit}.  I left the basic support
> in thinking it might be useful.  I can either remove it or add the indentation,
> but I found myself not really wanting the indentation.

I don't have a strong opinion, as I didn't make use of this
yet, but I think I wouldn't want indentation.  (E.g., maybe printing
a level counter instead of indentation could be better.).

> diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
> index 13b3ff6..3706577 100644
> --- a/gdb/gdbserver/tracepoint.c
> +++ b/gdb/gdbserver/tracepoint.c
> @@ -61,6 +61,8 @@
>  
>  */
>  
> +#ifdef IN_PROCESS_AGENT
> +
>  static void trace_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
>  
>  static void
> @@ -81,6 +83,19 @@ trace_vdebug (const char *fmt, ...)
>        trace_vdebug ((fmt), ##args);		\
>    } while (0)
>  
> +#else
> +
> +#define trace_debug_1(level, fmt, args...)	\
> +  do {						\
> +    if (level <= debug_threads)			\
> +      {						\
> +	debug_printf ((fmt), ##args);		\
> +	debug_printf ("\n");			\
> +      }						\
> +  } while (0)
> +

Please write this in a way that preserves printing PROG
in gdbserver.  When debugging gdbserver and the IPA both
tracing at the same time (fast tracepoints and regular
tracepoints), it's confusing not to have there explicitly
who printed what, because both programs print the
same messages.

> +#endif
> +
>  #define trace_debug(FMT, args...)		\
>    trace_debug_1 (1, FMT, ##args)
>  
> @@ -338,7 +353,7 @@ tracepoint_look_up_symbols (void)
>        if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
>  	{
>  	  if (debug_threads)
> -	    fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name);
> +	    debug_printf ("symbol `%s' not found\n", symbol_list[i].name);
>  	  return;
>  	}
>      }
> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
> index eff4499..1ce5512 100644
> --- a/gdb/gdbserver/utils.c
> +++ b/gdb/gdbserver/utils.c

Could this new debug support code be put in a new file
instead?  E.g., gdbserver/debug.c ?

Otherwise this all looks good to me.

>  /* Temporary storage using circular buffer.  */
>  #define NUMCELLS 10
>  #define CELLSIZE 50
> diff --git a/gdb/gdbserver/utils.h b/gdb/gdbserver/utils.h
> index 6d3df71..6c781c0 100644
> --- a/gdb/gdbserver/utils.h
> +++ b/gdb/gdbserver/utils.h
> @@ -19,10 +19,44 @@
>  #ifndef UTILS_H
>  #define UTILS_H
>  
> +/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
> +   which contains the name of the function currently being defined.
> +   This is broken in G++ before version 2.6.
> +   C9x has a similar variable called __func__, but prefer the GCC one since
> +   it demangles C++ function names.  */
> +#if (GCC_VERSION >= 2004)
> +#define FUNCTION_NAME __PRETTY_FUNCTION__
> +#else
> +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
> +#define FUNCTION_NAME __func__
> +#endif
> +#endif

It'd be nice if this and gdb_assert.h's version of the same were
shared.  That is, e.g., put this in common/common-utils.h instead,
and make gdb_assert.h define ASSERT_FUNCTION as FUNCTION_NAME
(or eliminate ASSERT_FUNCTION entirely).  Are you planning on
doing it?

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-15  0:47   ` Doug Evans
  2014-01-16 17:22     ` Pedro Alves
@ 2014-01-16 18:39     ` Yao Qi
  2014-01-16 19:01       ` Doug Evans
  1 sibling, 1 reply; 26+ messages in thread
From: Yao Qi @ 2014-01-16 18:39 UTC (permalink / raw)
  To: Doug Evans; +Cc: Pedro Alves, gdb-patches

On 01/15/2014 08:47 AM, Doug Evans wrote:
> While going through the reviews, I found myself wanting something more,
> namely timestamps (like "set debug timestamp on" in gdb).
> 

Hi Doug,
Could you help me to understand how useful timestamps are for
measuring performance? or you use timestamps for other purposes?

> This patch adds a check for gettimeofday and doesn't fall back to using one
> in libiberty or gnulib, leaving that for another day.

gdbserver has used gnulib, which means we can use gettimeofday
unconditionally in gdbserver?

> diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
> index 1b0da6c..e7d3e4f 100644
> --- a/gdb/gdbserver/linux-aarch64-low.c
> +++ b/gdb/gdbserver/linux-aarch64-low.c
> @@ -323,7 +323,7 @@ aarch64_get_pc (struct regcache *regcache)
>  
>    collect_register_by_name (regcache, "pc", &pc);
>    if (debug_threads)
> -    fprintf (stderr, "stop pc is %08lx\n", pc);
> +    debug_printf ("stop pc is %08lx\n", pc);
>    return pc;

IWBN to move "if (debug_threads)" into debug_printf too.

> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
> index eff4499..1ce5512 100644
> --- a/gdb/gdbserver/utils.c
> +++ b/gdb/gdbserver/utils.c
> @@ -17,6 +17,7 @@

> +
> +/* Increase or decrease the debug printf call nesting level.
> +   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
> +   Call this when entering major routines that can trigger a lot of debug
> +   output before it exits.  It allows the reader to associate subsequent
> +   debug output to the call that ultimately triggered it.  */
> +
> +void
> +debug_level_incr (int incr, const char *function_name)
> +{
> +  gdb_assert (incr == 1 || incr == -1);
> +
> +  /* Increment(/decrement) the level by one before printing the function name,
> +     to distinguish this as an entry(/exit) point.
> +     Then increment(/decrement) it again so that debugging printfs within
> +     the function are recognized as such.  */
> +  if (function_name != NULL)
> +    {
> +      debug_nesting_level += incr;
> +      debug_printf ("%s %s\n",
> +		    incr > 0 ? ">>>>entering" : "<<<<exiting",
> +		    function_name);
> +    }
> +  debug_nesting_level += incr;
> +
> +  /* Don't crash on mismatched enter/exit, but still inform the user.  */
> +  if (debug_nesting_level < 0)
> +    {
> +      debug_printf ("ERROR: mismatch in debug_level_enter/exit, level < 0\n");
> +      debug_nesting_level = 0;
> +    }
> +}
> +

utils.c is compiled to both gdbserver and ipa.  IMO,
ipa code should be thread-safe, because it can be used by a
multi-threaded program.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 17:22     ` Pedro Alves
@ 2014-01-16 18:43       ` Doug Evans
  2014-01-16 18:54         ` Pedro Alves
  0 siblings, 1 reply; 26+ messages in thread
From: Doug Evans @ 2014-01-16 18:43 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Yao Qi, gdb-patches

On Thu, Jan 16, 2014 at 9:22 AM, Pedro Alves <palves@redhat.com> wrote:
>> diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
>> index 13b3ff6..3706577 100644
>> --- a/gdb/gdbserver/tracepoint.c
>> +++ b/gdb/gdbserver/tracepoint.c
>> @@ -61,6 +61,8 @@
>>
>>  */
>>
>> +#ifdef IN_PROCESS_AGENT
>> +
>>  static void trace_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
>>
>>  static void
>> @@ -81,6 +83,19 @@ trace_vdebug (const char *fmt, ...)
>>        trace_vdebug ((fmt), ##args);          \
>>    } while (0)
>>
>> +#else
>> +
>> +#define trace_debug_1(level, fmt, args...)   \
>> +  do {                                               \
>> +    if (level <= debug_threads)                      \
>> +      {                                              \
>> +     debug_printf ((fmt), ##args);           \
>> +     debug_printf ("\n");                    \
>> +      }                                              \
>> +  } while (0)
>> +
>
> Please write this in a way that preserves printing PROG
> in gdbserver.  When debugging gdbserver and the IPA both
> tracing at the same time (fast tracepoints and regular
> tracepoints), it's confusing not to have there explicitly
> who printed what, because both programs print the
> same messages.

A counter-proposal is that no information is lost given that if PROG
isn't present you know it's gdbserver, and it makes the debugging
output consistent with the rest of gdbserver.
Otherwise "Consistency Is Good" is going to make me want to prepend
PROG to all gdbserver output, which I don't have a problem with, but
thought I'd double check.

>
>> +#endif
>> +
>>  #define trace_debug(FMT, args...)            \
>>    trace_debug_1 (1, FMT, ##args)
>>
>> @@ -338,7 +353,7 @@ tracepoint_look_up_symbols (void)
>>        if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
>>       {
>>         if (debug_threads)
>> -         fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name);
>> +         debug_printf ("symbol `%s' not found\n", symbol_list[i].name);
>>         return;
>>       }
>>      }
>> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
>> index eff4499..1ce5512 100644
>> --- a/gdb/gdbserver/utils.c
>> +++ b/gdb/gdbserver/utils.c
>
> Could this new debug support code be put in a new file
> instead?  E.g., gdbserver/debug.c ?

It's a pretty-small file, and utils.c is kind of our collective
kitchen sink for such things.
I have no preference, just double checking that that's what you want.
For one, Consistency Is Good means I'd want to push for gdb/debug.c
(if/when there is something to put in there) and I want to make sure
everyone is ok with that - no reason why they wouldn't be, per se,
just checking.

> Otherwise this all looks good to me.

Thanks.

>>  /* Temporary storage using circular buffer.  */
>>  #define NUMCELLS 10
>>  #define CELLSIZE 50
>> diff --git a/gdb/gdbserver/utils.h b/gdb/gdbserver/utils.h
>> index 6d3df71..6c781c0 100644
>> --- a/gdb/gdbserver/utils.h
>> +++ b/gdb/gdbserver/utils.h
>> @@ -19,10 +19,44 @@
>>  #ifndef UTILS_H
>>  #define UTILS_H
>>
>> +/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
>> +   which contains the name of the function currently being defined.
>> +   This is broken in G++ before version 2.6.
>> +   C9x has a similar variable called __func__, but prefer the GCC one since
>> +   it demangles C++ function names.  */
>> +#if (GCC_VERSION >= 2004)
>> +#define FUNCTION_NAME __PRETTY_FUNCTION__
>> +#else
>> +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
>> +#define FUNCTION_NAME __func__
>> +#endif
>> +#endif
>
> It'd be nice if this and gdb_assert.h's version of the same were
> shared.  That is, e.g., put this in common/common-utils.h instead,
> and make gdb_assert.h define ASSERT_FUNCTION as FUNCTION_NAME
> (or eliminate ASSERT_FUNCTION entirely).  Are you planning on
> doing it?

Done in v2.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 18:43       ` Doug Evans
@ 2014-01-16 18:54         ` Pedro Alves
  2014-01-16 23:28           ` [PATCH 0/3] Add debug_printf and timestamps to gdbserver Doug Evans
  0 siblings, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2014-01-16 18:54 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, gdb-patches

On 01/16/2014 06:43 PM, Doug Evans wrote:
> On Thu, Jan 16, 2014 at 9:22 AM, Pedro Alves <palves@redhat.com> wrote:

> A counter-proposal is that no information is lost given that if PROG
> isn't present you know it's gdbserver, and it makes the debugging
> output consistent with the rest of gdbserver.
> Otherwise "Consistency Is Good" is going to make me want to prepend
> PROG to all gdbserver output, which I don't have a problem with, but
> thought I'd double check.

OK, I'll concede.  Let's try going without.

>>> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
>>> index eff4499..1ce5512 100644
>>> --- a/gdb/gdbserver/utils.c
>>> +++ b/gdb/gdbserver/utils.c
>>
>> Could this new debug support code be put in a new file
>> instead?  E.g., gdbserver/debug.c ?
> 
> It's a pretty-small file, and utils.c is kind of our collective
> kitchen sink for such things.

Well, I/we've been trying to stop kitchen sinks.  It makes
turning things into libraries much easier.  See the "common"
project wiki page, for example.  Things grow into kitchen sinks
little by little.  Before you know it, the beast is huge.

> I have no preference, just double checking that that's what you want.

It is.

>> It'd be nice if this and gdb_assert.h's version of the same were
>> shared.  That is, e.g., put this in common/common-utils.h instead,
>> and make gdb_assert.h define ASSERT_FUNCTION as FUNCTION_NAME
>> (or eliminate ASSERT_FUNCTION entirely).  Are you planning on
>> doing it?
> 
> Done in v2.

Thanks.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 18:39     ` [PATCH 4/6] gdbserver: Delimit debugging output for readability Yao Qi
@ 2014-01-16 19:01       ` Doug Evans
  2014-01-17  2:32         ` Joel Brobecker
                           ` (4 more replies)
  0 siblings, 5 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-16 19:01 UTC (permalink / raw)
  To: Yao Qi; +Cc: Pedro Alves, gdb-patches

On Thu, Jan 16, 2014 at 10:37 AM, Yao Qi <yao@codesourcery.com> wrote:
> On 01/15/2014 08:47 AM, Doug Evans wrote:
>> While going through the reviews, I found myself wanting something more,
>> namely timestamps (like "set debug timestamp on" in gdb).
>>
>
> Hi Doug,
> Could you help me to understand how useful timestamps are for
> measuring performance? or you use timestamps for other purposes?

All of the above.
I can use it for measuring performance, debugging(!) performance
issues, and debugging in general.

>> This patch adds a check for gettimeofday and doesn't fall back to using one
>> in libiberty or gnulib, leaving that for another day.
>
> gdbserver has used gnulib, which means we can use gettimeofday
> unconditionally in gdbserver?

Left for another day.
There's no loss in splitting this up into steps.
[The next step will itself need to be spit up into several steps: get
gettimeofday from gnulib, and then have gdbserver (and gdb) use it -
it may be a nop for gdb, say gnulib being preferred over libiberty,
but something to be confirmed nonetheless.]

>> diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
>> index 1b0da6c..e7d3e4f 100644
>> --- a/gdb/gdbserver/linux-aarch64-low.c
>> +++ b/gdb/gdbserver/linux-aarch64-low.c
>> @@ -323,7 +323,7 @@ aarch64_get_pc (struct regcache *regcache)
>>
>>    collect_register_by_name (regcache, "pc", &pc);
>>    if (debug_threads)
>> -    fprintf (stderr, "stop pc is %08lx\n", pc);
>> +    debug_printf ("stop pc is %08lx\n", pc);
>>    return pc;
>
> IWBN to move "if (debug_threads)" into debug_printf too.

I thought of that, but there are times when you want to check
debug_threads before calling debug_printf.
So then it's a case of some code checking debug_threads and some not,
and then how often will cut-n-paste hacking proliferate unnecessary
tests of debug_printf.  Another alternative is of course to call a
different function that does the check, but now we have two debug
printf functions instead of one.

btw, One thought I have is to make debug_printf a macro (or create
DEBUG_PRINTF or use a different name) so that adding FUNCTION_NAME
becomes automagic.  OTOH, I'm not sure always including the function
name will be a net win - it could be, guess it might depend on
personal preference (--debug=timestamp,funcname ? :-)).

If people really want debug_threads tests in debug_printf (which is
fine by me), that can be left for another day too.
It is arguably a separate step since it's an additional change on top
of replacing fprintf (stderr, ...) with debug_printf.

>> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
>> index eff4499..1ce5512 100644
>> --- a/gdb/gdbserver/utils.c
>> +++ b/gdb/gdbserver/utils.c
>> @@ -17,6 +17,7 @@
>
>> +
>> +/* Increase or decrease the debug printf call nesting level.
>> +   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
>> +   Call this when entering major routines that can trigger a lot of debug
>> +   output before it exits.  It allows the reader to associate subsequent
>> +   debug output to the call that ultimately triggered it.  */
>> +
>> +void
>> +debug_level_incr (int incr, const char *function_name)
>> +{
>> +  gdb_assert (incr == 1 || incr == -1);
>> +
>> +  /* Increment(/decrement) the level by one before printing the function name,
>> +     to distinguish this as an entry(/exit) point.
>> +     Then increment(/decrement) it again so that debugging printfs within
>> +     the function are recognized as such.  */
>> +  if (function_name != NULL)
>> +    {
>> +      debug_nesting_level += incr;
>> +      debug_printf ("%s %s\n",
>> +                 incr > 0 ? ">>>>entering" : "<<<<exiting",
>> +                 function_name);
>> +    }
>> +  debug_nesting_level += incr;
>> +
>> +  /* Don't crash on mismatched enter/exit, but still inform the user.  */
>> +  if (debug_nesting_level < 0)
>> +    {
>> +      debug_printf ("ERROR: mismatch in debug_level_enter/exit, level < 0\n");
>> +      debug_nesting_level = 0;
>> +    }
>> +}
>> +
>
> utils.c is compiled to both gdbserver and ipa.  IMO,
> ipa code should be thread-safe, because it can be used by a
> multi-threaded program.

That would argue for removing the indentation support, at least for now.
Fine by me.

OTOH, it seemed like ipa code has its own debug printf'ing so it can
prepend PROG, so I'm not sure this is necessary.
OTOOH, it'd be less preferable to assume(!) ipa code would never call
debug_printf.
Thoughts?

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 0/3] Add debug_printf and timestamps to gdbserver
  2014-01-16 18:54         ` Pedro Alves
@ 2014-01-16 23:28           ` Doug Evans
  2014-01-16 23:31             ` [PATCH 1/3] gdbserver debug_printf+timestamps: FUNCTION_NAME Doug Evans
                               ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-16 23:28 UTC (permalink / raw)
  To: Pedro Alves, Yao Qi; +Cc: gdb-patches

Pedro Alves writes:
 > On 01/16/2014 06:43 PM, Doug Evans wrote:
 > > On Thu, Jan 16, 2014 at 9:22 AM, Pedro Alves <palves@redhat.com> wrote:
 > 
 > > A counter-proposal is that no information is lost given that if PROG
 > > isn't present you know it's gdbserver, and it makes the debugging
 > > output consistent with the rest of gdbserver.
 > > Otherwise "Consistency Is Good" is going to make me want to prepend
 > > PROG to all gdbserver output, which I don't have a problem with, but
 > > thought I'd double check.
 > 
 > OK, I'll concede.  Let's try going without.
 > 
 > >>> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
 > >>> index eff4499..1ce5512 100644
 > >>> --- a/gdb/gdbserver/utils.c
 > >>> +++ b/gdb/gdbserver/utils.c
 > >>
 > >> Could this new debug support code be put in a new file
 > >> instead?  E.g., gdbserver/debug.c ?
 > > 
 > > It's a pretty-small file, and utils.c is kind of our collective
 > > kitchen sink for such things.
 > 
 > Well, I/we've been trying to stop kitchen sinks.  It makes
 > turning things into libraries much easier.  See the "common"
 > project wiki page, for example.  Things grow into kitchen sinks
 > little by little.  Before you know it, the beast is huge.
 > 
 > > I have no preference, just double checking that that's what you want.
 > 
 > It is.
 > 
 > >> It'd be nice if this and gdb_assert.h's version of the same were
 > >> shared.  That is, e.g., put this in common/common-utils.h instead,
 > >> and make gdb_assert.h define ASSERT_FUNCTION as FUNCTION_NAME
 > >> (or eliminate ASSERT_FUNCTION entirely).  Are you planning on
 > >> doing it?
 > > 
 > > Done in v2.
 > 
 > Thanks.

v2 is now split into three parts:

1/3 - move ASSERT_FUNCTION to FUNCTION_NAME in common-utils.h
2/3 - create new function delim_string_to_char_ptr_vec_append in gdb_vecs.c
3/3 - the actual debug_printf patch

I went with --debug[=timestamp] as the option naming.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/3] gdbserver debug_printf+timestamps: FUNCTION_NAME
  2014-01-16 23:28           ` [PATCH 0/3] Add debug_printf and timestamps to gdbserver Doug Evans
@ 2014-01-16 23:31             ` Doug Evans
  2014-01-17 12:46               ` Pedro Alves
  2014-01-16 23:33             ` [PATCH 2/3] gdbserver debug_printf+timestamps: delim_string_to_char_ptr_vec_append Doug Evans
  2014-01-16 23:37             ` [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch Doug Evans
  2 siblings, 1 reply; 26+ messages in thread
From: Doug Evans @ 2014-01-16 23:31 UTC (permalink / raw)
  To: Pedro Alves, Yao Qi; +Cc: gdb-patches

Doug Evans writes:
 > v2 is now split into three parts:
 > 
 > 1/3 - move ASSERT_FUNCTION to FUNCTION_NAME in common-utils.h
 > 2/3 - create new function delim_string_to_char_ptr_vec_append in gdb_vecs.c
 > 3/3 - the actual debug_printf patch
 > 
 > I went with --debug[=timestamp] as the option naming.

I didn't do a darwin build but the change is mechanical.

2014-01-16  Doug Evans  <dje@google.com>

	* common/common-utils.h (FUNCTION_NAME): Renamed from ASSERT_FUNCTION,
	and moved here ...
	* common/gdb_assert.h (ASSERT_FUNCTION): ... from here.
	#include "common-utils.h".
	(gdb_assert, gdb_assert_fail, gdb_assert_not_reached): Update.
	* common/vec.h (VEC_ASSERT_PASS): Update.
	* darwin-nat.h: Replace #include of gdb_assert.h with common-utils.h.
	(MACH_CHECK_ERROR): Update.

diff --git a/gdb/common/common-utils.h b/gdb/common/common-utils.h
index 9777ac0..2d99549 100644
--- a/gdb/common/common-utils.h
+++ b/gdb/common/common-utils.h
@@ -25,6 +25,19 @@
 #include <stddef.h>
 #include <stdarg.h>
 
+/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
+   which contains the name of the function currently being defined.
+   This is broken in G++ before version 2.6.
+   C9x has a similar variable called __func__, but prefer the GCC one since
+   it demangles C++ function names.  */
+#if (GCC_VERSION >= 2004)
+#define FUNCTION_NAME		__PRETTY_FUNCTION__
+#else
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#define FUNCTION_NAME		__func__
+#endif
+#endif
+
 extern void malloc_failure (long size) ATTRIBUTE_NORETURN;
 extern void internal_error (const char *file, int line, const char *, ...)
      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 4);
diff --git a/gdb/common/gdb_assert.h b/gdb/common/gdb_assert.h
index 50f7bf2..4869fc4 100644
--- a/gdb/common/gdb_assert.h
+++ b/gdb/common/gdb_assert.h
@@ -19,6 +19,8 @@
 #ifndef GDB_ASSERT_H
 #define GDB_ASSERT_H
 
+#include "common-utils.h" /* For FUNCTION_NAME.  */
+
 /* A static assertion.  This will cause a compile-time error if EXPR,
    which must be a compile-time constant, is false.  */
 
@@ -32,24 +34,11 @@
 
 #define gdb_assert(expr)                                                      \
   ((void) ((expr) ? 0 :                                                       \
-	   (gdb_assert_fail (#expr, __FILE__, __LINE__, ASSERT_FUNCTION), 0)))
-
-/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
-   which contains the name of the function currently being defined.
-   This is broken in G++ before version 2.6.
-   C9x has a similar variable called __func__, but prefer the GCC one since
-   it demangles C++ function names.  */
-#if (GCC_VERSION >= 2004)
-#define ASSERT_FUNCTION		__PRETTY_FUNCTION__
-#else
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
-#define ASSERT_FUNCTION		__func__
-#endif
-#endif
+	   (gdb_assert_fail (#expr, __FILE__, __LINE__, FUNCTION_NAME), 0)))
 
 /* This prints an "Assertion failed" message, asking the user if they
    want to continue, dump core, or just exit.  */
-#if defined (ASSERT_FUNCTION)
+#if defined (FUNCTION_NAME)
 #define gdb_assert_fail(assertion, file, line, function)                      \
   internal_error (file, line, _("%s: Assertion `%s' failed."),                \
 		  function, assertion)
@@ -62,9 +51,9 @@
 /* The canonical form of gdb_assert (0).
    MESSAGE is a string to include in the error message.  */
 
-#if defined (ASSERT_FUNCTION)
+#if defined (FUNCTION_NAME)
 #define gdb_assert_not_reached(message) \
-  internal_error (__FILE__, __LINE__, "%s: %s", ASSERT_FUNCTION, _(message))
+  internal_error (__FILE__, __LINE__, "%s: %s", FUNCTION_NAME, _(message))
 #else
 #define gdb_assert_not_reached(message) \
   internal_error (__FILE__, __LINE__, _(message))
diff --git a/gdb/common/vec.h b/gdb/common/vec.h
index 9874573..7bae2ff 100644
--- a/gdb/common/vec.h
+++ b/gdb/common/vec.h
@@ -398,7 +398,7 @@ extern void *vec_o_reserve (void *, int, size_t, size_t);
 #define VEC_ASSERT_PASS ,file_,line_
 #define vec_assert(expr, op) \
   ((void)((expr) ? 0 : (gdb_assert_fail (op, file_, line_, \
-					 ASSERT_FUNCTION), 0)))
+					 FUNCTION_NAME), 0)))
 
 #define VEC(T) VEC_##T
 #define VEC_OP(T,OP) VEC_##T##_##OP
diff --git a/gdb/darwin-nat.h b/gdb/darwin-nat.h
index 6d42a3b..84f4be1 100644
--- a/gdb/darwin-nat.h
+++ b/gdb/darwin-nat.h
@@ -18,7 +18,7 @@
 #define __DARWIN_NAT_H__
 
 #include <mach/mach.h>
-#include "gdb_assert.h"
+#include "common-utils.h" /* For FUNCTION_NAME.  */
 
 /* Describe the mach exception handling state for a task.  This state is saved
    before being changed and restored when a process is detached.
@@ -136,10 +136,10 @@ extern mach_port_t darwin_port_set;
 /* A copy of mach_host_self ().  */
 extern mach_port_t darwin_host_self;
 
-/* ASSERT_FUNCTION is defined in gdb_assert.h (or not).  */
-#ifdef ASSERT_FUNCTION
+/* FUNCTION_NAME is defined in common-utils.h (or not).  */
+#ifdef FUNCTION_NAME
 #define MACH_CHECK_ERROR(ret) \
-  mach_check_error (ret, __FILE__, __LINE__, ASSERT_FUNCTION)
+  mach_check_error (ret, __FILE__, __LINE__, FUNCTION_NAME)
 #else
 #define MACH_CHECK_ERROR(ret) \
   mach_check_error (ret, __FILE__, __LINE__, "??")

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 2/3] gdbserver debug_printf+timestamps: delim_string_to_char_ptr_vec_append
  2014-01-16 23:28           ` [PATCH 0/3] Add debug_printf and timestamps to gdbserver Doug Evans
  2014-01-16 23:31             ` [PATCH 1/3] gdbserver debug_printf+timestamps: FUNCTION_NAME Doug Evans
@ 2014-01-16 23:33             ` Doug Evans
  2014-01-16 23:37             ` [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch Doug Evans
  2 siblings, 0 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-16 23:33 UTC (permalink / raw)
  To: Pedro Alves, Yao Qi; +Cc: gdb-patches

Doug Evans writes:
 > v2 is now split into three parts:
 > 
 > 1/3 - move ASSERT_FUNCTION to FUNCTION_NAME in common-utils.h
 > 2/3 - create new function delim_string_to_char_ptr_vec_append in gdb_vecs.c
 > 3/3 - the actual debug_printf patch
 > 
 > I went with --debug[=timestamp] as the option naming.

2014-01-16  Doug Evans  <dje@google.com>

	* common/gdb_vecs.c (delim_string_to_char_ptr_vec_append): New
	function, contents of dirnames_to_char_ptr_vec_append moved here.
	(delim_string_to_char_ptr_vec): New function.
	(dirnames_to_char_ptr_vec_append): Rewrite.
	* common/gdb_vecs.h (delim_string_to_char_ptr_vec): Declare.

diff --git a/gdb/common/gdb_vecs.c b/gdb/common/gdb_vecs.c
index b256986..4a3330f 100644
--- a/gdb/common/gdb_vecs.c
+++ b/gdb/common/gdb_vecs.c
@@ -44,35 +44,60 @@ free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec)
   VEC_free (char_ptr, char_ptr_vec);
 }
 
-/* Extended version of dirnames_to_char_ptr_vec - additionally if *VECP is
-   non-NULL the new list elements from DIRNAMES are appended to the existing
-   *VECP list of entries.  *VECP address will be updated by this call.  */
+/* Worker function to split character delimiter separated string of fields
+   STR into a CHAR_PTR_VEC.  */
 
-void
-dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp, const char *dirnames)
+static void
+delim_string_to_char_ptr_vec_append (VEC (char_ptr) **vecp,
+				     const char *str, char delimiter)
 {
   do
     {
       size_t this_len;
-      char *next_dir, *this_dir;
+      char *next_field, *this_field;
 
-      next_dir = strchr (dirnames, DIRNAME_SEPARATOR);
-      if (next_dir == NULL)
-	this_len = strlen (dirnames);
+      next_field = strchr (str, delimiter);
+      if (next_field == NULL)
+	this_len = strlen (str);
       else
 	{
-	  this_len = next_dir - dirnames;
-	  next_dir++;
+	  this_len = next_field - str;
+	  next_field++;
 	}
 
-      this_dir = xmalloc (this_len + 1);
-      memcpy (this_dir, dirnames, this_len);
-      this_dir[this_len] = '\0';
-      VEC_safe_push (char_ptr, *vecp, this_dir);
+      this_field = xmalloc (this_len + 1);
+      memcpy (this_field, str, this_len);
+      this_field[this_len] = '\0';
+      VEC_safe_push (char_ptr, *vecp, this_field);
 
-      dirnames = next_dir;
+      str = next_field;
     }
-  while (dirnames != NULL);
+  while (str != NULL);
+}
+
+/* Split STR, a list of DELIMITER-separated fields, into a CHAR_PTR_VEC.
+
+   You may modify the returned strings.
+   Read free_char_ptr_vec for its cleanup.  */
+
+VEC (char_ptr) *
+delim_string_to_char_ptr_vec (const char *str, char delimiter)
+{
+  VEC (char_ptr) *retval = NULL;
+  
+  delim_string_to_char_ptr_vec_append (&retval, str, delimiter);
+
+  return retval;
+}
+
+/* Extended version of dirnames_to_char_ptr_vec - additionally if *VECP is
+   non-NULL the new list elements from DIRNAMES are appended to the existing
+   *VECP list of entries.  *VECP address will be updated by this call.  */
+
+void
+dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp, const char *dirnames)
+{
+  delim_string_to_char_ptr_vec_append (vecp, dirnames, DIRNAME_SEPARATOR);
 }
 
 /* Split DIRNAMES by DIRNAME_SEPARATOR delimiter and return a list of all the
diff --git a/gdb/common/gdb_vecs.h b/gdb/common/gdb_vecs.h
index 2978205..0606689 100644
--- a/gdb/common/gdb_vecs.h
+++ b/gdb/common/gdb_vecs.h
@@ -36,6 +36,9 @@ extern void free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec);
 extern struct cleanup *
   make_cleanup_free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec);
 
+extern VEC (char_ptr) *delim_string_to_char_ptr_vec (const char *str,
+						     char delimiter);
+
 extern void dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp,
 					     const char *dirnames);
 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-16 23:28           ` [PATCH 0/3] Add debug_printf and timestamps to gdbserver Doug Evans
  2014-01-16 23:31             ` [PATCH 1/3] gdbserver debug_printf+timestamps: FUNCTION_NAME Doug Evans
  2014-01-16 23:33             ` [PATCH 2/3] gdbserver debug_printf+timestamps: delim_string_to_char_ptr_vec_append Doug Evans
@ 2014-01-16 23:37             ` Doug Evans
  2014-01-17  2:58               ` Doug Evans
                                 ` (2 more replies)
  2 siblings, 3 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-16 23:37 UTC (permalink / raw)
  To: Pedro Alves, Yao Qi, eliz; +Cc: gdb-patches

Doug Evans writes:
 > v2 is now split into three parts:
 > 
 > 1/3 - move ASSERT_FUNCTION to FUNCTION_NAME in common-utils.h
 > 2/3 - create new function delim_string_to_char_ptr_vec_append in gdb_vecs.c
 > 3/3 - the actual debug_printf patch
 > 
 > I went with --debug[=timestamp] as the option naming.

2014-01-16  Doug Evans  <dje@google.com>

	New gdbserver option --debug=timestamp.
	* NEWS: Mention it.

	gdbserver/
	* configure.ac (AC_CHECK_FUNCS): Add test for gettimeofday.
	* configure: Regenerate.
	* config.in: Regenerate.
	* Makefile.in (SFILES): Add debug.c.
	(OBS): Add debug.o.
	* debug.c: New file.
	* debug.h: New file.
	* linux-aarch64-low.c (*): Update all debugging printfs to use
	debug_printf instead of fprintf.
	* linux-arm-low.c (*): Ditto.
	* linux-cris-low.c (*): Ditto.
	* linux-crisv32-low.c (*): Ditto.
	* linux-m32r-low.c (*): Ditto.
	* linux-sparc-low.c (*): Ditto.
	* linux-x86.c (*): Ditto.
	* linux-low.c (*): Ditto.
	(linux_wait_1): Add calls to debug_enter, debug_exit.
	(linux_wait): Remove redundant debugging printf.
	(stop_all_lwps): Add calls to debug_enter, debug_exit.
	(linux_resume, unstop_all_lwps): Ditto.
	* mem-break.c (*): Update all debugging printfs to use
	debug_printf instead of fprintf.
	* remote-utils.c (*): Ditto.
	* thread-db.c (*): Ditto.
	* server.c #include "gdb_vecs.h".
	(debug_timestamp): New global.
	(*): Update all debugging printfs to use debug_printf instead of
	fprintf.
	(start_inferior): Replace call to fflush with call to debug_flush.
	(parse_debug_options): New function.
	(gdbserver_usage): Mention --debug=timestamp.
	(main): Parse --debug=foo.
	* server.h (debug_threads): Declaration moved to debug.h.
	#include "debug.h".
	* tracepoint.c (trace_debug_1) [!IN_PROCESS_AGENT]: Add version of
	trace_debug_1 that uses debug_printf.
	(tracepoint_look_up_symbols): Update all debugging printfs to use
	debug_printf instead of fprintf.

	doc/
	* gdb.texinfo (Server): Mention --debug=timestamp.
	(gdbserver man): Ditto.

diff --git a/gdb/NEWS b/gdb/NEWS
index 44189d5..8b6a17b 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,11 @@
 
 *** Changes since GDB 7.7
 
+* New features in the GDB remote stub, GDBserver
+
+  ** GDBserver now takes an optional argument to --debug, --debug=timestamp,
+     that adds a timestamp with each debugging message.
+
 * The 'record instruction-history' command now starts counting instructions
   at one.  This also affects the instruction ranges reported by the
   'record function-call-history' command when given the /i modifier.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e77ca2a..83531d5 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18512,6 +18512,9 @@ instance closes its port after the first connection.
 @cindex @option{--debug}, @code{gdbserver} option
 The @option{--debug} option tells @code{gdbserver} to display extra
 status information about the debugging process.
+The @option{--debug} option may be passed an argument expressed as
+@option{--debug=timestamp} which includes a timestamp in each line of
+debugging output.
 @cindex @option{--remote-debug}, @code{gdbserver} option
 The @option{--remote-debug} option tells @code{gdbserver} to display
 remote protocol debug output.  These options are intended for
@@ -44337,6 +44340,9 @@ process.
 This option is intended for @code{gdbserver} development and for bug reports to
 the developers.
 
+@item --debug=timestamp
+Same as @option{--debug}, but includes timestamps in the debugging output.
+
 @item --remote-debug
 Instruct @code{gdbserver} to display remote protocol debug output.
 This option is intended for @code{gdbserver} development and for bug reports to
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index e72ee6b..46324e6 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -141,7 +141,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/mem-break.c $(srcdir)/proc-service.c \
 	$(srcdir)/proc-service.list $(srcdir)/regcache.c \
 	$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
-	$(srcdir)/thread-db.c $(srcdir)/utils.c \
+	$(srcdir)/thread-db.c $(srcdir)/utils.c $(srcdir)/debug.c \
 	$(srcdir)/linux-arm-low.c $(srcdir)/linux-bfin-low.c \
 	$(srcdir)/linux-cris-low.c $(srcdir)/linux-crisv32-low.c \
 	${srcdir}/i386-low.c $(srcdir)/i387-fp.c \
@@ -173,7 +173,7 @@ SOURCES = $(SFILES)
 TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
 
 OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \
-      target.o waitstatus.o utils.o version.o vec.o gdb_vecs.o \
+      target.o waitstatus.o utils.o debug.o version.o vec.o gdb_vecs.o \
       mem-break.o hostio.o event-loop.o tracepoint.o xml-utils.o \
       common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \
       tdesc.o $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS)
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index e33cdea..1b9751f 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -66,6 +66,9 @@
 /* Define to 1 if you have the `getrlimit' function. */
 #undef HAVE_GETRLIMIT
 
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index fac7fb3..6d8a6a7 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4728,7 +4728,7 @@ fi
 
 done
 
-for ac_func in pread pwrite pread64 readlink
+for ac_func in gettimeofday pread pwrite pread64 readlink
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index dc8131c..0dfa4a9 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -82,7 +82,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 errno.h fcntl.h signal.h sys/file.h malloc.h dnl
 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
 		 netinet/tcp.h arpa/inet.h)
-AC_CHECK_FUNCS(pread pwrite pread64 readlink)
+AC_CHECK_FUNCS(gettimeofday pread pwrite pread64 readlink)
 AC_REPLACE_FUNCS(vasprintf vsnprintf)
 
 GDB_AC_COMMON
diff --git a/gdb/gdbserver/debug.c b/gdb/gdbserver/debug.c
new file mode 100644
index 0000000..f5963ee
--- /dev/null
+++ b/gdb/gdbserver/debug.c
@@ -0,0 +1,86 @@
+/* General utility routines for the remote server for GDB.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "server.h"
+#include <sys/time.h>
+
+/* Print a debugging message.
+   If the text begins a new line it is preceded by a timestamp, if the
+   system has gettimeofday.
+   We don't get fancy with newline checking, we just check whether the
+   previous call ended with "\n".  */
+
+void
+debug_printf (const char *msg, ...)
+{
+  va_list args;
+#ifdef HAVE_GETTIMEOFDAY
+  static int new_line = 1;
+
+  if (debug_timestamp && new_line)
+    {
+      struct timeval tm;
+
+      gettimeofday (&tm, NULL);
+      fprintf (stderr, "%ld:%06ld ", (long) tm.tv_sec, (long) tm.tv_usec);
+    }
+#endif
+
+  va_start (args, msg);
+  vfprintf (stderr, msg, args);
+  va_end (args);
+
+#ifdef HAVE_GETTIMEOFDAY
+  if (*msg)
+    new_line = msg[strlen (msg) - 1] == '\n';
+#endif
+}
+
+/* Flush debugging output.
+   This is called, for example, when starting an inferior to ensure all debug
+   output thus far appears before any inferior output.  */
+
+void
+debug_flush (void)
+{
+  fflush (stderr);
+}
+
+/* Notify the user that the code is entering FUNCTION_NAME.
+   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
+
+   This is intended to be called via the debug_enter macro.  */
+
+void
+do_debug_enter (const char *function_name)
+{
+  if (function_name != NULL)
+    debug_printf (">>>> entering %s\n", function_name);
+}
+
+/* Notify the user that the code is exiting FUNCTION_NAME.
+   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
+
+   This is intended to be called via the debug_exit macro.  */
+
+void
+do_debug_exit (const char *function_name)
+{
+  if (function_name != NULL)
+    debug_printf ("<<<< exiting %s\n", function_name);
+}
diff --git a/gdb/gdbserver/debug.h b/gdb/gdbserver/debug.h
new file mode 100644
index 0000000..435f683
--- /dev/null
+++ b/gdb/gdbserver/debug.h
@@ -0,0 +1,48 @@
+/* General utility routines for the remote server for GDB.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+extern int debug_threads;
+extern int debug_timestamp;
+
+void debug_printf (const char *msg, ...) ATTRIBUTE_PRINTF (1, 2);
+void debug_flush (void);
+void do_debug_enter (const char *function_name);
+void do_debug_exit (const char *function_name);
+
+/* These macros are for use in major functions that produce a lot of
+   debugging output.  They help identify in the mass of debugging output
+   when these functions enter and exit.  debug_enter is intended to be
+   called at the start of a function, before any other debugging output.
+   debug_exit is intended to be called at the end of the same function,
+   after all debugging output.  */
+#ifdef FUNCTION_NAME
+#define debug_enter() \
+  do { do_debug_enter (FUNCTION_NAME); } while (0)
+#define debug_exit() \
+  do { do_debug_exit (FUNCTION_NAME); } while (0)
+#else
+#define debug_enter() \
+  do { do_debug_enter (NULL); } while (0)
+#define debug_exit() \
+  do { do_debug_exit (NULL); } while (0)
+#endif
+
+#endif /* UTILS_H */
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index 1b0da6c..e7d3e4f 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -323,7 +323,7 @@ aarch64_get_pc (struct regcache *regcache)
 
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index da5085c..fb6ff68 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -256,7 +256,7 @@ arm_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-cris-low.c b/gdb/gdbserver/linux-cris-low.c
index d229d43..2abd987 100644
--- a/gdb/gdbserver/linux-cris-low.c
+++ b/gdb/gdbserver/linux-cris-low.c
@@ -67,7 +67,7 @@ cris_get_pc (struct regcache *regcache, void)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-crisv32-low.c b/gdb/gdbserver/linux-crisv32-low.c
index e4ebb62..a16a656 100644
--- a/gdb/gdbserver/linux-crisv32-low.c
+++ b/gdb/gdbserver/linux-crisv32-low.c
@@ -63,7 +63,7 @@ cris_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 01d0e84..bac6134 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -475,7 +475,7 @@ get_pc (struct lwp_info *lwp)
   pc = (*the_low_target.get_pc) (regcache);
 
   if (debug_threads)
-    fprintf (stderr, "pc is 0x%lx\n", (long) pc);
+    debug_printf ("pc is 0x%lx\n", (long) pc);
 
   current_inferior = saved_inferior;
   return pc;
@@ -520,7 +520,7 @@ get_stop_pc (struct lwp_info *lwp)
     stop_pc -= the_low_target.decr_pc_after_break;
 
   if (debug_threads)
-    fprintf (stderr, "stop pc is 0x%lx\n", (long) stop_pc);
+    debug_printf ("stop pc is 0x%lx\n", (long) stop_pc);
 
   return stop_pc;
 }
@@ -692,8 +692,7 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
   if (linux_proc_pid_is_stopped (lwpid))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Attached to a stopped process\n");
+	debug_printf ("Attached to a stopped process\n");
 
       /* The process is definitely stopped.  It is in a job control
 	 stop, unless the kernel predates the TASK_STOPPED /
@@ -824,8 +823,8 @@ linux_attach (unsigned long pid)
 		      new_threads_found++;
 
 		      if (debug_threads)
-			fprintf (stderr, "\
-Found and attached to new lwp %ld\n", lwp);
+			debug_printf ("Found and attached to new lwp %ld\n",
+				      lwp);
 		    }
 		}
 
@@ -898,18 +897,16 @@ linux_kill_one_lwp (struct lwp_info *lwp)
   errno = 0;
   kill (pid, SIGKILL);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 
   errno = 0;
   ptrace (PTRACE_KILL, pid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 }
 
 /* Callback for `find_inferior'.  Kills an lwp of a given process,
@@ -934,8 +931,8 @@ kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
   if (lwpid_of (lwp) == pid)
     {
       if (debug_threads)
-	fprintf (stderr, "lkop: is last of process %s\n",
-		 target_pid_to_str (entry->id));
+	debug_printf ("lkop: is last of process %s\n",
+		      target_pid_to_str (entry->id));
       return 0;
     }
 
@@ -975,14 +972,14 @@ linux_kill (int pid)
   if (lwp == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: cannot find lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: cannot find lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: killing lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: killing lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
 
       do
 	{
@@ -1031,9 +1028,8 @@ get_detach_signal (struct thread_info *thread)
   if (!WIFSTOPPED (status))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s hasn't stopped: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s hasn't stopped: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1041,10 +1037,9 @@ get_detach_signal (struct thread_info *thread)
   if (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had stopped with extended "
-		 "status: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s had stopped with extended "
+		      "status: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1053,10 +1048,9 @@ get_detach_signal (struct thread_info *thread)
   if (program_signals_p && !program_signals[signo])
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, but it is in nopass state\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else if (!program_signals_p
@@ -1066,20 +1060,19 @@ get_detach_signal (struct thread_info *thread)
 	   && (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, "
-		 "but we don't know if we should pass it.  Default to not.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, "
+		      "but we don't know if we should pass it. "
+		      "Default to not.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s has pending signal %s: delivering it.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s has pending signal %s: delivering it.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
 
       return WSTOPSIG (status);
     }
@@ -1100,9 +1093,8 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Sending SIGCONT to %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("Sending SIGCONT to %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       kill_lwp (lwpid_of (lwp), SIGCONT);
       lwp->stop_expected = 0;
@@ -1276,7 +1268,7 @@ linux_wait_for_lwp (ptid_t ptid, int *wstatp, int options)
   struct lwp_info *child = NULL;
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
+    debug_printf ("linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
 
   if (ptid_equal (ptid, minus_one_ptid))
     to_wait_for = -1;			/* any child */
@@ -1297,7 +1289,7 @@ retry:
       && (!WIFSTOPPED (*wstatp)
 	  || (WSTOPSIG (*wstatp) != 32
 	      && WSTOPSIG (*wstatp) != 33)))
-    fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp);
+    debug_printf ("Got an event from %d (%x)\n", ret, *wstatp);
 
   child = find_lwp_pid (pid_to_ptid (ret));
 
@@ -1404,7 +1396,7 @@ retry:
       current_inferior = get_lwp_thread (child);
       regcache = get_thread_regcache (current_inferior, 1);
       pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
+      debug_printf ("linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
       current_inferior = saved_inferior;
     }
 
@@ -1450,7 +1442,7 @@ handle_tracepoints (struct lwp_info *lwp)
   if (tpoint_related_event)
     {
       if (debug_threads)
-	fprintf (stderr, "got a tracepoint event\n");
+	debug_printf ("got a tracepoint event\n");
       return 1;
     }
 
@@ -1501,9 +1493,9 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
       int r;
 
       if (debug_threads)
-	fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Checking whether LWP %ld needs to move out of the "
+		      "jump pad.\n",
+		      lwpid_of (lwp));
 
       r = linux_fast_tracepoint_collecting (lwp, &status);
 
@@ -1527,9 +1519,9 @@ Checking whether LWP %ld needs to move out of the jump pad.\n",
 		}
 
 	      if (debug_threads)
-		fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...it does\n",
-		 lwpid_of (lwp));
+		debug_printf ("Checking whether LWP %ld needs to move out of "
+			      "the jump pad...it does\n",
+			      lwpid_of (lwp));
 	      current_inferior = saved_inferior;
 
 	      return 1;
@@ -1582,9 +1574,8 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
 	  if (lwp->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Cancelling fast exit-jump-pad: removing bkpt. "
-			 "stopping all threads momentarily.\n");
+		debug_printf ("Cancelling fast exit-jump-pad: removing bkpt. "
+			      "stopping all threads momentarily.\n");
 
 	      stop_all_lwps (1, lwp);
 	      cancel_breakpoints ();
@@ -1600,9 +1591,9 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
     }
 
   if (debug_threads)
-    fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...no\n",
-	     lwpid_of (lwp));
+    debug_printf ("Checking whether LWP %ld needs to move out of the "
+		  "jump pad...no\n",
+		  lwpid_of (lwp));
 
   current_inferior = saved_inferior;
   return 0;
@@ -1617,8 +1608,8 @@ enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
   struct pending_signals *p_sig;
 
   if (debug_threads)
-    fprintf (stderr, "\
-Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
+    debug_printf ("Deferring signal %d for LWP %ld.\n",
+		  WSTOPSIG (*wstat), lwpid_of (lwp));
 
   if (debug_threads)
     {
@@ -1627,11 +1618,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
       for (sig = lwp->pending_signals_to_report;
 	   sig != NULL;
 	   sig = sig->prev)
-	fprintf (stderr,
-		 "   Already queued %d\n",
-		 sig->signal);
+	debug_printf ("   Already queued %d\n",
+		      sig->signal);
 
-      fprintf (stderr, "   (no more currently queued signals)\n");
+      debug_printf ("   (no more currently queued signals)\n");
     }
 
   /* Don't enqueue non-RT signals if they are already in the deferred
@@ -1648,11 +1638,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
 	  if (sig->signal == WSTOPSIG (*wstat))
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Not requeuing already queued non-RT signal %d"
-			 " for LWP %ld\n",
-			 sig->signal,
-			 lwpid_of (lwp));
+		debug_printf ("Not requeuing already queued non-RT signal %d"
+			      " for LWP %ld\n",
+			      sig->signal,
+			      lwpid_of (lwp));
 	      return;
 	    }
 	}
@@ -1690,8 +1679,8 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
       *p_sig = NULL;
 
       if (debug_threads)
-	fprintf (stderr, "Reporting deferred signal %d for LWP %ld.\n",
-		 WSTOPSIG (*wstat), lwpid_of (lwp));
+	debug_printf ("Reporting deferred signal %d for LWP %ld.\n",
+		      WSTOPSIG (*wstat), lwpid_of (lwp));
 
       if (debug_threads)
 	{
@@ -1700,11 +1689,10 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 	  for (sig = lwp->pending_signals_to_report;
 	       sig != NULL;
 	       sig = sig->prev)
-	    fprintf (stderr,
-		     "   Still queued %d\n",
-		     sig->signal);
+	    debug_printf ("   Still queued %d\n",
+			  sig->signal);
 
-	  fprintf (stderr, "   (no more queued signals)\n");
+	  debug_printf ("   (no more queued signals)\n");
 	}
 
       return 1;
@@ -1734,9 +1722,8 @@ cancel_breakpoint (struct lwp_info *lwp)
   if ((*the_low_target.breakpoint_at) (lwp->stop_pc))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: Push back breakpoint for %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: Push back breakpoint for %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       /* Back up the PC if necessary.  */
       if (the_low_target.decr_pc_after_break)
@@ -1752,10 +1739,9 @@ cancel_breakpoint (struct lwp_info *lwp)
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: No breakpoint found at %s for [%s]\n",
-		 paddress (lwp->stop_pc),
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: No breakpoint found at %s for [%s]\n",
+		      paddress (lwp->stop_pc),
+		      target_pid_to_str (ptid_of (lwp)));
     }
 
   current_inferior = saved_inferior;
@@ -1788,7 +1774,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       event_child = (struct lwp_info *)
 	find_inferior (&all_lwps, status_pending_p_callback, &ptid);
       if (debug_threads && event_child)
-	fprintf (stderr, "Got a pending child %ld\n", lwpid_of (event_child));
+	debug_printf ("Got a pending child %ld\n", lwpid_of (event_child));
     }
   else
     {
@@ -1816,8 +1802,8 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
   if (event_child != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
-		 lwpid_of (event_child), event_child->status_pending);
+	debug_printf ("Got an event from pending child %ld (%04x)\n",
+		      lwpid_of (event_child), event_child->status_pending);
       *wstat = event_child->status_pending;
       event_child->status_pending_p = 0;
       event_child->status_pending = 0;
@@ -1847,7 +1833,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if ((options & WNOHANG) && event_child == NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "WNOHANG set, no event found\n");
+	    debug_printf ("WNOHANG set, no event found\n");
 	  return 0;
 	}
 
@@ -1873,14 +1859,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if (! WIFSTOPPED (*wstat))
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld exiting\n", lwpid_of (event_child));
+	    debug_printf ("LWP %ld exiting\n", lwpid_of (event_child));
 
 	  /* If the last thread is exiting, just return.  */
 	  if (last_thread_of_process_p (current_inferior))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "LWP %ld is last lwp of process\n",
-			 lwpid_of (event_child));
+		debug_printf ("LWP %ld is last lwp of process\n",
+			      lwpid_of (event_child));
 	      return lwpid_of (event_child);
 	    }
 
@@ -1888,14 +1874,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	    {
 	      current_inferior = (struct thread_info *) all_threads.head;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now %ld\n",
-			 lwpid_of (get_thread_lwp (current_inferior)));
+		debug_printf ("Current inferior is now %ld\n",
+			      lwpid_of (get_thread_lwp (current_inferior)));
 	    }
 	  else
 	    {
 	      current_inferior = NULL;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now <NULL>\n");
+		debug_printf ("Current inferior is now <NULL>\n");
 	    }
 
 	  /* If we were waiting for this particular child to do something...
@@ -1938,7 +1924,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	  int should_stop;
 
 	  if (debug_threads)
-	    fprintf (stderr, "Expected stop.\n");
+	    debug_printf ("Expected stop.\n");
 	  event_child->stop_expected = 0;
 
 	  should_stop = (current_inferior->last_resume_kind == resume_stop
@@ -2082,9 +2068,8 @@ select_event_lwp (struct lwp_info **orig_lp)
   if (event_lp != NULL)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "SEL: Select single-step %s\n",
-		 target_pid_to_str (ptid_of (event_lp)));
+	debug_printf ("SEL: Select single-step %s\n",
+		      target_pid_to_str (ptid_of (event_lp)));
     }
   else
     {
@@ -2099,9 +2084,8 @@ select_event_lwp (struct lwp_info **orig_lp)
 	((num_events * (double) rand ()) / (RAND_MAX + 1.0));
 
       if (debug_threads && num_events > 1)
-	fprintf (stderr,
-		 "SEL: Found %d SIGTRAP events, selecting #%d\n",
-		 num_events, random_selector);
+	debug_printf ("SEL: Found %d SIGTRAP events, selecting #%d\n",
+		      num_events, random_selector);
 
       event_lp = (struct lwp_info *) find_inferior (&all_lwps,
 						    select_event_lwp_callback,
@@ -2191,8 +2175,8 @@ linux_stabilize_threads (void)
   if (lwp_stuck != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "can't stabilize, LWP %ld is stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("can't stabilize, LWP %ld is stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
       return;
     }
 
@@ -2243,8 +2227,8 @@ linux_stabilize_threads (void)
 	= (struct lwp_info *) find_inferior (&all_lwps,
 					 stuck_in_jump_pad_callback, NULL);
       if (lwp_stuck != NULL)
-	fprintf (stderr, "couldn't stabilize, LWP %ld got stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
     }
 }
 
@@ -2265,6 +2249,12 @@ linux_wait_1 (ptid_t ptid,
   int trace_event;
   int in_step_range;
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("linux_wait_1: [%s]\n", target_pid_to_str (ptid));
+    }
+
   /* Translate generic target options into linux options.  */
   options = __WALL;
   if (target_options & TARGET_WNOHANG)
@@ -2309,13 +2299,20 @@ retry:
   else
     {
       if (debug_threads)
-	fprintf (stderr, "step_over_bkpt set [%s], doing a blocking wait\n",
-		 target_pid_to_str (step_over_bkpt));
+	debug_printf ("step_over_bkpt set [%s], doing a blocking wait\n",
+		      target_pid_to_str (step_over_bkpt));
       pid = linux_wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
     }
 
   if (pid == 0) /* only if TARGET_WNOHANG */
-    return null_ptid;
+    {
+      if (debug_threads)
+	{
+	  debug_printf ("linux_wait_1 ret = null_ptid\n");
+	  debug_exit ();
+	}
+      return null_ptid;
+    }
 
   event_child = get_thread_lwp (current_inferior);
 
@@ -2341,9 +2338,13 @@ retry:
 	      ourstatus->value.integer = WEXITSTATUS (w);
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild exited with retcode = %x \n",
-			 WEXITSTATUS (w));
+		{
+		  debug_printf ("linux_wait_1 ret = %s, exited with "
+				"retcode %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WEXITSTATUS (w));
+		  debug_exit ();
+		}
 	    }
 	  else
 	    {
@@ -2351,10 +2352,13 @@ retry:
 	      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild terminated with signal = %x \n",
-			 WTERMSIG (w));
-
+		{
+		  debug_printf ("linux_wait_1 ret = %s, terminated with "
+				"signal %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WTERMSIG (w));
+		  debug_exit ();
+		}
 	    }
 
 	  return ptid_of (event_child);
@@ -2409,7 +2413,7 @@ retry:
 	     already handled it.  So next time we resume (from this
 	     PC), we should step over it.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 
 	  if (breakpoint_here (event_child->stop_pc))
 	    event_child->need_step_over = 1;
@@ -2435,10 +2439,9 @@ retry:
       && agent_loaded_p ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Got signal %d for LWP %ld.  Check if we need "
-		 "to defer or adjust it.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Got signal %d for LWP %ld.  Check if we need "
+		      "to defer or adjust it.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       /* Allow debugging the jump pad itself.  */
       if (current_inferior->last_resume_kind != resume_step
@@ -2447,9 +2450,8 @@ retry:
 	  enqueue_one_deferred_signal (event_child, &w);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred (in jump pad)\n",
-		     WSTOPSIG (w), lwpid_of (event_child));
+	    debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n",
+			  WSTOPSIG (w), lwpid_of (event_child));
 
 	  linux_resume_one_lwp (event_child, 0, 0, NULL);
 	  goto retry;
@@ -2459,11 +2461,10 @@ retry:
   if (event_child->collecting_fast_tracepoint)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-LWP %ld was trying to move out of the jump pad (%d).  \
-Check if we're already there.\n",
-		 lwpid_of (event_child),
-		 event_child->collecting_fast_tracepoint);
+	debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
+		      "Check if we're already there.\n",
+		      lwpid_of (event_child),
+		      event_child->collecting_fast_tracepoint);
 
       trace_event = 1;
 
@@ -2476,9 +2477,8 @@ Check if we're already there.\n",
 	  if (event_child->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "No longer need exit-jump-pad bkpt; removing it."
-			 "stopping all threads momentarily.\n");
+		debug_printf ("No longer need exit-jump-pad bkpt; removing it."
+			      "stopping all threads momentarily.\n");
 
 	      /* Other running threads could hit this breakpoint.
 		 We don't handle moribund locations like GDB does,
@@ -2502,25 +2502,33 @@ Check if we're already there.\n",
       if (event_child->collecting_fast_tracepoint == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "fast tracepoint finished "
-		     "collecting successfully.\n");
+	    debug_printf ("fast tracepoint finished "
+			  "collecting successfully.\n");
 
 	  /* We may have a deferred signal to report.  */
 	  if (dequeue_one_deferred_signal (event_child, &w))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "dequeued one signal.\n");
+		debug_printf ("dequeued one signal.\n");
 	    }
 	  else
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "no deferred signals.\n");
+		debug_printf ("no deferred signals.\n");
 
 	      if (stabilizing_threads)
 		{
 		  ourstatus->kind = TARGET_WAITKIND_STOPPED;
 		  ourstatus->value.sig = GDB_SIGNAL_0;
+
+		  if (debug_threads)
+		    {
+		      debug_printf ("linux_wait_1 ret = %s, stopped "
+				    "while stabilizing threads\n",
+				    target_pid_to_str (ptid_of (event_child)));
+		      debug_exit ();
+		    }
+
 		  return ptid_of (event_child);
 		}
 	    }
@@ -2554,8 +2562,8 @@ Check if we're already there.\n",
       siginfo_t info, *info_p;
 
       if (debug_threads)
-	fprintf (stderr, "Ignored signal %d for LWP %ld.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Ignored signal %d for LWP %ld.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       if (ptrace (PTRACE_GETSIGINFO, lwpid_of (event_child),
 		  (PTRACE_TYPE_ARG3) 0, &info) == 0)
@@ -2600,16 +2608,16 @@ Check if we're already there.\n",
       if (debug_threads)
 	{
 	  if (bp_explains_trap)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 	  if (step_over_finished)
-	    fprintf (stderr, "Step-over finished.\n");
+	    debug_printf ("Step-over finished.\n");
 	  if (trace_event)
-	    fprintf (stderr, "Tracepoint event.\n");
+	    debug_printf ("Tracepoint event.\n");
 	  if (lwp_in_step_range (event_child))
-	    fprintf (stderr, "Range stepping pc 0x%s [0x%s, 0x%s).\n",
-		     paddress (event_child->stop_pc),
-		     paddress (event_child->step_range_start),
-		     paddress (event_child->step_range_end));
+	    debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).\n",
+			  paddress (event_child->stop_pc),
+			  paddress (event_child->step_range_start),
+			  paddress (event_child->step_range_end));
 	}
 
       /* We're not reporting this breakpoint to GDB, so apply the
@@ -2629,7 +2637,7 @@ Check if we're already there.\n",
 	 going to keep waiting, so use proceed, which handles stepping
 	 over the next breakpoint.  */
       if (debug_threads)
-	fprintf (stderr, "proceeding all threads.\n");
+	debug_printf ("proceeding all threads.\n");
 
       if (step_over_finished)
 	unsuspend_all_lwps (event_child);
@@ -2643,16 +2651,16 @@ Check if we're already there.\n",
       if (current_inferior->last_resume_kind == resume_step)
 	{
 	  if (event_child->step_range_start == event_child->step_range_end)
-	    fprintf (stderr, "GDB wanted to single-step, reporting event.\n");
+	    debug_printf ("GDB wanted to single-step, reporting event.\n");
 	  else if (!lwp_in_step_range (event_child))
-	    fprintf (stderr, "Out of step range, reporting event.\n");
+	    debug_printf ("Out of step range, reporting event.\n");
 	}
       if (event_child->stopped_by_watchpoint)
-	fprintf (stderr, "Stopped by watchpoint.\n");
+	debug_printf ("Stopped by watchpoint.\n");
       if (gdb_breakpoint_here (event_child->stop_pc))
-	fprintf (stderr, "Stopped by GDB breakpoint.\n");
+	debug_printf ("Stopped by GDB breakpoint.\n");
       if (debug_threads)
-	fprintf (stderr, "Hit a non-gdbserver trap event.\n");
+	debug_printf ("Hit a non-gdbserver trap event.\n");
     }
 
   /* Alright, we're going to report a stop.  */
@@ -2730,10 +2738,12 @@ Check if we're already there.\n",
   gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait ret = %s, %d, %d\n",
-	     target_pid_to_str (ptid_of (event_child)),
-	     ourstatus->kind,
-	     ourstatus->value.sig);
+    {
+      debug_printf ("linux_wait_1 ret = %s, %d, %d\n",
+		    target_pid_to_str (ptid_of (event_child)),
+		    ourstatus->kind, ourstatus->value.sig);
+      debug_exit ();
+    }
 
   return ptid_of (event_child);
 }
@@ -2772,9 +2782,6 @@ linux_wait (ptid_t ptid,
 {
   ptid_t event_ptid;
 
-  if (debug_threads)
-    fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
-
   /* Flush the async file first.  */
   if (target_is_async_p ())
     async_file_flush ();
@@ -2837,13 +2844,13 @@ send_sigstop (struct lwp_info *lwp)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr, "Have pending sigstop for lwp %d\n", pid);
+	debug_printf ("Have pending sigstop for lwp %d\n", pid);
 
       return;
     }
 
   if (debug_threads)
-    fprintf (stderr, "Sending sigstop to lwp %d\n", pid);
+    debug_printf ("Sending sigstop to lwp %d\n", pid);
 
   lwp->stop_expected = 1;
   kill_lwp (pid, SIGSTOP);
@@ -2912,8 +2919,8 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "wait_for_sigstop: LWP %ld already stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("wait_for_sigstop: LWP %ld already stopped\n",
+		      lwpid_of (lwp));
       return;
     }
 
@@ -2926,7 +2933,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   ptid = lwp->head.id;
 
   if (debug_threads)
-    fprintf (stderr, "wait_for_sigstop: pulling one event\n");
+    debug_printf ("wait_for_sigstop: pulling one event\n");
 
   pid = linux_wait_for_event (ptid, &wstat, __WALL);
 
@@ -2936,14 +2943,14 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (WIFSTOPPED (wstat))
     {
       if (debug_threads)
-	fprintf (stderr, "LWP %ld stopped with signal %d\n",
-		 lwpid_of (lwp), WSTOPSIG (wstat));
+	debug_printf ("LWP %ld stopped with signal %d\n",
+		      lwpid_of (lwp), WSTOPSIG (wstat));
 
       if (WSTOPSIG (wstat) != SIGSTOP)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n",
-		     lwpid_of (lwp), wstat);
+	    debug_printf ("LWP %ld stopped with non-sigstop status %06x\n",
+			  lwpid_of (lwp), wstat);
 
 	  lwp->status_pending_p = 1;
 	  lwp->status_pending = wstat;
@@ -2952,7 +2959,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Process %d exited while stopping LWPs\n", pid);
+	debug_printf ("Process %d exited while stopping LWPs\n", pid);
 
       lwp = find_lwp_pid (pid_to_ptid (pid));
       if (lwp)
@@ -2973,7 +2980,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Previously current thread died.\n");
+	debug_printf ("Previously current thread died.\n");
 
       if (non_stop)
 	{
@@ -3032,9 +3039,8 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
       && maybe_move_out_of_jump_pad (lwp, wstat))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "LWP %ld needs stabilizing (in jump pad)\n",
-		 lwpid_of (lwp));
+	debug_printf ("LWP %ld needs stabilizing (in jump pad)\n",
+		      lwpid_of (lwp));
 
       if (wstat)
 	{
@@ -3042,10 +3048,9 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
 	  enqueue_one_deferred_signal (lwp, wstat);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred "
-		     "(in jump pad)\n",
-		     WSTOPSIG (*wstat), lwpid_of (lwp));
+	    debug_printf ("Signal %d for LWP %ld deferred "
+			  "(in jump pad)\n",
+			  WSTOPSIG (*wstat), lwpid_of (lwp));
 	}
 
       linux_resume_one_lwp (lwp, 0, 0, NULL);
@@ -3076,6 +3081,16 @@ stop_all_lwps (int suspend, struct lwp_info *except)
   /* Should not be called recursively.  */
   gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("stop_all_lwps (%s, except=%s)\n",
+		    suspend ? "stop-and-suspend" : "stop",
+		    except != NULL
+		    ? target_pid_to_str (ptid_of (except))
+		    : "none");
+    }
+
   stopping_threads = (suspend
 		      ? STOPPING_AND_SUSPENDING_THREADS
 		      : STOPPING_THREADS);
@@ -3086,6 +3101,13 @@ stop_all_lwps (int suspend, struct lwp_info *except)
     find_inferior (&all_lwps, send_sigstop_callback, except);
   for_each_inferior (&all_lwps, wait_for_sigstop);
   stopping_threads = NOT_STOPPING_THREADS;
+
+  if (debug_threads)
+    {
+      debug_printf ("stop_all_lwps done, setting stopping_threads "
+		    "back to !stopping\n");
+      debug_exit ();
+    }
 }
 
 /* Resume execution of the inferior process.
@@ -3138,10 +3160,10 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "Not resuming lwp %ld (%s, signal %d, stop %s);"
-		 " has pending status\n",
-		 lwpid_of (lwp), step ? "step" : "continue", signal,
-		 lwp->stop_expected ? "expected" : "not expected");
+	debug_printf ("Not resuming lwp %ld (%s, signal %d, stop %s);"
+		      " has pending status\n",
+		      lwpid_of (lwp), step ? "step" : "continue", signal,
+		      lwp->stop_expected ? "expected" : "not expected");
       return;
     }
 
@@ -3149,9 +3171,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   current_inferior = get_lwp_thread (lwp);
 
   if (debug_threads)
-    fprintf (stderr, "Resuming lwp %ld (%s, signal %d, stop %s)\n",
-	     lwpid_of (lwp), step ? "step" : "continue", signal,
-	     lwp->stop_expected ? "expected" : "not expected");
+    debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)\n",
+		  lwpid_of (lwp), step ? "step" : "continue", signal,
+		  lwp->stop_expected ? "expected" : "not expected");
 
   /* This bit needs some thinking about.  If we get a signal that
      we must report while a single-step reinsert is still pending,
@@ -3166,8 +3188,8 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "  pending reinsert at 0x%s\n",
-		 paddress (lwp->bp_reinsert));
+	debug_printf ("  pending reinsert at 0x%s\n",
+		      paddress (lwp->bp_reinsert));
 
       if (can_hardware_single_step ())
 	{
@@ -3190,9 +3212,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (fast_tp_collecting == 1)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " (exit-jump-pad-bkpt)\n",
+		      lwpid_of (lwp));
 
       /* Postpone any pending signal.  It was enqueued above.  */
       signal = 0;
@@ -3200,9 +3222,9 @@ lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
   else if (fast_tp_collecting == 2)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " single-stepping\n",
+		      lwpid_of (lwp));
 
       if (can_hardware_single_step ())
 	step = 1;
@@ -3226,9 +3248,8 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
       && can_hardware_single_step ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "lwp %ld has a while-stepping action -> forcing step.\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld has a while-stepping action -> forcing step.\n",
+		      lwpid_of (lwp));
       step = 1;
     }
 
@@ -3236,7 +3257,7 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
     {
       struct regcache *regcache = get_thread_regcache (current_inferior, 1);
       CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "  resuming from pc 0x%lx\n", (long) pc);
+      debug_printf ("  resuming from pc 0x%lx\n", (long) pc);
     }
 
   /* If we have pending signals, consume one unless we are trying to
@@ -3334,11 +3355,12 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      && thread->last_resume_kind == resume_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "already %s LWP %ld at GDB's request\n",
-			 thread->last_status.kind == TARGET_WAITKIND_STOPPED
-			 ? "stopped"
-			 : "stopping",
-			 lwpid_of (lwp));
+		debug_printf ("already %s LWP %ld at GDB's request\n",
+			      (thread->last_status.kind
+			       == TARGET_WAITKIND_STOPPED)
+			      ? "stopped"
+			      : "stopping",
+			      lwpid_of (lwp));
 
 	      continue;
 	    }
@@ -3359,10 +3381,9 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      lwp->status_pending_p = 1;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Dequeueing deferred signal %d for LWP %ld, "
-			 "leaving status pending.\n",
-			 WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
+		debug_printf ("Dequeueing deferred signal %d for LWP %ld, "
+			      "leaving status pending.\n",
+			      WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
 	    }
 
 	  return 0;
@@ -3413,9 +3434,8 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, not stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3424,9 +3444,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (thread->last_resume_kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, should remain stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, should remain"
+		      " stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3435,25 +3455,23 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, suspended\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, suspended\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (!lwp->need_step_over)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? No\n", lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? No\n", lwpid_of (lwp));
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, has pending status.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
+		      " status.\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3469,10 +3487,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (pc != lwp->stop_pc)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Cancelling, PC was changed.  "
-		 "Old stop_pc was 0x%s, PC is now 0x%s\n",
-		 lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
+	debug_printf ("Need step over [LWP %ld]? Cancelling, PC was changed. "
+		      "Old stop_pc was 0x%s, PC is now 0x%s\n",
+		      lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
 
       lwp->need_step_over = 0;
       return 0;
@@ -3492,10 +3509,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
 	  && gdb_no_commands_at_breakpoint (pc))
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, but found"
-		     " GDB breakpoint at 0x%s; skipping step over\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, but found"
+			  " GDB breakpoint at 0x%s; skipping step over\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  current_inferior = saved_inferior;
 	  return 0;
@@ -3503,10 +3519,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, "
-		     "found breakpoint at 0x%s\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, "
+			  "found breakpoint at 0x%s\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  /* We've found an lwp that needs stepping over --- return 1 so
 	     that find_inferior stops looking.  */
@@ -3521,9 +3536,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   current_inferior = saved_inferior;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Need step over [LWP %ld]? No, no breakpoint found at 0x%s\n",
-	     lwpid_of (lwp), paddress (pc));
+    debug_printf ("Need step over [LWP %ld]? No, no breakpoint found"
+		  " at 0x%s\n",
+		  lwpid_of (lwp), paddress (pc));
 
   return 0;
 }
@@ -3554,15 +3569,14 @@ start_step_over (struct lwp_info *lwp)
   int step;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Starting step-over on LWP %ld.  Stopping all threads\n",
-	     lwpid_of (lwp));
+    debug_printf ("Starting step-over on LWP %ld.  Stopping all threads\n",
+		  lwpid_of (lwp));
 
   stop_all_lwps (1, lwp);
   gdb_assert (lwp->suspended == 0);
 
   if (debug_threads)
-    fprintf (stderr, "Done stopping all threads for step-over.\n");
+    debug_printf ("Done stopping all threads for step-over.\n");
 
   /* Note, we should always reach here with an already adjusted PC,
      either by GDB (if we're resuming due to GDB's request), or by our
@@ -3607,7 +3621,7 @@ finish_step_over (struct lwp_info *lwp)
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "Finished step over.\n");
+	debug_printf ("Finished step over.\n");
 
       /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
 	 may be no breakpoint to reinsert there by now.  */
@@ -3662,12 +3676,12 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (lwp->resume->kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr, "resume_stop request for LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resume_stop request for LWP %ld\n", lwpid_of (lwp));
 
       if (!lwp->stopped)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "stopping LWP %ld\n", lwpid_of (lwp));
+	    debug_printf ("stopping LWP %ld\n", lwpid_of (lwp));
 
 	  /* Stop the thread, and wait for the event asynchronously,
 	     through the event loop.  */
@@ -3676,8 +3690,8 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "already stopped LWP %ld\n",
-		     lwpid_of (lwp));
+	    debug_printf ("already stopped LWP %ld\n",
+			  lwpid_of (lwp));
 
 	  /* The LWP may have been stopped in an internal event that
 	     was not meant to be notified back to GDB (e.g., gdbserver
@@ -3719,7 +3733,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (!leave_pending)
     {
       if (debug_threads)
-	fprintf (stderr, "resuming LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resuming LWP %ld\n", lwpid_of (lwp));
 
       step = (lwp->resume->kind == resume_step);
       linux_resume_one_lwp (lwp, step, lwp->resume->sig, NULL);
@@ -3727,7 +3741,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "leaving LWP %ld stopped\n", lwpid_of (lwp));
+	debug_printf ("leaving LWP %ld stopped\n", lwpid_of (lwp));
 
       /* If we have a new signal, enqueue the signal.  */
       if (lwp->resume->sig != 0)
@@ -3764,6 +3778,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   int any_pending;
   int leave_all_stopped;
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("linux_resume:\n");
+    }
+
   find_inferior (&all_threads, linux_set_resume_request, &array);
 
   /* If there is a thread which would otherwise be resumed, which has
@@ -3792,13 +3812,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   if (debug_threads)
     {
       if (need_step_over != NULL)
-	fprintf (stderr, "Not resuming all, need step over\n");
+	debug_printf ("Not resuming all, need step over\n");
       else if (any_pending)
-	fprintf (stderr,
-		 "Not resuming, all-stop and found "
-		 "an LWP with pending status\n");
+	debug_printf ("Not resuming, all-stop and found "
+		      "an LWP with pending status\n");
       else
-	fprintf (stderr, "Resuming, no pending status or step over needed\n");
+	debug_printf ("Resuming, no pending status or step over needed\n");
     }
 
   /* Even if we're leaving threads stopped, queue all signals we'd
@@ -3807,6 +3826,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
 
   if (need_step_over)
     start_step_over (need_step_over);
+
+  if (debug_threads)
+    {
+      debug_printf ("linux_resume done\n");
+      debug_exit ();
+    }
 }
 
 /* This function is called once per thread.  We check the thread's
@@ -3829,13 +3854,12 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
+    debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
 
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld already running\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld already running\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3845,16 +3869,16 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
       && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
     {
       if (debug_threads)
-	fprintf (stderr, "   client wants LWP to remain %ld stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   client wants LWP to remain %ld stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld has pending status, leaving stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   LWP %ld has pending status, leaving stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3863,7 +3887,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld is suspended\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld is suspended\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3882,10 +3906,9 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
 	 pending, this is a no-op.  */
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Client wants LWP %ld to stop. "
-		 "Making sure it has a SIGSTOP pending\n",
-		 lwpid_of (lwp));
+	debug_printf ("Client wants LWP %ld to stop. "
+		      "Making sure it has a SIGSTOP pending\n",
+		      lwpid_of (lwp));
 
       send_sigstop (lwp);
     }
@@ -3932,9 +3955,9 @@ proceed_all_lwps (void)
       if (need_step_over != NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "proceed_all_lwps: found "
-		     "thread %ld needing a step-over\n",
-		     lwpid_of (need_step_over));
+	    debug_printf ("proceed_all_lwps: found "
+			  "thread %ld needing a step-over\n",
+			  lwpid_of (need_step_over));
 
 	  start_step_over (need_step_over);
 	  return;
@@ -3942,7 +3965,7 @@ proceed_all_lwps (void)
     }
 
   if (debug_threads)
-    fprintf (stderr, "Proceeding, no step-over needed\n");
+    debug_printf ("Proceeding, no step-over needed\n");
 
   find_inferior (&all_lwps, proceed_one_lwp, NULL);
 }
@@ -3956,18 +3979,24 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
 {
   if (debug_threads)
     {
+      debug_enter ();
       if (except)
-	fprintf (stderr,
-		 "unstopping all lwps, except=(LWP %ld)\n", lwpid_of (except));
+	debug_printf ("unstopping all lwps, except=(LWP %ld)\n",
+		      lwpid_of (except));
       else
-	fprintf (stderr,
-		 "unstopping all lwps\n");
+	debug_printf ("unstopping all lwps\n");
     }
 
   if (unsuspend)
     find_inferior (&all_lwps, unsuspend_and_proceed_one_lwp, except);
   else
     find_inferior (&all_lwps, proceed_one_lwp, except);
+
+  if (debug_threads)
+    {
+      debug_printf ("unstop_all_lwps done\n");
+      debug_exit ();
+    }
 }
 
 
@@ -4533,8 +4562,8 @@ linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 	val = val & 0xffff;
       else if (len == 3)
 	val = val & 0xffffff;
-      fprintf (stderr, "Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
-	       val, (long)memaddr);
+      debug_printf ("Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
+		    val, (long)memaddr);
     }
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
@@ -4777,9 +4806,9 @@ linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
   pid = lwpid_of (get_thread_lwp (current_inferior));
 
   if (debug_threads)
-    fprintf (stderr, "%s siginfo for lwp %d.\n",
-	     readbuf != NULL ? "Reading" : "Writing",
-	     pid);
+    debug_printf ("%s siginfo for lwp %d.\n",
+		  readbuf != NULL ? "Reading" : "Writing",
+		  pid);
 
   if (offset >= sizeof (siginfo))
     return -1;
@@ -4851,8 +4880,8 @@ linux_async (int enable)
   int previous = (linux_event_pipe[0] != -1);
 
   if (debug_threads)
-    fprintf (stderr, "linux_async (%d), previous=%d\n",
-	     enable, previous);
+    debug_printf ("linux_async (%d), previous=%d\n",
+		  enable, previous);
 
   if (previous != enable)
     {
diff --git a/gdb/gdbserver/linux-m32r-low.c b/gdb/gdbserver/linux-m32r-low.c
index e208523..477e185 100644
--- a/gdb/gdbserver/linux-m32r-low.c
+++ b/gdb/gdbserver/linux-m32r-low.c
@@ -59,7 +59,7 @@ m32r_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-sparc-low.c b/gdb/gdbserver/linux-sparc-low.c
index fcffe05..75c97dd 100644
--- a/gdb/gdbserver/linux-sparc-low.c
+++ b/gdb/gdbserver/linux-sparc-low.c
@@ -231,7 +231,7 @@ sparc_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 04fa3c9..b141c2b 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -2022,8 +2022,8 @@ add_insns (unsigned char *start, int len)
   CORE_ADDR buildaddr = current_insn_ptr;
 
   if (debug_threads)
-    fprintf (stderr, "Adding %d bytes of insn at %s\n",
-	     len, paddress (buildaddr));
+    debug_printf ("Adding %d bytes of insn at %s\n",
+		  len, paddress (buildaddr));
 
   append_insns (&buildaddr, len, start);
   current_insn_ptr = buildaddr;
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index fd706e9..b77ce10 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -197,10 +197,9 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -211,9 +210,8 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -334,10 +332,9 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert fast tracepoint jump "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert fast tracepoint jump "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -398,10 +395,9 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " fast tracepoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " fast tracepoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (jp);
       return NULL;
     }
@@ -424,9 +420,8 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert fast tracepoint jump at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
 
       /* Unlink it.  */
       proc->fast_tracepoint_jumps = jp->next;
@@ -450,10 +445,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -480,9 +474,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
 	  jp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert fast tracepoint jump at 0x%s (%s).\n",
-		     paddress (pc), strerror (err));
+	    debug_printf ("Failed to uninsert fast tracepoint jump at"
+			  " 0x%s (%s).\n",
+			  paddress (pc), strerror (err));
 	}
     }
 }
@@ -500,10 +494,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       /* This can happen when we remove breakpoints when a tracepoint
 	 hit causes a tracing stop, while handling a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (where));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (where));
       return;
     }
 
@@ -528,9 +521,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       jp->inserted = 0;
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to reinsert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to reinsert fast tracepoint jump at"
+		      " 0x%s (%s).\n",
+		      paddress (where), strerror (err));
     }
 }
 
@@ -598,10 +591,9 @@ delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert raw breakpoint "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert raw breakpoint "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -932,9 +924,9 @@ gdb_no_commands_at_breakpoint (CORE_ADDR where)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr, "at 0x%s, bp command_list is 0x%s\n",
-	     paddress (where),
-	     phex_nz ((uintptr_t) bp->command_list, 0));
+    debug_printf ("at 0x%s, bp command_list is 0x%s\n",
+		  paddress (where),
+		  phex_nz ((uintptr_t) bp->command_list, 0));
   return (bp->command_list == NULL);
 }
 
@@ -1034,9 +1026,8 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
 	  bp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
-		     paddress (bp->pc), strerror (err));
+	    debug_printf ("Failed to uninsert raw breakpoint at 0x%s (%s).\n",
+			  paddress (bp->pc), strerror (err));
 	}
     }
 }
@@ -1052,10 +1043,9 @@ uninsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find breakpoint at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find breakpoint at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -1087,9 +1077,8 @@ reinsert_raw_breakpoint (struct raw_breakpoint *bp)
   if (err == 0)
     bp->inserted = 1;
   else if (debug_threads)
-    fprintf (stderr,
-	     "Failed to reinsert breakpoint at 0x%s (%s).\n",
-	     paddress (bp->pc), strerror (err));
+    debug_printf ("Failed to reinsert breakpoint at 0x%s (%s).\n",
+		  paddress (bp->pc), strerror (err));
 }
 
 void
@@ -1103,10 +1092,9 @@ reinsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find raw breakpoint at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find raw breakpoint at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (pc));
       return;
     }
 
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 75ace6e..3b88995 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -161,7 +161,7 @@ handle_accept_event (int err, gdb_client_data client_data)
   socklen_t tmp;
 
   if (debug_threads)
-    fprintf (stderr, "handling possible accept event\n");
+    debug_printf ("handling possible accept event\n");
 
   tmp = sizeof (sockaddr);
   remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
@@ -1315,8 +1315,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
 		      struct target_waitstatus *status)
 {
   if (debug_threads)
-    fprintf (stderr, "Writing resume reply for %s:%d\n",
-	     target_pid_to_str (ptid), status->kind);
+    debug_printf ("Writing resume reply for %s:%d\n",
+		  target_pid_to_str (ptid), status->kind);
 
   switch (status->kind)
     {
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 28ea048..8b999eb 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -26,6 +26,7 @@
 #if HAVE_SIGNAL_H
 #include <signal.h>
 #endif
+#include "gdb_vecs.h"
 #include "gdb_wait.h"
 #include "btrace-common.h"
 #include "filestuff.h"
@@ -70,6 +71,9 @@ static char **program_argv, **wrapper_argv;
    was originally used to debug LinuxThreads support.  */
 int debug_threads;
 
+/* Include timestamps in debugging output.  */
+int debug_timestamp;
+
 /* Enable debugging of h/w breakpoint/watchpoint support.  */
 int debug_hw_points;
 
@@ -222,8 +226,8 @@ start_inferior (char **argv)
     {
       int i;
       for (i = 0; new_argv[i]; ++i)
-	fprintf (stderr, "new_argv[%d] = \"%s\"\n", i, new_argv[i]);
-      fflush (stderr);
+	debug_printf ("new_argv[%d] = \"%s\"\n", i, new_argv[i]);
+      debug_flush ();
     }
 
 #ifdef SIGTTOU
@@ -2535,10 +2539,9 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
 	      char *status_string
 		= target_waitstatus_to_string (&thread->last_status);
 
-	      fprintf (stderr,
-		       "Reporting thread %s as already stopped with %s\n",
-		       target_pid_to_str (entry->id),
-		       status_string);
+	      debug_printf ("Reporting thread %s as already stopped with %s\n",
+			    target_pid_to_str (entry->id),
+			    status_string);
 
 	      xfree (status_string);
 	    }
@@ -2710,6 +2713,43 @@ handle_status (char *own_buf)
     }
 }
 
+/* Parse options to --debug.
+   ARG is either "--debug" or "--debug=foo".
+   The result is zero if all options were parsed ok, otherwise
+   (e.g., an option is misspelled) an error message is printed and
+   non-zero is returned .  */
+
+static int
+parse_debug_options (const char *arg)
+{
+  VEC (char_ptr) *options;
+  int ix;
+  char *option;
+
+  /* This is always implicit.  */
+  debug_threads = 1;
+
+  if (strcmp (arg, "--debug") == 0)
+    return 0;
+  gdb_assert (strncmp (arg, "--debug=", sizeof ("--debug=") - 1) == 0);
+
+  options = delim_string_to_char_ptr_vec (arg + sizeof ("--debug=") - 1, ',');
+
+  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
+    {
+      if (strcmp (option, "timestamp") == 0)
+	debug_timestamp = 1;
+      else
+	{
+	  fprintf (stderr, "Unknown --debug argument: \"%s\"\n", option);
+	  return 1;
+	}
+    }
+
+  free_char_ptr_vec (options);
+  return 0;
+}
+
 static void
 gdbserver_version (void)
 {
@@ -2732,7 +2772,11 @@ gdbserver_usage (FILE *stream)
 	   "HOST:PORT to listen for a TCP connection.\n"
 	   "\n"
 	   "Options:\n"
+#ifdef HAVE_GETTIMEOFDAY
+	   "  --debug[=timestamp]   Enable general debugging output.\n"
+#else
 	   "  --debug               Enable general debugging output.\n"
+#endif
 	   "  --remote-debug        Enable remote protocol debugging output.\n"
 	   "  --version             Display version information and exit.\n"
 	   "  --wrapper WRAPPER --  Run WRAPPER to start new programs.\n"
@@ -2907,7 +2951,12 @@ main (int argc, char *argv[])
 	  *next_arg = NULL;
 	}
       else if (strcmp (*next_arg, "--debug") == 0)
-	debug_threads = 1;
+	parse_debug_options (*next_arg);
+      else if (strncmp (*next_arg, "--debug=", sizeof ("--debug=") - 1) == 0)
+	{
+	  if (parse_debug_options (*next_arg) != 0)
+	    exit (1);
+	}
       else if (strcmp (*next_arg, "--remote-debug") == 0)
 	remote_debug = 1;
       else if (strcmp (*next_arg, "--disable-packet") == 0)
@@ -3204,14 +3253,14 @@ process_point_options (CORE_ADDR point_addr, char **packet)
 	{
 	  /* Conditional expression.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint condition.\n");
+	    debug_printf ("Found breakpoint condition.\n");
 	  add_breakpoint_condition (point_addr, &dataptr);
 	}
       else if (strncmp (dataptr, "cmds:", strlen ("cmds:")) == 0)
 	{
 	  dataptr += strlen ("cmds:");
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint commands %s.\n", dataptr);
+	    debug_printf ("Found breakpoint commands %s.\n", dataptr);
 	  persist = (*dataptr == '1');
 	  dataptr += 2;
 	  add_breakpoint_commands (point_addr, &dataptr, persist);
@@ -3316,7 +3365,7 @@ process_serial_event (void)
 	  if (!non_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "Forcing non-stop mode\n");
+		debug_printf ("Forcing non-stop mode\n");
 
 	      non_stop = 1;
 	      start_non_stop (1);
@@ -3709,7 +3758,7 @@ int
 handle_serial_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible serial event\n");
+    debug_printf ("handling possible serial event\n");
 
   /* Really handle it.  */
   if (process_serial_event () < 0)
@@ -3728,7 +3777,7 @@ int
 handle_target_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible target event\n");
+    debug_printf ("handling possible target event\n");
 
   last_ptid = mywait (minus_one_ptid, &last_status,
 		      TARGET_WNOHANG, 1);
@@ -3770,10 +3819,10 @@ handle_target_event (int err, gdb_client_data client_data)
 	      struct thread_resume resume_info;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "GDB not connected; forwarding event %d for [%s]\n",
-			 (int) last_status.kind,
-			 target_pid_to_str (last_ptid));
+		debug_printf ("GDB not connected; forwarding event %d for"
+			      " [%s]\n",
+			      (int) last_status.kind,
+			      target_pid_to_str (last_ptid));
 
 	      resume_info.thread = last_ptid;
 	      resume_info.kind = resume_continue;
@@ -3781,9 +3830,9 @@ handle_target_event (int err, gdb_client_data client_data)
 	      (*the_target->resume) (&resume_info, 1);
 	    }
 	  else if (debug_threads)
-	    fprintf (stderr, "GDB not connected; ignoring event %d for [%s]\n",
-		     (int) last_status.kind,
-		     target_pid_to_str (last_ptid));
+	    debug_printf ("GDB not connected; ignoring event %d for [%s]\n",
+			  (int) last_status.kind,
+			  target_pid_to_str (last_ptid));
 	}
       else
 	{
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index d82556a..6eb1a16 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -110,7 +110,6 @@ extern ptid_t cont_thread;
 extern ptid_t general_thread;
 
 extern int server_waiting;
-extern int debug_threads;
 extern int debug_hw_points;
 extern int pass_signals[];
 extern int program_signals[];
@@ -146,6 +145,7 @@ extern int handle_target_event (int err, gdb_client_data client_data);
 
 #include "common-utils.h"
 #include "utils.h"
+#include "debug.h"
 
 #include "gdb_assert.h"
 
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 8b8f6ce..df06b9d 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -194,7 +194,7 @@ thread_db_create_event (CORE_ADDR where)
     fatal ("unexpected thread_db->td_ta_event_getmsg_p == NULL");
 
   if (debug_threads)
-    fprintf (stderr, "Thread creation event.\n");
+    debug_printf ("Thread creation event.\n");
 
   /* FIXME: This assumes we don't get another event.
      In the LinuxThreads implementation, this is safe,
@@ -289,8 +289,8 @@ find_one_thread (ptid_t ptid)
 	   lwpid, thread_db_err_str (err));
 
   if (debug_threads)
-    fprintf (stderr, "Found thread %ld (LWP %d)\n",
-	     ti.ti_tid, ti.ti_lid);
+    debug_printf ("Found thread %ld (LWP %d)\n",
+		  ti.ti_tid, ti.ti_lid);
 
   if (lwpid != ti.ti_lid)
     {
@@ -326,8 +326,8 @@ attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
   struct lwp_info *lwp;
 
   if (debug_threads)
-    fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
-	     ti_p->ti_tid, ti_p->ti_lid);
+    debug_printf ("Attaching to thread %ld (LWP %d)\n",
+		  ti_p->ti_tid, ti_p->ti_lid);
   linux_attach_lwp (ti_p->ti_lid);
   lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
   if (lwp == NULL)
@@ -432,8 +432,8 @@ thread_db_find_new_threads (void)
 					 TD_THR_LOWEST_PRIORITY,
 					 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
       if (debug_threads)
-	fprintf (stderr, "Found %d threads in iteration %d.\n",
-		 new_thread_count, iteration);
+	debug_printf ("Found %d threads in iteration %d.\n",
+		      new_thread_count, iteration);
 
       if (new_thread_count != 0)
 	{
@@ -546,7 +546,7 @@ thread_db_load_search (void)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -595,7 +595,7 @@ try_thread_db_load_1 (void *handle)
       if ((a) == NULL)						\
 	{							\
 	  if (debug_threads)					\
-	    fprintf (stderr, "dlsym: %s\n", dlerror ());	\
+	    debug_printf ("dlsym: %s\n", dlerror ());		\
 	  if (required)						\
 	    {							\
 	      free (tdb);					\
@@ -613,7 +613,7 @@ try_thread_db_load_1 (void *handle)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -663,13 +663,13 @@ try_thread_db_load (const char *library)
   void *handle;
 
   if (debug_threads)
-    fprintf (stderr, "Trying host libthread_db library: %s.\n",
-	     library);
+    debug_printf ("Trying host libthread_db library: %s.\n",
+		  library);
   handle = dlopen (library, RTLD_NOW);
   if (handle == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "dlopen failed: %s.\n", dlerror ());
+	debug_printf ("dlopen failed: %s.\n", dlerror ());
       return 0;
     }
 
@@ -786,7 +786,7 @@ thread_db_load_search (void)
 
   free_char_ptr_vec (dir_vec);
   if (debug_threads)
-    fprintf (stderr, "thread_db_load_search returning %d\n", rc);
+    debug_printf ("thread_db_load_search returning %d\n", rc);
   return rc;
 }
 
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 13b3ff6..3706577 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -61,6 +61,8 @@
 
 */
 
+#ifdef IN_PROCESS_AGENT
+
 static void trace_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 static void
@@ -81,6 +83,19 @@ trace_vdebug (const char *fmt, ...)
       trace_vdebug ((fmt), ##args);		\
   } while (0)
 
+#else
+
+#define trace_debug_1(level, fmt, args...)	\
+  do {						\
+    if (level <= debug_threads)			\
+      {						\
+	debug_printf ((fmt), ##args);		\
+	debug_printf ("\n");			\
+      }						\
+  } while (0)
+
+#endif
+
 #define trace_debug(FMT, args...)		\
   trace_debug_1 (1, FMT, ##args)
 
@@ -338,7 +353,7 @@ tracepoint_look_up_symbols (void)
       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name);
+	    debug_printf ("symbol `%s' not found\n", symbol_list[i].name);
 	  return;
 	}
     }

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 19:01       ` Doug Evans
@ 2014-01-17  2:32         ` Joel Brobecker
  2014-01-17  2:40         ` Joel Brobecker
                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 26+ messages in thread
From: Joel Brobecker @ 2014-01-17  2:32 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, Pedro Alves, gdb-patches

> All of the above.
> I can use it for measuring performance, debugging(!) performance
> issues, and debugging in general.

FWIW, I've often used timetimes to try to narrow down where
time is spent. Sometimes, global performance measurements
such as hot spots, etc, can be a little skewed with code
that we didn't want to analyze. Or I've also worked on platforms
where performance analysis tools are not available. So I used
the poor man's performance tool, timestamped traces.

-- 
Joel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 19:01       ` Doug Evans
  2014-01-17  2:32         ` Joel Brobecker
@ 2014-01-17  2:40         ` Joel Brobecker
  2014-01-17 12:46         ` Pedro Alves
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 26+ messages in thread
From: Joel Brobecker @ 2014-01-17  2:40 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, Pedro Alves, gdb-patches

> >>    if (debug_threads)
> >> -    fprintf (stderr, "stop pc is %08lx\n", pc);
> >> +    debug_printf ("stop pc is %08lx\n", pc);
> >>    return pc;
> >
> > IWBN to move "if (debug_threads)" into debug_printf too.
> 
> I thought of that, but there are times when you want to check
> debug_threads before calling debug_printf.

I used to think the same way as Yao. But I think the pattern that
has been followed pretty consistently is the one above. I've seen
also emails or articles (I can't remember which), which justify
the use of the current pattern. From memory, you're saving a function
call, the string formatting, and also, if you need to call functions
with side-effects, you're saving that too. It doesn't sound like
it is all such a big problem, but I think it's significant enough
that we want to continue with our currently established pattern.

Some units have dealt with that issue by defining a macro expanding
to "if (debug_[...]) call_debug_trace_fun ([...]);".

As Doug suggested, maybe for a followup patch, for those interested.

-- 
Joel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-16 23:37             ` [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch Doug Evans
@ 2014-01-17  2:58               ` Doug Evans
  2014-01-17  7:04               ` Eli Zaretskii
  2014-01-17 12:46               ` Pedro Alves
  2 siblings, 0 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-17  2:58 UTC (permalink / raw)
  To: Pedro Alves, Yao Qi, Eli Zaretskii; +Cc: gdb-patches

On Thu, Jan 16, 2014 at 3:37 PM, Doug Evans <dje@google.com> wrote:
> [...]
> @@ -2710,6 +2713,43 @@ handle_status (char *own_buf)
>      }
>  }
>
> +/* Parse options to --debug.
> +   ARG is either "--debug" or "--debug=foo".
> +   The result is zero if all options were parsed ok, otherwise
> +   (e.g., an option is misspelled) an error message is printed and
> +   non-zero is returned .  */
> +
> +static int
> +parse_debug_options (const char *arg)
> +{
> +  VEC (char_ptr) *options;
> +  int ix;
> +  char *option;
> +
> +  /* This is always implicit.  */
> +  debug_threads = 1;
> +
> +  if (strcmp (arg, "--debug") == 0)
> +    return 0;
> +  gdb_assert (strncmp (arg, "--debug=", sizeof ("--debug=") - 1) == 0);
> +
> +  options = delim_string_to_char_ptr_vec (arg + sizeof ("--debug=") - 1, ',');
> +
> +  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
> +    {
> +      if (strcmp (option, "timestamp") == 0)
> +       debug_timestamp = 1;
> +      else
> +       {
> +         fprintf (stderr, "Unknown --debug argument: \"%s\"\n", option);
> +         return 1;
> +       }
> +    }
> +
> +  free_char_ptr_vec (options);
> +  return 0;
> +}

Blech, something's been nagging at me and sure enough ...
Silly memory leak (harmless, but still ...).
Will be fixed for checkin.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-16 23:37             ` [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch Doug Evans
  2014-01-17  2:58               ` Doug Evans
@ 2014-01-17  7:04               ` Eli Zaretskii
  2014-01-17 12:46               ` Pedro Alves
  2 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2014-01-17  7:04 UTC (permalink / raw)
  To: Doug Evans; +Cc: palves, yao, gdb-patches

> From: Doug Evans <dje@google.com>
> Date: Thu, 16 Jan 2014 15:37:13 -0800
> cc: gdb-patches <gdb-patches@sourceware.org>
> 
> Doug Evans writes:
>  > v2 is now split into three parts:
>  > 
>  > 1/3 - move ASSERT_FUNCTION to FUNCTION_NAME in common-utils.h
>  > 2/3 - create new function delim_string_to_char_ptr_vec_append in gdb_vecs.c
>  > 3/3 - the actual debug_printf patch
>  > 
>  > I went with --debug[=timestamp] as the option naming.

Thanks.

> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -3,6 +3,11 @@
>  
>  *** Changes since GDB 7.7
>  
> +* New features in the GDB remote stub, GDBserver
> +
> +  ** GDBserver now takes an optional argument to --debug, --debug=timestamp,
> +     that adds a timestamp with each debugging message.
             ^^^^^^^^^^^^^^^^^^^^^
Either "adds to" or "prints with" or "includes with".

The documentation parts are OK with that change.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] gdbserver debug_printf+timestamps: FUNCTION_NAME
  2014-01-16 23:31             ` [PATCH 1/3] gdbserver debug_printf+timestamps: FUNCTION_NAME Doug Evans
@ 2014-01-17 12:46               ` Pedro Alves
  0 siblings, 0 replies; 26+ messages in thread
From: Pedro Alves @ 2014-01-17 12:46 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, gdb-patches

On 01/16/2014 11:31 PM, Doug Evans wrote:
> Doug Evans writes:
>  > v2 is now split into three parts:
>  > 
>  > 1/3 - move ASSERT_FUNCTION to FUNCTION_NAME in common-utils.h
>  > 2/3 - create new function delim_string_to_char_ptr_vec_append in gdb_vecs.c
>  > 3/3 - the actual debug_printf patch
>  > 
>  > I went with --debug[=timestamp] as the option naming.
> 
> I didn't do a darwin build but the change is mechanical.
> 
> 2014-01-16  Doug Evans  <dje@google.com>
> 
> 	* common/common-utils.h (FUNCTION_NAME): Renamed from ASSERT_FUNCTION,
> 	and moved here ...
> 	* common/gdb_assert.h (ASSERT_FUNCTION): ... from here.
> 	#include "common-utils.h".
> 	(gdb_assert, gdb_assert_fail, gdb_assert_not_reached): Update.
> 	* common/vec.h (VEC_ASSERT_PASS): Update.
> 	* darwin-nat.h: Replace #include of gdb_assert.h with common-utils.h.
> 	(MACH_CHECK_ERROR): Update.

Looks good to me.

Thanks,
-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 19:01       ` Doug Evans
  2014-01-17  2:32         ` Joel Brobecker
  2014-01-17  2:40         ` Joel Brobecker
@ 2014-01-17 12:46         ` Pedro Alves
  2014-01-17 12:59         ` Yao Qi
  2014-01-20  5:42         ` Tom Tromey
  4 siblings, 0 replies; 26+ messages in thread
From: Pedro Alves @ 2014-01-17 12:46 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, gdb-patches

On 01/16/2014 07:01 PM, Doug Evans wrote:
>> >
>> > utils.c is compiled to both gdbserver and ipa.  IMO,
>> > ipa code should be thread-safe, because it can be used by a
>> > multi-threaded program.
> That would argue for removing the indentation support, at least for now.
> Fine by me.
>
> OTOH, it seemed like ipa code has its own debug printf'ing so it can
> prepend PROG, so I'm not sure this is necessary.

It's more a per-module thing, than a per-program thing.  E.g., ax.c.
Certainly PROG handling could (or perhaps should even?) be moved
to debug_printf.  (And ax_debug made a client of debug_printf).

> OTOOH, it'd be less preferable to assume(!) ipa code would never call
> debug_printf.

Yeah.

> Thoughts?

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-16 23:37             ` [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch Doug Evans
  2014-01-17  2:58               ` Doug Evans
  2014-01-17  7:04               ` Eli Zaretskii
@ 2014-01-17 12:46               ` Pedro Alves
  2014-01-17 22:45                 ` Doug Evans
  2 siblings, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2014-01-17 12:46 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, eliz, gdb-patches

On 01/16/2014 11:37 PM, Doug Evans wrote:
> +++ b/gdb/gdbserver/debug.c
> @@ -0,0 +1,86 @@
> +/* General utility routines for the remote server for GDB.

These ...

> +++ b/gdb/gdbserver/debug.h
> @@ -0,0 +1,48 @@
> +/* General utility routines for the remote server for GDB.

... need updating.

> +#endif /* UTILS_H */

This too -- DEBUG_H.

> +debug_printf (const char *msg, ...)
> +{
> +  va_list args;
> +#ifdef HAVE_GETTIMEOFDAY
> +  static int new_line = 1;
> +

Note this isn't thread safe either.  Maybe add a comment
in case we ever try to make timespamping work in the IPA?

> +  options = delim_string_to_char_ptr_vec (arg + sizeof ("--debug=") - 1, ',');
> +
> +  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
> +    {

I don't see much point in this extra copying over plain old strtok
(already used in the --disable-packet= code), but OK...

>        else if (strcmp (*next_arg, "--debug") == 0)
> -	debug_threads = 1;
> +	parse_debug_options (*next_arg);
> +      else if (strncmp (*next_arg, "--debug=", sizeof ("--debug=") - 1) == 0)
> +	{
> +	  if (parse_debug_options (*next_arg) != 0)
> +	    exit (1);
> +	}

This should be hooked in "monitor set debug ..." as well.

Otherwise looks good to me.

Thanks,
-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 19:01       ` Doug Evans
                           ` (2 preceding siblings ...)
  2014-01-17 12:46         ` Pedro Alves
@ 2014-01-17 12:59         ` Yao Qi
  2014-01-20  5:42         ` Tom Tromey
  4 siblings, 0 replies; 26+ messages in thread
From: Yao Qi @ 2014-01-17 12:59 UTC (permalink / raw)
  To: Doug Evans; +Cc: Pedro Alves, gdb-patches

On 01/17/2014 03:01 AM, Doug Evans wrote:
> Left for another day.
> There's no loss in splitting this up into steps.
> [The next step will itself need to be spit up into several steps: get
> gettimeofday from gnulib, and then have gdbserver (and gdb) use it -
> it may be a nop for gdb, say gnulib being preferred over libiberty,
> but something to be confirmed nonetheless.]
> 

I thought gettimeofday module has been imported, but it wasn't.  Then,
we can import it in next step.

>>> >> diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
>>> >> index 1b0da6c..e7d3e4f 100644
>>> >> --- a/gdb/gdbserver/linux-aarch64-low.c
>>> >> +++ b/gdb/gdbserver/linux-aarch64-low.c
>>> >> @@ -323,7 +323,7 @@ aarch64_get_pc (struct regcache *regcache)
>>> >>
>>> >>    collect_register_by_name (regcache, "pc", &pc);
>>> >>    if (debug_threads)
>>> >> -    fprintf (stderr, "stop pc is %08lx\n", pc);
>>> >> +    debug_printf ("stop pc is %08lx\n", pc);
>>> >>    return pc;
>> >
>> > IWBN to move "if (debug_threads)" into debug_printf too.
> I thought of that, but there are times when you want to check
> debug_threads before calling debug_printf.
> So then it's a case of some code checking debug_threads and some not,
> and then how often will cut-n-paste hacking proliferate unnecessary
> tests of debug_printf.  Another alternative is of course to call a
> different function that does the check, but now we have two debug
> printf functions instead of one.
> 
> btw, One thought I have is to make debug_printf a macro (or create
> DEBUG_PRINTF or use a different name) so that adding FUNCTION_NAME
> becomes automagic.  OTOH, I'm not sure always including the function
> name will be a net win - it could be, guess it might depend on
> personal preference (--debug=timestamp,funcname ? :-)).
> 
> If people really want debug_threads tests in debug_printf (which is
> fine by me), that can be left for another day too.
> It is arguably a separate step since it's an additional change on top
> of replacing fprintf (stderr, ...) with debug_printf.
> 

FAOD, current pattern ("if (debug_threads) debug_printf ()") works fine
by me.  It has been good enough, IMO.

>>> >> diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
>>> >> index eff4499..1ce5512 100644
>>> >> --- a/gdb/gdbserver/utils.c
>>> >> +++ b/gdb/gdbserver/utils.c
>>> >> @@ -17,6 +17,7 @@
>> >
>>> >> +
>>> >> +/* Increase or decrease the debug printf call nesting level.
>>> >> +   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
>>> >> +   Call this when entering major routines that can trigger a lot of debug
>>> >> +   output before it exits.  It allows the reader to associate subsequent
>>> >> +   debug output to the call that ultimately triggered it.  */
>>> >> +
>>> >> +void
>>> >> +debug_level_incr (int incr, const char *function_name)
>>> >> +{
>>> >> +  gdb_assert (incr == 1 || incr == -1);
>>> >> +
>>> >> +  /* Increment(/decrement) the level by one before printing the function name,
>>> >> +     to distinguish this as an entry(/exit) point.
>>> >> +     Then increment(/decrement) it again so that debugging printfs within
>>> >> +     the function are recognized as such.  */
>>> >> +  if (function_name != NULL)
>>> >> +    {
>>> >> +      debug_nesting_level += incr;
>>> >> +      debug_printf ("%s %s\n",
>>> >> +                 incr > 0 ? ">>>>entering" : "<<<<exiting",
>>> >> +                 function_name);
>>> >> +    }
>>> >> +  debug_nesting_level += incr;
>>> >> +
>>> >> +  /* Don't crash on mismatched enter/exit, but still inform the user.  */
>>> >> +  if (debug_nesting_level < 0)
>>> >> +    {
>>> >> +      debug_printf ("ERROR: mismatch in debug_level_enter/exit, level < 0\n");
>>> >> +      debug_nesting_level = 0;
>>> >> +    }
>>> >> +}
>>> >> +
>> >
>> > utils.c is compiled to both gdbserver and ipa.  IMO,
>> > ipa code should be thread-safe, because it can be used by a
>> > multi-threaded program.
> That would argue for removing the indentation support, at least for now.
> Fine by me.
> 
> OTOH, it seemed like ipa code has its own debug printf'ing so it can
> prepend PROG, so I'm not sure this is necessary.
> OTOOH, it'd be less preferable to assume(!) ipa code would never call
> debug_printf.

debug_printf doesn't have any issues used in ipa, but debug_level_incr
has.  Probably we can use "#ifndef IN_PROCESS_AGENT" to guarantee
debug_level stuffs can't be used in ipa.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-17 12:46               ` Pedro Alves
@ 2014-01-17 22:45                 ` Doug Evans
  2014-01-18  8:25                   ` Eli Zaretskii
  2014-01-20 16:14                   ` Pedro Alves
  0 siblings, 2 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-17 22:45 UTC (permalink / raw)
  To: Pedro Alves, Yao Qi, eliz; +Cc: gdb-patches

Pedro Alves writes:
 > On 01/16/2014 11:37 PM, Doug Evans wrote:
 > > +++ b/gdb/gdbserver/debug.c
 > > @@ -0,0 +1,86 @@
 > > +/* General utility routines for the remote server for GDB.
 > 
 > These ...
 > 
 > > +++ b/gdb/gdbserver/debug.h
 > > @@ -0,0 +1,48 @@
 > > +/* General utility routines for the remote server for GDB.
 > 
 > ... need updating.
 > 
 > > +#endif /* UTILS_H */
 > 
 > This too -- DEBUG_H.
 > 
 > > +debug_printf (const char *msg, ...)
 > > +{
 > > +  va_list args;
 > > +#ifdef HAVE_GETTIMEOFDAY
 > > +  static int new_line = 1;
 > > +
 > 
 > Note this isn't thread safe either.  Maybe add a comment
 > in case we ever try to make timespamping work in the IPA?
 > 
 > > +  options = delim_string_to_char_ptr_vec (arg + sizeof ("--debug=") - 1, ',');
 > > +
 > > +  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
 > > +    {
 > 
 > I don't see much point in this extra copying over plain old strtok
 > (already used in the --disable-packet= code), but OK...
 > 
 > >        else if (strcmp (*next_arg, "--debug") == 0)
 > > -	debug_threads = 1;
 > > +	parse_debug_options (*next_arg);
 > > +      else if (strncmp (*next_arg, "--debug=", sizeof ("--debug=") - 1) == 0)
 > > +	{
 > > +	  if (parse_debug_options (*next_arg) != 0)
 > > +	    exit (1);
 > > +	}
 > 
 > This should be hooked in "monitor set debug ..." as well.
 > 
 > Otherwise looks good to me.

I changed --debug= to --debug-format=, and added monitor commands.

Eli, the docs presumably need a re-review.

I will commit this in a few days if there are no objections.

2014-01-17  Doug Evans  <dje@google.com>

	New gdbserver option --debug-format=timestamp.
	* NEWS: Mention it.

	gdbserver/
	* configure.ac (AC_CHECK_FUNCS): Add test for gettimeofday.
	* configure: Regenerate.
	* config.in: Regenerate.
	* Makefile.in (SFILES): Add debug.c.
	(OBS): Add debug.o.
	* debug.c: New file.
	* debug.h: New file.
	* linux-aarch64-low.c (*): Update all debugging printfs to use
	debug_printf instead of fprintf.
	* linux-arm-low.c (*): Ditto.
	* linux-cris-low.c (*): Ditto.
	* linux-crisv32-low.c (*): Ditto.
	* linux-m32r-low.c (*): Ditto.
	* linux-sparc-low.c (*): Ditto.
	* linux-x86.c (*): Ditto.
	* linux-low.c (*): Ditto.
	(linux_wait_1): Add calls to debug_enter, debug_exit.
	(linux_wait): Remove redundant debugging printf.
	(stop_all_lwps): Add calls to debug_enter, debug_exit.
	(linux_resume, unstop_all_lwps): Ditto.
	* mem-break.c (*): Update all debugging printfs to use
	debug_printf instead of fprintf.
	* remote-utils.c (*): Ditto.
	* thread-db.c (*): Ditto.
	* server.c #include <ctype.h>, "gdb_vecs.h".
	(debug_threads): Moved to debug.c.
	(*): Update all debugging printfs to use debug_printf instead of
	fprintf.
	(start_inferior): Replace call to fflush with call to debug_flush.
	(monitor_show_help): Mention set debug-format.
	(parse_debug_format_options): New function.
	(handle_monitor_command): Handle "monitor set debug-format".
	(gdbserver_usage): Mention --debug-format.
	(main): Parse --debug-format.
	* server.h (debug_threads): Declaration moved to debug.h.
	#include "debug.h".
	* tracepoint.c (trace_debug_1) [!IN_PROCESS_AGENT]: Add version of
	trace_debug_1 that uses debug_printf.
	(tracepoint_look_up_symbols): Update all debugging printfs to use
	debug_printf instead of fprintf.

	doc/
	* gdb.texinfo (Server): Mention --debug-format=all|none|timestamp.
	(gdbserver man): Ditto.

	testsuite/
	* gdb.server/server-mon.exp: Add tests for "set debug-format".

diff --git a/gdb/NEWS b/gdb/NEWS
index 44189d5..f40666d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,14 @@
 
 *** Changes since GDB 7.7
 
+* New features in the GDB remote stub, GDBserver
+
+  ** New option --debug-format=option1[,option2,...] allows one to add
+     additional text to each debugging message.  At present only timestamps
+     are supported: --debug-format=timestamps.
+     Timestamps can also be turned on with the
+     "monitor set debug-format timestamps" command from GDB.
+
 * The 'record instruction-history' command now starts counting instructions
   at one.  This also affects the instruction ranges reported by the
   'record function-call-history' command when given the /i modifier.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e77ca2a..c907c0d 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18517,6 +18517,22 @@ The @option{--remote-debug} option tells @code{gdbserver} to display
 remote protocol debug output.  These options are intended for
 @code{gdbserver} development and for bug reports to the developers.
 
+The @option{--debug-format=option1[,option2,...]} option tells
+@code{gdbserver} to include additional information in each line of
+debugging output.  Possible options are:
+
+@table @code
+@item none
+Turn off all extra information in debugging output.
+@item all
+Turn on all extra information in debugging output.
+@item timestamps
+Include a timestamp in each line of debugging output.
+@end table
+
+Options are processed in order.  Thus, for example, if @option{none}
+appears last then no additional information is added to debugging output.
+
 @cindex @option{--wrapper}, @code{gdbserver} option
 The @option{--wrapper} option specifies a wrapper to launch programs
 for debugging.  The option should be followed by the name of the
@@ -18587,6 +18603,22 @@ Disable or enable general debugging messages.
 Disable or enable specific debugging messages associated with the remote
 protocol (@pxref{Remote Protocol}).
 
+@item monitor set debug-format option1@r{[},option2,...@r{]}
+Specify additional text to add to debugging messages.
+Possible options are:
+
+@table @code
+@item none
+Turn off all extra information in debugging output.
+@item all
+Turn on all extra information in debugging output.
+@item timestamps
+Include a timestamp in each line of debugging output.
+@end table
+
+Options are processed in order.  Thus, for example, if @option{none}
+appears last then no additional information is added to debugging output.
+
 @item monitor set libthread-db-search-path [PATH]
 @cindex gdbserver, search path for @code{libthread_db}
 When this command is issued, @var{path} is a colon-separated list of
@@ -44342,6 +44374,24 @@ Instruct @code{gdbserver} to display remote protocol debug output.
 This option is intended for @code{gdbserver} development and for bug reports to
 the developers.
 
+@item --debug-format=option1@r{[},option2,...@r{]}
+Instruct @code{gdbserver} to include extra information in each line
+of debugging output.
+
+Possible options are:
+
+@table @code
+@item none
+Turn off all extra information in debugging output.
+@item all
+Turn on all extra information in debugging output.
+@item timestamps
+Include a timestamp in each line of debugging output.
+@end table
+
+Options are processed in order.  Thus, for example, if @option{none}
+appears last then no additional information is added to debugging output.
+
 @item --wrapper
 Specify a wrapper to launch programs
 for debugging.  The option should be followed by the name of the
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index e72ee6b..46324e6 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -141,7 +141,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/mem-break.c $(srcdir)/proc-service.c \
 	$(srcdir)/proc-service.list $(srcdir)/regcache.c \
 	$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
-	$(srcdir)/thread-db.c $(srcdir)/utils.c \
+	$(srcdir)/thread-db.c $(srcdir)/utils.c $(srcdir)/debug.c \
 	$(srcdir)/linux-arm-low.c $(srcdir)/linux-bfin-low.c \
 	$(srcdir)/linux-cris-low.c $(srcdir)/linux-crisv32-low.c \
 	${srcdir}/i386-low.c $(srcdir)/i387-fp.c \
@@ -173,7 +173,7 @@ SOURCES = $(SFILES)
 TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
 
 OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \
-      target.o waitstatus.o utils.o version.o vec.o gdb_vecs.o \
+      target.o waitstatus.o utils.o debug.o version.o vec.o gdb_vecs.o \
       mem-break.o hostio.o event-loop.o tracepoint.o xml-utils.o \
       common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \
       tdesc.o $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS)
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index e33cdea..1b9751f 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -66,6 +66,9 @@
 /* Define to 1 if you have the `getrlimit' function. */
 #undef HAVE_GETRLIMIT
 
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index fac7fb3..6d8a6a7 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4728,7 +4728,7 @@ fi
 
 done
 
-for ac_func in pread pwrite pread64 readlink
+for ac_func in gettimeofday pread pwrite pread64 readlink
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index dc8131c..0dfa4a9 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -82,7 +82,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 errno.h fcntl.h signal.h sys/file.h malloc.h dnl
 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
 		 netinet/tcp.h arpa/inet.h)
-AC_CHECK_FUNCS(pread pwrite pread64 readlink)
+AC_CHECK_FUNCS(gettimeofday pread pwrite pread64 readlink)
 AC_REPLACE_FUNCS(vasprintf vsnprintf)
 
 GDB_AC_COMMON
diff --git a/gdb/gdbserver/debug.c b/gdb/gdbserver/debug.c
new file mode 100644
index 0000000..6f4d531
--- /dev/null
+++ b/gdb/gdbserver/debug.c
@@ -0,0 +1,98 @@
+/* Debugging routines for the remote server for GDB.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "server.h"
+#include <sys/time.h>
+
+/* Enable miscellaneous debugging output.  The name is historical - it
+   was originally used to debug LinuxThreads support.  */
+int debug_threads;
+
+/* Include timestamps in debugging output.  */
+int debug_timestamp;
+
+/* Print a debugging message.
+   If the text begins a new line it is preceded by a timestamp, if the
+   system has gettimeofday.
+   We don't get fancy with newline checking, we just check whether the
+   previous call ended with "\n".  */
+
+void
+debug_printf (const char *msg, ...)
+{
+  va_list args;
+#if defined (HAVE_GETTIMEOFDAY) && !defined (IN_PROCESS_AGENT)
+  /* N.B. Not thread safe, and can't be used, as is, with IPA.  */
+  static int new_line = 1;
+
+  if (debug_timestamp && new_line)
+    {
+      struct timeval tm;
+
+      gettimeofday (&tm, NULL);
+
+      /* 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);
+    }
+#endif
+
+  va_start (args, msg);
+  vfprintf (stderr, msg, args);
+  va_end (args);
+
+#if defined (HAVE_GETTIMEOFDAY) && !defined (IN_PROCESS_AGENT)
+  if (*msg)
+    new_line = msg[strlen (msg) - 1] == '\n';
+#endif
+}
+
+/* Flush debugging output.
+   This is called, for example, when starting an inferior to ensure all debug
+   output thus far appears before any inferior output.  */
+
+void
+debug_flush (void)
+{
+  fflush (stderr);
+}
+
+/* Notify the user that the code is entering FUNCTION_NAME.
+   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
+
+   This is intended to be called via the debug_enter macro.  */
+
+void
+do_debug_enter (const char *function_name)
+{
+  if (function_name != NULL)
+    debug_printf (">>>> entering %s\n", function_name);
+}
+
+/* Notify the user that the code is exiting FUNCTION_NAME.
+   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
+
+   This is intended to be called via the debug_exit macro.  */
+
+void
+do_debug_exit (const char *function_name)
+{
+  if (function_name != NULL)
+    debug_printf ("<<<< exiting %s\n", function_name);
+}
diff --git a/gdb/gdbserver/debug.h b/gdb/gdbserver/debug.h
new file mode 100644
index 0000000..0f056ca
--- /dev/null
+++ b/gdb/gdbserver/debug.h
@@ -0,0 +1,55 @@
+/* Debugging routines for the remote server for GDB.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/* We declare debug format variables here, and debug_threads but no other
+   debug content variables (e.g., not remote_debug) because while this file
+   is not currently used by IPA it may be some day, and IPA may have its own
+   set of debug content variables.  It's ok to declare debug_threads here
+   because it is misnamed - a better name is debug_basic or some such,
+   which can work for any program, gdbserver or IPA.  If/when this file is
+   used with IPA it is recommended to fix debug_thread's name.  */
+extern int debug_threads;
+extern int debug_timestamp;
+
+void debug_printf (const char *msg, ...) ATTRIBUTE_PRINTF (1, 2);
+void debug_flush (void);
+void do_debug_enter (const char *function_name);
+void do_debug_exit (const char *function_name);
+
+/* These macros are for use in major functions that produce a lot of
+   debugging output.  They help identify in the mass of debugging output
+   when these functions enter and exit.  debug_enter is intended to be
+   called at the start of a function, before any other debugging output.
+   debug_exit is intended to be called at the end of the same function,
+   after all debugging output.  */
+#ifdef FUNCTION_NAME
+#define debug_enter() \
+  do { do_debug_enter (FUNCTION_NAME); } while (0)
+#define debug_exit() \
+  do { do_debug_exit (FUNCTION_NAME); } while (0)
+#else
+#define debug_enter() \
+  do { } while (0)
+#define debug_exit() \
+  do { } while (0)
+#endif
+
+#endif /* DEBUG_H */
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index 1b0da6c..e7d3e4f 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -323,7 +323,7 @@ aarch64_get_pc (struct regcache *regcache)
 
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index da5085c..fb6ff68 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -256,7 +256,7 @@ arm_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-cris-low.c b/gdb/gdbserver/linux-cris-low.c
index d229d43..2abd987 100644
--- a/gdb/gdbserver/linux-cris-low.c
+++ b/gdb/gdbserver/linux-cris-low.c
@@ -67,7 +67,7 @@ cris_get_pc (struct regcache *regcache, void)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-crisv32-low.c b/gdb/gdbserver/linux-crisv32-low.c
index e4ebb62..a16a656 100644
--- a/gdb/gdbserver/linux-crisv32-low.c
+++ b/gdb/gdbserver/linux-crisv32-low.c
@@ -63,7 +63,7 @@ cris_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 01d0e84..bac6134 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -475,7 +475,7 @@ get_pc (struct lwp_info *lwp)
   pc = (*the_low_target.get_pc) (regcache);
 
   if (debug_threads)
-    fprintf (stderr, "pc is 0x%lx\n", (long) pc);
+    debug_printf ("pc is 0x%lx\n", (long) pc);
 
   current_inferior = saved_inferior;
   return pc;
@@ -520,7 +520,7 @@ get_stop_pc (struct lwp_info *lwp)
     stop_pc -= the_low_target.decr_pc_after_break;
 
   if (debug_threads)
-    fprintf (stderr, "stop pc is 0x%lx\n", (long) stop_pc);
+    debug_printf ("stop pc is 0x%lx\n", (long) stop_pc);
 
   return stop_pc;
 }
@@ -692,8 +692,7 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
   if (linux_proc_pid_is_stopped (lwpid))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Attached to a stopped process\n");
+	debug_printf ("Attached to a stopped process\n");
 
       /* The process is definitely stopped.  It is in a job control
 	 stop, unless the kernel predates the TASK_STOPPED /
@@ -824,8 +823,8 @@ linux_attach (unsigned long pid)
 		      new_threads_found++;
 
 		      if (debug_threads)
-			fprintf (stderr, "\
-Found and attached to new lwp %ld\n", lwp);
+			debug_printf ("Found and attached to new lwp %ld\n",
+				      lwp);
 		    }
 		}
 
@@ -898,18 +897,16 @@ linux_kill_one_lwp (struct lwp_info *lwp)
   errno = 0;
   kill (pid, SIGKILL);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 
   errno = 0;
   ptrace (PTRACE_KILL, pid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 }
 
 /* Callback for `find_inferior'.  Kills an lwp of a given process,
@@ -934,8 +931,8 @@ kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
   if (lwpid_of (lwp) == pid)
     {
       if (debug_threads)
-	fprintf (stderr, "lkop: is last of process %s\n",
-		 target_pid_to_str (entry->id));
+	debug_printf ("lkop: is last of process %s\n",
+		      target_pid_to_str (entry->id));
       return 0;
     }
 
@@ -975,14 +972,14 @@ linux_kill (int pid)
   if (lwp == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: cannot find lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: cannot find lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: killing lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: killing lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
 
       do
 	{
@@ -1031,9 +1028,8 @@ get_detach_signal (struct thread_info *thread)
   if (!WIFSTOPPED (status))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s hasn't stopped: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s hasn't stopped: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1041,10 +1037,9 @@ get_detach_signal (struct thread_info *thread)
   if (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had stopped with extended "
-		 "status: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s had stopped with extended "
+		      "status: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1053,10 +1048,9 @@ get_detach_signal (struct thread_info *thread)
   if (program_signals_p && !program_signals[signo])
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, but it is in nopass state\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else if (!program_signals_p
@@ -1066,20 +1060,19 @@ get_detach_signal (struct thread_info *thread)
 	   && (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, "
-		 "but we don't know if we should pass it.  Default to not.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, "
+		      "but we don't know if we should pass it. "
+		      "Default to not.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s has pending signal %s: delivering it.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s has pending signal %s: delivering it.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
 
       return WSTOPSIG (status);
     }
@@ -1100,9 +1093,8 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Sending SIGCONT to %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("Sending SIGCONT to %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       kill_lwp (lwpid_of (lwp), SIGCONT);
       lwp->stop_expected = 0;
@@ -1276,7 +1268,7 @@ linux_wait_for_lwp (ptid_t ptid, int *wstatp, int options)
   struct lwp_info *child = NULL;
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
+    debug_printf ("linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
 
   if (ptid_equal (ptid, minus_one_ptid))
     to_wait_for = -1;			/* any child */
@@ -1297,7 +1289,7 @@ retry:
       && (!WIFSTOPPED (*wstatp)
 	  || (WSTOPSIG (*wstatp) != 32
 	      && WSTOPSIG (*wstatp) != 33)))
-    fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp);
+    debug_printf ("Got an event from %d (%x)\n", ret, *wstatp);
 
   child = find_lwp_pid (pid_to_ptid (ret));
 
@@ -1404,7 +1396,7 @@ retry:
       current_inferior = get_lwp_thread (child);
       regcache = get_thread_regcache (current_inferior, 1);
       pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
+      debug_printf ("linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
       current_inferior = saved_inferior;
     }
 
@@ -1450,7 +1442,7 @@ handle_tracepoints (struct lwp_info *lwp)
   if (tpoint_related_event)
     {
       if (debug_threads)
-	fprintf (stderr, "got a tracepoint event\n");
+	debug_printf ("got a tracepoint event\n");
       return 1;
     }
 
@@ -1501,9 +1493,9 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
       int r;
 
       if (debug_threads)
-	fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Checking whether LWP %ld needs to move out of the "
+		      "jump pad.\n",
+		      lwpid_of (lwp));
 
       r = linux_fast_tracepoint_collecting (lwp, &status);
 
@@ -1527,9 +1519,9 @@ Checking whether LWP %ld needs to move out of the jump pad.\n",
 		}
 
 	      if (debug_threads)
-		fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...it does\n",
-		 lwpid_of (lwp));
+		debug_printf ("Checking whether LWP %ld needs to move out of "
+			      "the jump pad...it does\n",
+			      lwpid_of (lwp));
 	      current_inferior = saved_inferior;
 
 	      return 1;
@@ -1582,9 +1574,8 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
 	  if (lwp->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Cancelling fast exit-jump-pad: removing bkpt. "
-			 "stopping all threads momentarily.\n");
+		debug_printf ("Cancelling fast exit-jump-pad: removing bkpt. "
+			      "stopping all threads momentarily.\n");
 
 	      stop_all_lwps (1, lwp);
 	      cancel_breakpoints ();
@@ -1600,9 +1591,9 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
     }
 
   if (debug_threads)
-    fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...no\n",
-	     lwpid_of (lwp));
+    debug_printf ("Checking whether LWP %ld needs to move out of the "
+		  "jump pad...no\n",
+		  lwpid_of (lwp));
 
   current_inferior = saved_inferior;
   return 0;
@@ -1617,8 +1608,8 @@ enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
   struct pending_signals *p_sig;
 
   if (debug_threads)
-    fprintf (stderr, "\
-Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
+    debug_printf ("Deferring signal %d for LWP %ld.\n",
+		  WSTOPSIG (*wstat), lwpid_of (lwp));
 
   if (debug_threads)
     {
@@ -1627,11 +1618,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
       for (sig = lwp->pending_signals_to_report;
 	   sig != NULL;
 	   sig = sig->prev)
-	fprintf (stderr,
-		 "   Already queued %d\n",
-		 sig->signal);
+	debug_printf ("   Already queued %d\n",
+		      sig->signal);
 
-      fprintf (stderr, "   (no more currently queued signals)\n");
+      debug_printf ("   (no more currently queued signals)\n");
     }
 
   /* Don't enqueue non-RT signals if they are already in the deferred
@@ -1648,11 +1638,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
 	  if (sig->signal == WSTOPSIG (*wstat))
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Not requeuing already queued non-RT signal %d"
-			 " for LWP %ld\n",
-			 sig->signal,
-			 lwpid_of (lwp));
+		debug_printf ("Not requeuing already queued non-RT signal %d"
+			      " for LWP %ld\n",
+			      sig->signal,
+			      lwpid_of (lwp));
 	      return;
 	    }
 	}
@@ -1690,8 +1679,8 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
       *p_sig = NULL;
 
       if (debug_threads)
-	fprintf (stderr, "Reporting deferred signal %d for LWP %ld.\n",
-		 WSTOPSIG (*wstat), lwpid_of (lwp));
+	debug_printf ("Reporting deferred signal %d for LWP %ld.\n",
+		      WSTOPSIG (*wstat), lwpid_of (lwp));
 
       if (debug_threads)
 	{
@@ -1700,11 +1689,10 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 	  for (sig = lwp->pending_signals_to_report;
 	       sig != NULL;
 	       sig = sig->prev)
-	    fprintf (stderr,
-		     "   Still queued %d\n",
-		     sig->signal);
+	    debug_printf ("   Still queued %d\n",
+			  sig->signal);
 
-	  fprintf (stderr, "   (no more queued signals)\n");
+	  debug_printf ("   (no more queued signals)\n");
 	}
 
       return 1;
@@ -1734,9 +1722,8 @@ cancel_breakpoint (struct lwp_info *lwp)
   if ((*the_low_target.breakpoint_at) (lwp->stop_pc))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: Push back breakpoint for %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: Push back breakpoint for %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       /* Back up the PC if necessary.  */
       if (the_low_target.decr_pc_after_break)
@@ -1752,10 +1739,9 @@ cancel_breakpoint (struct lwp_info *lwp)
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: No breakpoint found at %s for [%s]\n",
-		 paddress (lwp->stop_pc),
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: No breakpoint found at %s for [%s]\n",
+		      paddress (lwp->stop_pc),
+		      target_pid_to_str (ptid_of (lwp)));
     }
 
   current_inferior = saved_inferior;
@@ -1788,7 +1774,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       event_child = (struct lwp_info *)
 	find_inferior (&all_lwps, status_pending_p_callback, &ptid);
       if (debug_threads && event_child)
-	fprintf (stderr, "Got a pending child %ld\n", lwpid_of (event_child));
+	debug_printf ("Got a pending child %ld\n", lwpid_of (event_child));
     }
   else
     {
@@ -1816,8 +1802,8 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
   if (event_child != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
-		 lwpid_of (event_child), event_child->status_pending);
+	debug_printf ("Got an event from pending child %ld (%04x)\n",
+		      lwpid_of (event_child), event_child->status_pending);
       *wstat = event_child->status_pending;
       event_child->status_pending_p = 0;
       event_child->status_pending = 0;
@@ -1847,7 +1833,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if ((options & WNOHANG) && event_child == NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "WNOHANG set, no event found\n");
+	    debug_printf ("WNOHANG set, no event found\n");
 	  return 0;
 	}
 
@@ -1873,14 +1859,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if (! WIFSTOPPED (*wstat))
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld exiting\n", lwpid_of (event_child));
+	    debug_printf ("LWP %ld exiting\n", lwpid_of (event_child));
 
 	  /* If the last thread is exiting, just return.  */
 	  if (last_thread_of_process_p (current_inferior))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "LWP %ld is last lwp of process\n",
-			 lwpid_of (event_child));
+		debug_printf ("LWP %ld is last lwp of process\n",
+			      lwpid_of (event_child));
 	      return lwpid_of (event_child);
 	    }
 
@@ -1888,14 +1874,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	    {
 	      current_inferior = (struct thread_info *) all_threads.head;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now %ld\n",
-			 lwpid_of (get_thread_lwp (current_inferior)));
+		debug_printf ("Current inferior is now %ld\n",
+			      lwpid_of (get_thread_lwp (current_inferior)));
 	    }
 	  else
 	    {
 	      current_inferior = NULL;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now <NULL>\n");
+		debug_printf ("Current inferior is now <NULL>\n");
 	    }
 
 	  /* If we were waiting for this particular child to do something...
@@ -1938,7 +1924,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	  int should_stop;
 
 	  if (debug_threads)
-	    fprintf (stderr, "Expected stop.\n");
+	    debug_printf ("Expected stop.\n");
 	  event_child->stop_expected = 0;
 
 	  should_stop = (current_inferior->last_resume_kind == resume_stop
@@ -2082,9 +2068,8 @@ select_event_lwp (struct lwp_info **orig_lp)
   if (event_lp != NULL)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "SEL: Select single-step %s\n",
-		 target_pid_to_str (ptid_of (event_lp)));
+	debug_printf ("SEL: Select single-step %s\n",
+		      target_pid_to_str (ptid_of (event_lp)));
     }
   else
     {
@@ -2099,9 +2084,8 @@ select_event_lwp (struct lwp_info **orig_lp)
 	((num_events * (double) rand ()) / (RAND_MAX + 1.0));
 
       if (debug_threads && num_events > 1)
-	fprintf (stderr,
-		 "SEL: Found %d SIGTRAP events, selecting #%d\n",
-		 num_events, random_selector);
+	debug_printf ("SEL: Found %d SIGTRAP events, selecting #%d\n",
+		      num_events, random_selector);
 
       event_lp = (struct lwp_info *) find_inferior (&all_lwps,
 						    select_event_lwp_callback,
@@ -2191,8 +2175,8 @@ linux_stabilize_threads (void)
   if (lwp_stuck != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "can't stabilize, LWP %ld is stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("can't stabilize, LWP %ld is stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
       return;
     }
 
@@ -2243,8 +2227,8 @@ linux_stabilize_threads (void)
 	= (struct lwp_info *) find_inferior (&all_lwps,
 					 stuck_in_jump_pad_callback, NULL);
       if (lwp_stuck != NULL)
-	fprintf (stderr, "couldn't stabilize, LWP %ld got stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
     }
 }
 
@@ -2265,6 +2249,12 @@ linux_wait_1 (ptid_t ptid,
   int trace_event;
   int in_step_range;
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("linux_wait_1: [%s]\n", target_pid_to_str (ptid));
+    }
+
   /* Translate generic target options into linux options.  */
   options = __WALL;
   if (target_options & TARGET_WNOHANG)
@@ -2309,13 +2299,20 @@ retry:
   else
     {
       if (debug_threads)
-	fprintf (stderr, "step_over_bkpt set [%s], doing a blocking wait\n",
-		 target_pid_to_str (step_over_bkpt));
+	debug_printf ("step_over_bkpt set [%s], doing a blocking wait\n",
+		      target_pid_to_str (step_over_bkpt));
       pid = linux_wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
     }
 
   if (pid == 0) /* only if TARGET_WNOHANG */
-    return null_ptid;
+    {
+      if (debug_threads)
+	{
+	  debug_printf ("linux_wait_1 ret = null_ptid\n");
+	  debug_exit ();
+	}
+      return null_ptid;
+    }
 
   event_child = get_thread_lwp (current_inferior);
 
@@ -2341,9 +2338,13 @@ retry:
 	      ourstatus->value.integer = WEXITSTATUS (w);
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild exited with retcode = %x \n",
-			 WEXITSTATUS (w));
+		{
+		  debug_printf ("linux_wait_1 ret = %s, exited with "
+				"retcode %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WEXITSTATUS (w));
+		  debug_exit ();
+		}
 	    }
 	  else
 	    {
@@ -2351,10 +2352,13 @@ retry:
 	      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild terminated with signal = %x \n",
-			 WTERMSIG (w));
-
+		{
+		  debug_printf ("linux_wait_1 ret = %s, terminated with "
+				"signal %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WTERMSIG (w));
+		  debug_exit ();
+		}
 	    }
 
 	  return ptid_of (event_child);
@@ -2409,7 +2413,7 @@ retry:
 	     already handled it.  So next time we resume (from this
 	     PC), we should step over it.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 
 	  if (breakpoint_here (event_child->stop_pc))
 	    event_child->need_step_over = 1;
@@ -2435,10 +2439,9 @@ retry:
       && agent_loaded_p ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Got signal %d for LWP %ld.  Check if we need "
-		 "to defer or adjust it.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Got signal %d for LWP %ld.  Check if we need "
+		      "to defer or adjust it.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       /* Allow debugging the jump pad itself.  */
       if (current_inferior->last_resume_kind != resume_step
@@ -2447,9 +2450,8 @@ retry:
 	  enqueue_one_deferred_signal (event_child, &w);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred (in jump pad)\n",
-		     WSTOPSIG (w), lwpid_of (event_child));
+	    debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n",
+			  WSTOPSIG (w), lwpid_of (event_child));
 
 	  linux_resume_one_lwp (event_child, 0, 0, NULL);
 	  goto retry;
@@ -2459,11 +2461,10 @@ retry:
   if (event_child->collecting_fast_tracepoint)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-LWP %ld was trying to move out of the jump pad (%d).  \
-Check if we're already there.\n",
-		 lwpid_of (event_child),
-		 event_child->collecting_fast_tracepoint);
+	debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
+		      "Check if we're already there.\n",
+		      lwpid_of (event_child),
+		      event_child->collecting_fast_tracepoint);
 
       trace_event = 1;
 
@@ -2476,9 +2477,8 @@ Check if we're already there.\n",
 	  if (event_child->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "No longer need exit-jump-pad bkpt; removing it."
-			 "stopping all threads momentarily.\n");
+		debug_printf ("No longer need exit-jump-pad bkpt; removing it."
+			      "stopping all threads momentarily.\n");
 
 	      /* Other running threads could hit this breakpoint.
 		 We don't handle moribund locations like GDB does,
@@ -2502,25 +2502,33 @@ Check if we're already there.\n",
       if (event_child->collecting_fast_tracepoint == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "fast tracepoint finished "
-		     "collecting successfully.\n");
+	    debug_printf ("fast tracepoint finished "
+			  "collecting successfully.\n");
 
 	  /* We may have a deferred signal to report.  */
 	  if (dequeue_one_deferred_signal (event_child, &w))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "dequeued one signal.\n");
+		debug_printf ("dequeued one signal.\n");
 	    }
 	  else
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "no deferred signals.\n");
+		debug_printf ("no deferred signals.\n");
 
 	      if (stabilizing_threads)
 		{
 		  ourstatus->kind = TARGET_WAITKIND_STOPPED;
 		  ourstatus->value.sig = GDB_SIGNAL_0;
+
+		  if (debug_threads)
+		    {
+		      debug_printf ("linux_wait_1 ret = %s, stopped "
+				    "while stabilizing threads\n",
+				    target_pid_to_str (ptid_of (event_child)));
+		      debug_exit ();
+		    }
+
 		  return ptid_of (event_child);
 		}
 	    }
@@ -2554,8 +2562,8 @@ Check if we're already there.\n",
       siginfo_t info, *info_p;
 
       if (debug_threads)
-	fprintf (stderr, "Ignored signal %d for LWP %ld.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Ignored signal %d for LWP %ld.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       if (ptrace (PTRACE_GETSIGINFO, lwpid_of (event_child),
 		  (PTRACE_TYPE_ARG3) 0, &info) == 0)
@@ -2600,16 +2608,16 @@ Check if we're already there.\n",
       if (debug_threads)
 	{
 	  if (bp_explains_trap)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 	  if (step_over_finished)
-	    fprintf (stderr, "Step-over finished.\n");
+	    debug_printf ("Step-over finished.\n");
 	  if (trace_event)
-	    fprintf (stderr, "Tracepoint event.\n");
+	    debug_printf ("Tracepoint event.\n");
 	  if (lwp_in_step_range (event_child))
-	    fprintf (stderr, "Range stepping pc 0x%s [0x%s, 0x%s).\n",
-		     paddress (event_child->stop_pc),
-		     paddress (event_child->step_range_start),
-		     paddress (event_child->step_range_end));
+	    debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).\n",
+			  paddress (event_child->stop_pc),
+			  paddress (event_child->step_range_start),
+			  paddress (event_child->step_range_end));
 	}
 
       /* We're not reporting this breakpoint to GDB, so apply the
@@ -2629,7 +2637,7 @@ Check if we're already there.\n",
 	 going to keep waiting, so use proceed, which handles stepping
 	 over the next breakpoint.  */
       if (debug_threads)
-	fprintf (stderr, "proceeding all threads.\n");
+	debug_printf ("proceeding all threads.\n");
 
       if (step_over_finished)
 	unsuspend_all_lwps (event_child);
@@ -2643,16 +2651,16 @@ Check if we're already there.\n",
       if (current_inferior->last_resume_kind == resume_step)
 	{
 	  if (event_child->step_range_start == event_child->step_range_end)
-	    fprintf (stderr, "GDB wanted to single-step, reporting event.\n");
+	    debug_printf ("GDB wanted to single-step, reporting event.\n");
 	  else if (!lwp_in_step_range (event_child))
-	    fprintf (stderr, "Out of step range, reporting event.\n");
+	    debug_printf ("Out of step range, reporting event.\n");
 	}
       if (event_child->stopped_by_watchpoint)
-	fprintf (stderr, "Stopped by watchpoint.\n");
+	debug_printf ("Stopped by watchpoint.\n");
       if (gdb_breakpoint_here (event_child->stop_pc))
-	fprintf (stderr, "Stopped by GDB breakpoint.\n");
+	debug_printf ("Stopped by GDB breakpoint.\n");
       if (debug_threads)
-	fprintf (stderr, "Hit a non-gdbserver trap event.\n");
+	debug_printf ("Hit a non-gdbserver trap event.\n");
     }
 
   /* Alright, we're going to report a stop.  */
@@ -2730,10 +2738,12 @@ Check if we're already there.\n",
   gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait ret = %s, %d, %d\n",
-	     target_pid_to_str (ptid_of (event_child)),
-	     ourstatus->kind,
-	     ourstatus->value.sig);
+    {
+      debug_printf ("linux_wait_1 ret = %s, %d, %d\n",
+		    target_pid_to_str (ptid_of (event_child)),
+		    ourstatus->kind, ourstatus->value.sig);
+      debug_exit ();
+    }
 
   return ptid_of (event_child);
 }
@@ -2772,9 +2782,6 @@ linux_wait (ptid_t ptid,
 {
   ptid_t event_ptid;
 
-  if (debug_threads)
-    fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
-
   /* Flush the async file first.  */
   if (target_is_async_p ())
     async_file_flush ();
@@ -2837,13 +2844,13 @@ send_sigstop (struct lwp_info *lwp)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr, "Have pending sigstop for lwp %d\n", pid);
+	debug_printf ("Have pending sigstop for lwp %d\n", pid);
 
       return;
     }
 
   if (debug_threads)
-    fprintf (stderr, "Sending sigstop to lwp %d\n", pid);
+    debug_printf ("Sending sigstop to lwp %d\n", pid);
 
   lwp->stop_expected = 1;
   kill_lwp (pid, SIGSTOP);
@@ -2912,8 +2919,8 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "wait_for_sigstop: LWP %ld already stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("wait_for_sigstop: LWP %ld already stopped\n",
+		      lwpid_of (lwp));
       return;
     }
 
@@ -2926,7 +2933,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   ptid = lwp->head.id;
 
   if (debug_threads)
-    fprintf (stderr, "wait_for_sigstop: pulling one event\n");
+    debug_printf ("wait_for_sigstop: pulling one event\n");
 
   pid = linux_wait_for_event (ptid, &wstat, __WALL);
 
@@ -2936,14 +2943,14 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (WIFSTOPPED (wstat))
     {
       if (debug_threads)
-	fprintf (stderr, "LWP %ld stopped with signal %d\n",
-		 lwpid_of (lwp), WSTOPSIG (wstat));
+	debug_printf ("LWP %ld stopped with signal %d\n",
+		      lwpid_of (lwp), WSTOPSIG (wstat));
 
       if (WSTOPSIG (wstat) != SIGSTOP)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n",
-		     lwpid_of (lwp), wstat);
+	    debug_printf ("LWP %ld stopped with non-sigstop status %06x\n",
+			  lwpid_of (lwp), wstat);
 
 	  lwp->status_pending_p = 1;
 	  lwp->status_pending = wstat;
@@ -2952,7 +2959,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Process %d exited while stopping LWPs\n", pid);
+	debug_printf ("Process %d exited while stopping LWPs\n", pid);
 
       lwp = find_lwp_pid (pid_to_ptid (pid));
       if (lwp)
@@ -2973,7 +2980,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Previously current thread died.\n");
+	debug_printf ("Previously current thread died.\n");
 
       if (non_stop)
 	{
@@ -3032,9 +3039,8 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
       && maybe_move_out_of_jump_pad (lwp, wstat))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "LWP %ld needs stabilizing (in jump pad)\n",
-		 lwpid_of (lwp));
+	debug_printf ("LWP %ld needs stabilizing (in jump pad)\n",
+		      lwpid_of (lwp));
 
       if (wstat)
 	{
@@ -3042,10 +3048,9 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
 	  enqueue_one_deferred_signal (lwp, wstat);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred "
-		     "(in jump pad)\n",
-		     WSTOPSIG (*wstat), lwpid_of (lwp));
+	    debug_printf ("Signal %d for LWP %ld deferred "
+			  "(in jump pad)\n",
+			  WSTOPSIG (*wstat), lwpid_of (lwp));
 	}
 
       linux_resume_one_lwp (lwp, 0, 0, NULL);
@@ -3076,6 +3081,16 @@ stop_all_lwps (int suspend, struct lwp_info *except)
   /* Should not be called recursively.  */
   gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("stop_all_lwps (%s, except=%s)\n",
+		    suspend ? "stop-and-suspend" : "stop",
+		    except != NULL
+		    ? target_pid_to_str (ptid_of (except))
+		    : "none");
+    }
+
   stopping_threads = (suspend
 		      ? STOPPING_AND_SUSPENDING_THREADS
 		      : STOPPING_THREADS);
@@ -3086,6 +3101,13 @@ stop_all_lwps (int suspend, struct lwp_info *except)
     find_inferior (&all_lwps, send_sigstop_callback, except);
   for_each_inferior (&all_lwps, wait_for_sigstop);
   stopping_threads = NOT_STOPPING_THREADS;
+
+  if (debug_threads)
+    {
+      debug_printf ("stop_all_lwps done, setting stopping_threads "
+		    "back to !stopping\n");
+      debug_exit ();
+    }
 }
 
 /* Resume execution of the inferior process.
@@ -3138,10 +3160,10 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "Not resuming lwp %ld (%s, signal %d, stop %s);"
-		 " has pending status\n",
-		 lwpid_of (lwp), step ? "step" : "continue", signal,
-		 lwp->stop_expected ? "expected" : "not expected");
+	debug_printf ("Not resuming lwp %ld (%s, signal %d, stop %s);"
+		      " has pending status\n",
+		      lwpid_of (lwp), step ? "step" : "continue", signal,
+		      lwp->stop_expected ? "expected" : "not expected");
       return;
     }
 
@@ -3149,9 +3171,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   current_inferior = get_lwp_thread (lwp);
 
   if (debug_threads)
-    fprintf (stderr, "Resuming lwp %ld (%s, signal %d, stop %s)\n",
-	     lwpid_of (lwp), step ? "step" : "continue", signal,
-	     lwp->stop_expected ? "expected" : "not expected");
+    debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)\n",
+		  lwpid_of (lwp), step ? "step" : "continue", signal,
+		  lwp->stop_expected ? "expected" : "not expected");
 
   /* This bit needs some thinking about.  If we get a signal that
      we must report while a single-step reinsert is still pending,
@@ -3166,8 +3188,8 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "  pending reinsert at 0x%s\n",
-		 paddress (lwp->bp_reinsert));
+	debug_printf ("  pending reinsert at 0x%s\n",
+		      paddress (lwp->bp_reinsert));
 
       if (can_hardware_single_step ())
 	{
@@ -3190,9 +3212,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (fast_tp_collecting == 1)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " (exit-jump-pad-bkpt)\n",
+		      lwpid_of (lwp));
 
       /* Postpone any pending signal.  It was enqueued above.  */
       signal = 0;
@@ -3200,9 +3222,9 @@ lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
   else if (fast_tp_collecting == 2)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " single-stepping\n",
+		      lwpid_of (lwp));
 
       if (can_hardware_single_step ())
 	step = 1;
@@ -3226,9 +3248,8 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
       && can_hardware_single_step ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "lwp %ld has a while-stepping action -> forcing step.\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld has a while-stepping action -> forcing step.\n",
+		      lwpid_of (lwp));
       step = 1;
     }
 
@@ -3236,7 +3257,7 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
     {
       struct regcache *regcache = get_thread_regcache (current_inferior, 1);
       CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "  resuming from pc 0x%lx\n", (long) pc);
+      debug_printf ("  resuming from pc 0x%lx\n", (long) pc);
     }
 
   /* If we have pending signals, consume one unless we are trying to
@@ -3334,11 +3355,12 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      && thread->last_resume_kind == resume_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "already %s LWP %ld at GDB's request\n",
-			 thread->last_status.kind == TARGET_WAITKIND_STOPPED
-			 ? "stopped"
-			 : "stopping",
-			 lwpid_of (lwp));
+		debug_printf ("already %s LWP %ld at GDB's request\n",
+			      (thread->last_status.kind
+			       == TARGET_WAITKIND_STOPPED)
+			      ? "stopped"
+			      : "stopping",
+			      lwpid_of (lwp));
 
 	      continue;
 	    }
@@ -3359,10 +3381,9 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      lwp->status_pending_p = 1;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Dequeueing deferred signal %d for LWP %ld, "
-			 "leaving status pending.\n",
-			 WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
+		debug_printf ("Dequeueing deferred signal %d for LWP %ld, "
+			      "leaving status pending.\n",
+			      WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
 	    }
 
 	  return 0;
@@ -3413,9 +3434,8 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, not stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3424,9 +3444,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (thread->last_resume_kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, should remain stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, should remain"
+		      " stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3435,25 +3455,23 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, suspended\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, suspended\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (!lwp->need_step_over)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? No\n", lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? No\n", lwpid_of (lwp));
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, has pending status.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
+		      " status.\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3469,10 +3487,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (pc != lwp->stop_pc)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Cancelling, PC was changed.  "
-		 "Old stop_pc was 0x%s, PC is now 0x%s\n",
-		 lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
+	debug_printf ("Need step over [LWP %ld]? Cancelling, PC was changed. "
+		      "Old stop_pc was 0x%s, PC is now 0x%s\n",
+		      lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
 
       lwp->need_step_over = 0;
       return 0;
@@ -3492,10 +3509,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
 	  && gdb_no_commands_at_breakpoint (pc))
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, but found"
-		     " GDB breakpoint at 0x%s; skipping step over\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, but found"
+			  " GDB breakpoint at 0x%s; skipping step over\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  current_inferior = saved_inferior;
 	  return 0;
@@ -3503,10 +3519,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, "
-		     "found breakpoint at 0x%s\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, "
+			  "found breakpoint at 0x%s\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  /* We've found an lwp that needs stepping over --- return 1 so
 	     that find_inferior stops looking.  */
@@ -3521,9 +3536,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   current_inferior = saved_inferior;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Need step over [LWP %ld]? No, no breakpoint found at 0x%s\n",
-	     lwpid_of (lwp), paddress (pc));
+    debug_printf ("Need step over [LWP %ld]? No, no breakpoint found"
+		  " at 0x%s\n",
+		  lwpid_of (lwp), paddress (pc));
 
   return 0;
 }
@@ -3554,15 +3569,14 @@ start_step_over (struct lwp_info *lwp)
   int step;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Starting step-over on LWP %ld.  Stopping all threads\n",
-	     lwpid_of (lwp));
+    debug_printf ("Starting step-over on LWP %ld.  Stopping all threads\n",
+		  lwpid_of (lwp));
 
   stop_all_lwps (1, lwp);
   gdb_assert (lwp->suspended == 0);
 
   if (debug_threads)
-    fprintf (stderr, "Done stopping all threads for step-over.\n");
+    debug_printf ("Done stopping all threads for step-over.\n");
 
   /* Note, we should always reach here with an already adjusted PC,
      either by GDB (if we're resuming due to GDB's request), or by our
@@ -3607,7 +3621,7 @@ finish_step_over (struct lwp_info *lwp)
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "Finished step over.\n");
+	debug_printf ("Finished step over.\n");
 
       /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
 	 may be no breakpoint to reinsert there by now.  */
@@ -3662,12 +3676,12 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (lwp->resume->kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr, "resume_stop request for LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resume_stop request for LWP %ld\n", lwpid_of (lwp));
 
       if (!lwp->stopped)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "stopping LWP %ld\n", lwpid_of (lwp));
+	    debug_printf ("stopping LWP %ld\n", lwpid_of (lwp));
 
 	  /* Stop the thread, and wait for the event asynchronously,
 	     through the event loop.  */
@@ -3676,8 +3690,8 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "already stopped LWP %ld\n",
-		     lwpid_of (lwp));
+	    debug_printf ("already stopped LWP %ld\n",
+			  lwpid_of (lwp));
 
 	  /* The LWP may have been stopped in an internal event that
 	     was not meant to be notified back to GDB (e.g., gdbserver
@@ -3719,7 +3733,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (!leave_pending)
     {
       if (debug_threads)
-	fprintf (stderr, "resuming LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resuming LWP %ld\n", lwpid_of (lwp));
 
       step = (lwp->resume->kind == resume_step);
       linux_resume_one_lwp (lwp, step, lwp->resume->sig, NULL);
@@ -3727,7 +3741,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "leaving LWP %ld stopped\n", lwpid_of (lwp));
+	debug_printf ("leaving LWP %ld stopped\n", lwpid_of (lwp));
 
       /* If we have a new signal, enqueue the signal.  */
       if (lwp->resume->sig != 0)
@@ -3764,6 +3778,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   int any_pending;
   int leave_all_stopped;
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("linux_resume:\n");
+    }
+
   find_inferior (&all_threads, linux_set_resume_request, &array);
 
   /* If there is a thread which would otherwise be resumed, which has
@@ -3792,13 +3812,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   if (debug_threads)
     {
       if (need_step_over != NULL)
-	fprintf (stderr, "Not resuming all, need step over\n");
+	debug_printf ("Not resuming all, need step over\n");
       else if (any_pending)
-	fprintf (stderr,
-		 "Not resuming, all-stop and found "
-		 "an LWP with pending status\n");
+	debug_printf ("Not resuming, all-stop and found "
+		      "an LWP with pending status\n");
       else
-	fprintf (stderr, "Resuming, no pending status or step over needed\n");
+	debug_printf ("Resuming, no pending status or step over needed\n");
     }
 
   /* Even if we're leaving threads stopped, queue all signals we'd
@@ -3807,6 +3826,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
 
   if (need_step_over)
     start_step_over (need_step_over);
+
+  if (debug_threads)
+    {
+      debug_printf ("linux_resume done\n");
+      debug_exit ();
+    }
 }
 
 /* This function is called once per thread.  We check the thread's
@@ -3829,13 +3854,12 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
+    debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
 
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld already running\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld already running\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3845,16 +3869,16 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
       && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
     {
       if (debug_threads)
-	fprintf (stderr, "   client wants LWP to remain %ld stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   client wants LWP to remain %ld stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld has pending status, leaving stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   LWP %ld has pending status, leaving stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3863,7 +3887,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld is suspended\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld is suspended\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3882,10 +3906,9 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
 	 pending, this is a no-op.  */
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Client wants LWP %ld to stop. "
-		 "Making sure it has a SIGSTOP pending\n",
-		 lwpid_of (lwp));
+	debug_printf ("Client wants LWP %ld to stop. "
+		      "Making sure it has a SIGSTOP pending\n",
+		      lwpid_of (lwp));
 
       send_sigstop (lwp);
     }
@@ -3932,9 +3955,9 @@ proceed_all_lwps (void)
       if (need_step_over != NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "proceed_all_lwps: found "
-		     "thread %ld needing a step-over\n",
-		     lwpid_of (need_step_over));
+	    debug_printf ("proceed_all_lwps: found "
+			  "thread %ld needing a step-over\n",
+			  lwpid_of (need_step_over));
 
 	  start_step_over (need_step_over);
 	  return;
@@ -3942,7 +3965,7 @@ proceed_all_lwps (void)
     }
 
   if (debug_threads)
-    fprintf (stderr, "Proceeding, no step-over needed\n");
+    debug_printf ("Proceeding, no step-over needed\n");
 
   find_inferior (&all_lwps, proceed_one_lwp, NULL);
 }
@@ -3956,18 +3979,24 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
 {
   if (debug_threads)
     {
+      debug_enter ();
       if (except)
-	fprintf (stderr,
-		 "unstopping all lwps, except=(LWP %ld)\n", lwpid_of (except));
+	debug_printf ("unstopping all lwps, except=(LWP %ld)\n",
+		      lwpid_of (except));
       else
-	fprintf (stderr,
-		 "unstopping all lwps\n");
+	debug_printf ("unstopping all lwps\n");
     }
 
   if (unsuspend)
     find_inferior (&all_lwps, unsuspend_and_proceed_one_lwp, except);
   else
     find_inferior (&all_lwps, proceed_one_lwp, except);
+
+  if (debug_threads)
+    {
+      debug_printf ("unstop_all_lwps done\n");
+      debug_exit ();
+    }
 }
 
 
@@ -4533,8 +4562,8 @@ linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 	val = val & 0xffff;
       else if (len == 3)
 	val = val & 0xffffff;
-      fprintf (stderr, "Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
-	       val, (long)memaddr);
+      debug_printf ("Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
+		    val, (long)memaddr);
     }
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
@@ -4777,9 +4806,9 @@ linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
   pid = lwpid_of (get_thread_lwp (current_inferior));
 
   if (debug_threads)
-    fprintf (stderr, "%s siginfo for lwp %d.\n",
-	     readbuf != NULL ? "Reading" : "Writing",
-	     pid);
+    debug_printf ("%s siginfo for lwp %d.\n",
+		  readbuf != NULL ? "Reading" : "Writing",
+		  pid);
 
   if (offset >= sizeof (siginfo))
     return -1;
@@ -4851,8 +4880,8 @@ linux_async (int enable)
   int previous = (linux_event_pipe[0] != -1);
 
   if (debug_threads)
-    fprintf (stderr, "linux_async (%d), previous=%d\n",
-	     enable, previous);
+    debug_printf ("linux_async (%d), previous=%d\n",
+		  enable, previous);
 
   if (previous != enable)
     {
diff --git a/gdb/gdbserver/linux-m32r-low.c b/gdb/gdbserver/linux-m32r-low.c
index e208523..477e185 100644
--- a/gdb/gdbserver/linux-m32r-low.c
+++ b/gdb/gdbserver/linux-m32r-low.c
@@ -59,7 +59,7 @@ m32r_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-sparc-low.c b/gdb/gdbserver/linux-sparc-low.c
index fcffe05..75c97dd 100644
--- a/gdb/gdbserver/linux-sparc-low.c
+++ b/gdb/gdbserver/linux-sparc-low.c
@@ -231,7 +231,7 @@ sparc_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index e1daa7d..1e590e8 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -2027,8 +2027,8 @@ add_insns (unsigned char *start, int len)
   CORE_ADDR buildaddr = current_insn_ptr;
 
   if (debug_threads)
-    fprintf (stderr, "Adding %d bytes of insn at %s\n",
-	     len, paddress (buildaddr));
+    debug_printf ("Adding %d bytes of insn at %s\n",
+		  len, paddress (buildaddr));
 
   append_insns (&buildaddr, len, start);
   current_insn_ptr = buildaddr;
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index fd706e9..b77ce10 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -197,10 +197,9 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -211,9 +210,8 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -334,10 +332,9 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert fast tracepoint jump "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert fast tracepoint jump "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -398,10 +395,9 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " fast tracepoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " fast tracepoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (jp);
       return NULL;
     }
@@ -424,9 +420,8 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert fast tracepoint jump at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
 
       /* Unlink it.  */
       proc->fast_tracepoint_jumps = jp->next;
@@ -450,10 +445,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -480,9 +474,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
 	  jp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert fast tracepoint jump at 0x%s (%s).\n",
-		     paddress (pc), strerror (err));
+	    debug_printf ("Failed to uninsert fast tracepoint jump at"
+			  " 0x%s (%s).\n",
+			  paddress (pc), strerror (err));
 	}
     }
 }
@@ -500,10 +494,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       /* This can happen when we remove breakpoints when a tracepoint
 	 hit causes a tracing stop, while handling a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (where));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (where));
       return;
     }
 
@@ -528,9 +521,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       jp->inserted = 0;
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to reinsert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to reinsert fast tracepoint jump at"
+		      " 0x%s (%s).\n",
+		      paddress (where), strerror (err));
     }
 }
 
@@ -598,10 +591,9 @@ delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert raw breakpoint "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert raw breakpoint "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -932,9 +924,9 @@ gdb_no_commands_at_breakpoint (CORE_ADDR where)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr, "at 0x%s, bp command_list is 0x%s\n",
-	     paddress (where),
-	     phex_nz ((uintptr_t) bp->command_list, 0));
+    debug_printf ("at 0x%s, bp command_list is 0x%s\n",
+		  paddress (where),
+		  phex_nz ((uintptr_t) bp->command_list, 0));
   return (bp->command_list == NULL);
 }
 
@@ -1034,9 +1026,8 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
 	  bp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
-		     paddress (bp->pc), strerror (err));
+	    debug_printf ("Failed to uninsert raw breakpoint at 0x%s (%s).\n",
+			  paddress (bp->pc), strerror (err));
 	}
     }
 }
@@ -1052,10 +1043,9 @@ uninsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find breakpoint at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find breakpoint at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -1087,9 +1077,8 @@ reinsert_raw_breakpoint (struct raw_breakpoint *bp)
   if (err == 0)
     bp->inserted = 1;
   else if (debug_threads)
-    fprintf (stderr,
-	     "Failed to reinsert breakpoint at 0x%s (%s).\n",
-	     paddress (bp->pc), strerror (err));
+    debug_printf ("Failed to reinsert breakpoint at 0x%s (%s).\n",
+		  paddress (bp->pc), strerror (err));
 }
 
 void
@@ -1103,10 +1092,9 @@ reinsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find raw breakpoint at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find raw breakpoint at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (pc));
       return;
     }
 
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 75ace6e..3b88995 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -161,7 +161,7 @@ handle_accept_event (int err, gdb_client_data client_data)
   socklen_t tmp;
 
   if (debug_threads)
-    fprintf (stderr, "handling possible accept event\n");
+    debug_printf ("handling possible accept event\n");
 
   tmp = sizeof (sockaddr);
   remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
@@ -1315,8 +1315,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
 		      struct target_waitstatus *status)
 {
   if (debug_threads)
-    fprintf (stderr, "Writing resume reply for %s:%d\n",
-	     target_pid_to_str (ptid), status->kind);
+    debug_printf ("Writing resume reply for %s:%d\n",
+		  target_pid_to_str (ptid), status->kind);
 
   switch (status->kind)
     {
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 28ea048..88354be 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -22,10 +22,12 @@
 #include "notif.h"
 #include "tdesc.h"
 
+#include <ctype.h>
 #include <unistd.h>
 #if HAVE_SIGNAL_H
 #include <signal.h>
 #endif
+#include "gdb_vecs.h"
 #include "gdb_wait.h"
 #include "btrace-common.h"
 #include "filestuff.h"
@@ -66,10 +68,6 @@ int disable_randomization = 1;
 
 static char **program_argv, **wrapper_argv;
 
-/* Enable miscellaneous debugging output.  The name is historical - it
-   was originally used to debug LinuxThreads support.  */
-int debug_threads;
-
 /* Enable debugging of h/w breakpoint/watchpoint support.  */
 int debug_hw_points;
 
@@ -222,8 +220,8 @@ start_inferior (char **argv)
     {
       int i;
       for (i = 0; new_argv[i]; ++i)
-	fprintf (stderr, "new_argv[%d] = \"%s\"\n", i, new_argv[i]);
-      fflush (stderr);
+	debug_printf ("new_argv[%d] = \"%s\"\n", i, new_argv[i]);
+      debug_flush ();
     }
 
 #ifdef SIGTTOU
@@ -694,6 +692,13 @@ monitor_show_help (void)
   monitor_output ("    Enable h/w breakpoint/watchpoint debugging messages\n");
   monitor_output ("  set remote-debug <0|1>\n");
   monitor_output ("    Enable remote protocol debugging messages\n");
+  monitor_output ("  set debug-format option1[,option2,...]\n");
+  monitor_output ("    Add additional information to debugging messages\n");
+  monitor_output ("    Options: all, none");
+#ifdef HAVE_GETTIMEOFDAY
+  monitor_output (", timestamp");
+#endif
+  monitor_output ("\n");
   monitor_output ("  exit\n");
   monitor_output ("    Quit GDBserver\n");
 }
@@ -921,6 +926,80 @@ handle_search_memory (char *own_buf, int packet_len)
       return;					\
     }
 
+/* Parse options to --debug-format= and "monitor set debug-format".
+   ARG is the text after "--debug-format=" or "monitor set debug-format".
+   IS_MONITOR is non-zero if we're invoked via "monitor set debug-format".
+   This triggers calls to monitor_output.
+   The result is NULL if all options were parsed ok, otherwise an error
+   message which the caller must free.
+
+   N.B. These commands affect all debug format settings, they are not
+   cumulative.  If a format is not specified, it is turned off.
+   However, we don't go to extra trouble with things like
+   "monitor set debug-format all,none,timestamp".
+   Instead we just parse them one at a time, in order.
+
+   The syntax for "monitor set debug" we support here is not identical
+   to gdb's "set debug foo on|off" because we also use this function to
+   parse "--debug-format=foo,bar".  */
+
+static char *
+parse_debug_format_options (const char *arg, int is_monitor)
+{
+  VEC (char_ptr) *options;
+  int ix;
+  char *option;
+
+  /* First turn all debug format options off.  */
+  debug_timestamp = 0;
+
+  /* First remove leading spaces, for "monitor set debug-format".  */
+  while (isspace (*arg))
+    ++arg;
+
+  options = delim_string_to_char_ptr_vec (arg, ',');
+
+  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
+    {
+      if (strcmp (option, "all") == 0)
+	{
+	  debug_timestamp = 1;
+	  if (is_monitor)
+	    monitor_output ("All extra debug format options enabled.\n");
+	}
+      else if (strcmp (option, "none") == 0)
+	{
+	  debug_timestamp = 0;
+	  if (is_monitor)
+	    monitor_output ("All extra debug format options disabled.\n");
+	}
+#ifdef HAVE_GETTIMEOFDAY
+      else if (strcmp (option, "timestamp") == 0)
+	{
+	  debug_timestamp = 1;
+	  if (is_monitor)
+	    monitor_output ("Timestamps will be added to debug output.\n");
+	}
+#endif
+      else if (*option == '\0')
+	{
+	  /* An empty option, e.g., "--debug-format=foo,,bar", is ignored.  */
+	  continue;
+	}
+      else
+	{
+	  char *msg = xstrprintf ("Unknown debug-format argument: \"%s\"\n",
+				  option);
+
+	  free_char_ptr_vec (options);
+	  return msg;
+	}
+    }
+
+  free_char_ptr_vec (options);
+  return NULL;
+}
+
 /* Handle monitor commands not handled by target-specific handlers.  */
 
 static void
@@ -956,6 +1035,21 @@ handle_monitor_command (char *mon, char *own_buf)
       remote_debug = 0;
       monitor_output ("Protocol debug output disabled.\n");
     }
+  else if (strncmp (mon, "set debug-format ",
+		    sizeof ("set debug-format ") - 1) == 0)
+    {
+      char *error_msg
+	= parse_debug_format_options (mon + sizeof ("set debug-format ") - 1,
+				      1);
+
+      if (error_msg != NULL)
+	{
+	  monitor_output (error_msg);
+	  monitor_show_help ();
+	  write_enn (own_buf);
+	  xfree (error_msg);
+	}
+    }
   else if (strcmp (mon, "help") == 0)
     monitor_show_help ();
   else if (strcmp (mon, "exit") == 0)
@@ -2535,10 +2629,9 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
 	      char *status_string
 		= target_waitstatus_to_string (&thread->last_status);
 
-	      fprintf (stderr,
-		       "Reporting thread %s as already stopped with %s\n",
-		       target_pid_to_str (entry->id),
-		       status_string);
+	      debug_printf ("Reporting thread %s as already stopped with %s\n",
+			    target_pid_to_str (entry->id),
+			    status_string);
 
 	      xfree (status_string);
 	    }
@@ -2733,6 +2826,14 @@ gdbserver_usage (FILE *stream)
 	   "\n"
 	   "Options:\n"
 	   "  --debug               Enable general debugging output.\n"
+	   "  --debug-format=opt1[,opt2,...]\n"
+	   "                        Specify extra content in debugging output.\n"
+	   "                          Options:\n"
+	   "                            all\n"
+	   "                            none\n"
+#ifdef HAVE_GETTIMEOFDAY
+	   "                            timestamp\n"
+#endif
 	   "  --remote-debug        Enable remote protocol debugging output.\n"
 	   "  --version             Display version information and exit.\n"
 	   "  --wrapper WRAPPER --  Run WRAPPER to start new programs.\n"
@@ -2908,6 +3009,20 @@ main (int argc, char *argv[])
 	}
       else if (strcmp (*next_arg, "--debug") == 0)
 	debug_threads = 1;
+      else if (strncmp (*next_arg,
+			"--debug-format=",
+			sizeof ("--debug-format=") - 1) == 0)
+	{
+	  char *error_msg
+	    = parse_debug_format_options ((*next_arg)
+					  + sizeof ("--debug-format=") - 1, 0);
+
+	  if (error_msg != NULL)
+	    {
+	      fprintf (stderr, "%s", error_msg);
+	      exit (1);
+	    }
+	}
       else if (strcmp (*next_arg, "--remote-debug") == 0)
 	remote_debug = 1;
       else if (strcmp (*next_arg, "--disable-packet") == 0)
@@ -3204,14 +3319,14 @@ process_point_options (CORE_ADDR point_addr, char **packet)
 	{
 	  /* Conditional expression.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint condition.\n");
+	    debug_printf ("Found breakpoint condition.\n");
 	  add_breakpoint_condition (point_addr, &dataptr);
 	}
       else if (strncmp (dataptr, "cmds:", strlen ("cmds:")) == 0)
 	{
 	  dataptr += strlen ("cmds:");
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint commands %s.\n", dataptr);
+	    debug_printf ("Found breakpoint commands %s.\n", dataptr);
 	  persist = (*dataptr == '1');
 	  dataptr += 2;
 	  add_breakpoint_commands (point_addr, &dataptr, persist);
@@ -3316,7 +3431,7 @@ process_serial_event (void)
 	  if (!non_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "Forcing non-stop mode\n");
+		debug_printf ("Forcing non-stop mode\n");
 
 	      non_stop = 1;
 	      start_non_stop (1);
@@ -3709,7 +3824,7 @@ int
 handle_serial_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible serial event\n");
+    debug_printf ("handling possible serial event\n");
 
   /* Really handle it.  */
   if (process_serial_event () < 0)
@@ -3728,7 +3843,7 @@ int
 handle_target_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible target event\n");
+    debug_printf ("handling possible target event\n");
 
   last_ptid = mywait (minus_one_ptid, &last_status,
 		      TARGET_WNOHANG, 1);
@@ -3770,10 +3885,10 @@ handle_target_event (int err, gdb_client_data client_data)
 	      struct thread_resume resume_info;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "GDB not connected; forwarding event %d for [%s]\n",
-			 (int) last_status.kind,
-			 target_pid_to_str (last_ptid));
+		debug_printf ("GDB not connected; forwarding event %d for"
+			      " [%s]\n",
+			      (int) last_status.kind,
+			      target_pid_to_str (last_ptid));
 
 	      resume_info.thread = last_ptid;
 	      resume_info.kind = resume_continue;
@@ -3781,9 +3896,9 @@ handle_target_event (int err, gdb_client_data client_data)
 	      (*the_target->resume) (&resume_info, 1);
 	    }
 	  else if (debug_threads)
-	    fprintf (stderr, "GDB not connected; ignoring event %d for [%s]\n",
-		     (int) last_status.kind,
-		     target_pid_to_str (last_ptid));
+	    debug_printf ("GDB not connected; ignoring event %d for [%s]\n",
+			  (int) last_status.kind,
+			  target_pid_to_str (last_ptid));
 	}
       else
 	{
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index d82556a..6eb1a16 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -110,7 +110,6 @@ extern ptid_t cont_thread;
 extern ptid_t general_thread;
 
 extern int server_waiting;
-extern int debug_threads;
 extern int debug_hw_points;
 extern int pass_signals[];
 extern int program_signals[];
@@ -146,6 +145,7 @@ extern int handle_target_event (int err, gdb_client_data client_data);
 
 #include "common-utils.h"
 #include "utils.h"
+#include "debug.h"
 
 #include "gdb_assert.h"
 
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 8b8f6ce..df06b9d 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -194,7 +194,7 @@ thread_db_create_event (CORE_ADDR where)
     fatal ("unexpected thread_db->td_ta_event_getmsg_p == NULL");
 
   if (debug_threads)
-    fprintf (stderr, "Thread creation event.\n");
+    debug_printf ("Thread creation event.\n");
 
   /* FIXME: This assumes we don't get another event.
      In the LinuxThreads implementation, this is safe,
@@ -289,8 +289,8 @@ find_one_thread (ptid_t ptid)
 	   lwpid, thread_db_err_str (err));
 
   if (debug_threads)
-    fprintf (stderr, "Found thread %ld (LWP %d)\n",
-	     ti.ti_tid, ti.ti_lid);
+    debug_printf ("Found thread %ld (LWP %d)\n",
+		  ti.ti_tid, ti.ti_lid);
 
   if (lwpid != ti.ti_lid)
     {
@@ -326,8 +326,8 @@ attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
   struct lwp_info *lwp;
 
   if (debug_threads)
-    fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
-	     ti_p->ti_tid, ti_p->ti_lid);
+    debug_printf ("Attaching to thread %ld (LWP %d)\n",
+		  ti_p->ti_tid, ti_p->ti_lid);
   linux_attach_lwp (ti_p->ti_lid);
   lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
   if (lwp == NULL)
@@ -432,8 +432,8 @@ thread_db_find_new_threads (void)
 					 TD_THR_LOWEST_PRIORITY,
 					 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
       if (debug_threads)
-	fprintf (stderr, "Found %d threads in iteration %d.\n",
-		 new_thread_count, iteration);
+	debug_printf ("Found %d threads in iteration %d.\n",
+		      new_thread_count, iteration);
 
       if (new_thread_count != 0)
 	{
@@ -546,7 +546,7 @@ thread_db_load_search (void)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -595,7 +595,7 @@ try_thread_db_load_1 (void *handle)
       if ((a) == NULL)						\
 	{							\
 	  if (debug_threads)					\
-	    fprintf (stderr, "dlsym: %s\n", dlerror ());	\
+	    debug_printf ("dlsym: %s\n", dlerror ());		\
 	  if (required)						\
 	    {							\
 	      free (tdb);					\
@@ -613,7 +613,7 @@ try_thread_db_load_1 (void *handle)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -663,13 +663,13 @@ try_thread_db_load (const char *library)
   void *handle;
 
   if (debug_threads)
-    fprintf (stderr, "Trying host libthread_db library: %s.\n",
-	     library);
+    debug_printf ("Trying host libthread_db library: %s.\n",
+		  library);
   handle = dlopen (library, RTLD_NOW);
   if (handle == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "dlopen failed: %s.\n", dlerror ());
+	debug_printf ("dlopen failed: %s.\n", dlerror ());
       return 0;
     }
 
@@ -786,7 +786,7 @@ thread_db_load_search (void)
 
   free_char_ptr_vec (dir_vec);
   if (debug_threads)
-    fprintf (stderr, "thread_db_load_search returning %d\n", rc);
+    debug_printf ("thread_db_load_search returning %d\n", rc);
   return rc;
 }
 
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 13b3ff6..3706577 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -61,6 +61,8 @@
 
 */
 
+#ifdef IN_PROCESS_AGENT
+
 static void trace_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 static void
@@ -81,6 +83,19 @@ trace_vdebug (const char *fmt, ...)
       trace_vdebug ((fmt), ##args);		\
   } while (0)
 
+#else
+
+#define trace_debug_1(level, fmt, args...)	\
+  do {						\
+    if (level <= debug_threads)			\
+      {						\
+	debug_printf ((fmt), ##args);		\
+	debug_printf ("\n");			\
+      }						\
+  } while (0)
+
+#endif
+
 #define trace_debug(FMT, args...)		\
   trace_debug_1 (1, FMT, ##args)
 
@@ -338,7 +353,7 @@ tracepoint_look_up_symbols (void)
       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name);
+	    debug_printf ("symbol `%s' not found\n", symbol_list[i].name);
 	  return;
 	}
     }
diff --git a/gdb/testsuite/gdb.server/server-mon.exp b/gdb/testsuite/gdb.server/server-mon.exp
index 05f63e7..58b1df2 100644
--- a/gdb/testsuite/gdb.server/server-mon.exp
+++ b/gdb/testsuite/gdb.server/server-mon.exp
@@ -50,3 +50,7 @@ gdb_test "monitor set debug 1" "Debug output enabled\\."
 gdb_test "monitor set debug 0" "Debug output disabled\\."
 gdb_test "monitor set remote-debug 1" "Protocol debug output enabled\\."
 gdb_test "monitor set remote-debug 0" "Protocol debug output disabled\\."
+gdb_test "monitor set debug-format all" \
+    "All extra debug format options enabled\\."
+gdb_test "monitor set debug-format none" \
+    "All extra debug format options disabled\\."

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-17 22:45                 ` Doug Evans
@ 2014-01-18  8:25                   ` Eli Zaretskii
  2014-01-20 16:14                   ` Pedro Alves
  1 sibling, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2014-01-18  8:25 UTC (permalink / raw)
  To: Doug Evans; +Cc: palves, yao, gdb-patches

> From: Doug Evans <dje@google.com>
> Date: Fri, 17 Jan 2014 14:45:00 -0800
> cc: gdb-patches <gdb-patches@sourceware.org>
> 
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -3,6 +3,14 @@
>  
>  *** Changes since GDB 7.7
>  
> +* New features in the GDB remote stub, GDBserver
> +
> +  ** New option --debug-format=option1[,option2,...] allows one to add
> +     additional text to each debugging message.  At present only timestamps
> +     are supported: --debug-format=timestamps.

I stumbled on "debugging message".  Why not say "to each output"
instead?

> +The @option{--debug-format=option1[,option2,...]} option tells
> +@code{gdbserver} to include additional information in each line of
> +debugging output.  Possible options are:

Again, "each line of debugging output" is somewhat vague.  (Aren't
there multi-line outputs, and if so, will gdbserver indeed precede
each of these lines with a timestamp?)  I hope we can find something
more clear.  Also, an example will help here.

Also, a @cindex entry here would be nice.

> @@ -44342,6 +44374,24 @@ Instruct @code{gdbserver} to display remote protocol debug output.
>  This option is intended for @code{gdbserver} development and for bug reports to
>  the developers.
>  
> +@item --debug-format=option1@r{[},option2,...@r{]}
> +Instruct @code{gdbserver} to include extra information in each line
> +of debugging output.
> +
> +Possible options are:

Why is this described twice?  I suggest to describe once, and leave a
cross-reference in the second place.

The documentation part is OK with these fixed.

Thanks.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-16 19:01       ` Doug Evans
                           ` (3 preceding siblings ...)
  2014-01-17 12:59         ` Yao Qi
@ 2014-01-20  5:42         ` Tom Tromey
  2014-01-20 19:51           ` Doug Evans
  4 siblings, 1 reply; 26+ messages in thread
From: Tom Tromey @ 2014-01-20  5:42 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, Pedro Alves, gdb-patches

>>>>> "Doug" == Doug Evans <dje@google.com> writes:

>> gdbserver has used gnulib, which means we can use gettimeofday
>> unconditionally in gdbserver?

Doug> Left for another day.
Doug> There's no loss in splitting this up into steps.

This is only true if you are planning to actually do the next step.

Doug> [The next step will itself need to be spit up into several steps: get
Doug> gettimeofday from gnulib, and then have gdbserver (and gdb) use it -
Doug> it may be a nop for gdb, say gnulib being preferred over libiberty,
Doug> but something to be confirmed nonetheless.]

FWIW I have a patch to link gdbserver against libiberty.
I'll try to submit it soon.

Tom

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-17 22:45                 ` Doug Evans
  2014-01-18  8:25                   ` Eli Zaretskii
@ 2014-01-20 16:14                   ` Pedro Alves
  2014-01-22 23:06                     ` Doug Evans
  1 sibling, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2014-01-20 16:14 UTC (permalink / raw)
  To: Doug Evans; +Cc: Yao Qi, eliz, gdb-patches

On 01/17/2014 10:45 PM, Doug Evans wrote:
> Pedro Alves writes:
>  > On 01/16/2014 11:37 PM, Doug Evans wrote:
>  > > +++ b/gdb/gdbserver/debug.c
>  > > @@ -0,0 +1,86 @@
>  > > +/* General utility routines for the remote server for GDB.
>  > 
>  > These ...
>  > 
>  > > +++ b/gdb/gdbserver/debug.h
>  > > @@ -0,0 +1,48 @@
>  > > +/* General utility routines for the remote server for GDB.
>  > 
>  > ... need updating.
>  > 
>  > > +#endif /* UTILS_H */
>  > 
>  > This too -- DEBUG_H.
>  > 
>  > > +debug_printf (const char *msg, ...)
>  > > +{
>  > > +  va_list args;
>  > > +#ifdef HAVE_GETTIMEOFDAY
>  > > +  static int new_line = 1;
>  > > +
>  > 
>  > Note this isn't thread safe either.  Maybe add a comment
>  > in case we ever try to make timespamping work in the IPA?
>  > 
>  > > +  options = delim_string_to_char_ptr_vec (arg + sizeof ("--debug=") - 1, ',');
>  > > +
>  > > +  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
>  > > +    {
>  > 
>  > I don't see much point in this extra copying over plain old strtok
>  > (already used in the --disable-packet= code), but OK...
>  > 
>  > >        else if (strcmp (*next_arg, "--debug") == 0)
>  > > -	debug_threads = 1;
>  > > +	parse_debug_options (*next_arg);
>  > > +      else if (strncmp (*next_arg, "--debug=", sizeof ("--debug=") - 1) == 0)
>  > > +	{
>  > > +	  if (parse_debug_options (*next_arg) != 0)
>  > > +	    exit (1);
>  > > +	}
>  > 
>  > This should be hooked in "monitor set debug ..." as well.
>  > 
>  > Otherwise looks good to me.
> 
> I changed --debug= to --debug-format=, and added monitor commands.

Thanks.  I have no further comments.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] gdbserver: Delimit debugging output for readability
  2014-01-20  5:42         ` Tom Tromey
@ 2014-01-20 19:51           ` Doug Evans
  0 siblings, 0 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-20 19:51 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Yao Qi, Pedro Alves, gdb-patches

On Sun, Jan 19, 2014 at 9:42 PM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Doug" == Doug Evans <dje@google.com> writes:
>
>>> gdbserver has used gnulib, which means we can use gettimeofday
>>> unconditionally in gdbserver?
>
> Doug> Left for another day.
> Doug> There's no loss in splitting this up into steps.
>
> This is only true if you are planning to actually do the next step.

You deleted the two immediately preceding lines, sigh.

>>>> This patch adds a check for gettimeofday and doesn't fall back to using one
>>>> in libiberty or gnulib, leaving that for another day.

palves had already told me people were thinking of linking gdbserver
with libiberty for a different reason.
Plus it's hardly a stretch to have already imagined that happening.
And when that happened, yes I was planning on taking advantage of that.

Duh.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch
  2014-01-20 16:14                   ` Pedro Alves
@ 2014-01-22 23:06                     ` Doug Evans
  0 siblings, 0 replies; 26+ messages in thread
From: Doug Evans @ 2014-01-22 23:06 UTC (permalink / raw)
  To: Pedro Alves, eliz, Yao Qi; +Cc: gdb-patches

Eli writes:
 > The documentation part is OK with these fixed.

Pedro Alves writes:
 > > I changed --debug= to --debug-format=, and added monitor commands.
 > 
 > Thanks.  I have no further comments.

Here's what I committed.  Thanks.

commit 00abb91a8f38c92f5252af1fb503c195c9955533
Author: Doug Evans <dje@google.com>
Date:   Wed Jan 22 13:59:54 2014 -0800

    New gdbserver option --debug-format=timestamp.
    
    	New gdbserver option --debug-format=timestamp.
    	* NEWS: Mention it.
    
    	gdbserver/
    	* configure.ac (AC_CHECK_FUNCS): Add test for gettimeofday.
    	* configure: Regenerate.
    	* config.in: Regenerate.
    	* Makefile.in (SFILES): Add debug.c.
    	(OBS): Add debug.o.
    	* debug.c: New file.
    	* debug.h: New file.
    	* linux-aarch64-low.c (*): Update all debugging printfs to use
    	debug_printf instead of fprintf.
    	* linux-arm-low.c (*): Ditto.
    	* linux-cris-low.c (*): Ditto.
    	* linux-crisv32-low.c (*): Ditto.
    	* linux-m32r-low.c (*): Ditto.
    	* linux-sparc-low.c (*): Ditto.
    	* linux-x86.c (*): Ditto.
    	* linux-low.c (*): Ditto.
    	(linux_wait_1): Add calls to debug_enter, debug_exit.
    	(linux_wait): Remove redundant debugging printf.
    	(stop_all_lwps): Add calls to debug_enter, debug_exit.
    	(linux_resume, unstop_all_lwps): Ditto.
    	* mem-break.c (*): Update all debugging printfs to use
    	debug_printf instead of fprintf.
    	* remote-utils.c (*): Ditto.
    	* thread-db.c (*): Ditto.
    	* server.c #include <ctype.h>, "gdb_vecs.h".
    	(debug_threads): Moved to debug.c.
    	(*): Update all debugging printfs to use debug_printf instead of
    	fprintf.
    	(start_inferior): Replace call to fflush with call to debug_flush.
    	(monitor_show_help): Mention set debug-format.
    	(parse_debug_format_options): New function.
    	(handle_monitor_command): Handle "monitor set debug-format".
    	(gdbserver_usage): Mention --debug-format.
    	(main): Parse --debug-format.
    	* server.h (debug_threads): Declaration moved to debug.h.
    	#include "debug.h".
    	* tracepoint.c (trace_debug_1) [!IN_PROCESS_AGENT]: Add version of
    	trace_debug_1 that uses debug_printf.
    	(tracepoint_look_up_symbols): Update all debugging printfs to use
    	debug_printf instead of fprintf.
    
    	doc/
    	* gdb.texinfo (Server): Mention --debug-format=all|none|timestamp.
    	(gdbserver man): Ditto.
    
    	testsuite/
    	* gdb.server/server-mon.exp: Add tests for "set debug-format".

diff --git a/gdb/NEWS b/gdb/NEWS
index 5a44a67..6b1aacb 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,14 @@
 
 *** Changes since GDB 7.7
 
+* New features in the GDB remote stub, GDBserver
+
+  ** New option --debug-format=option1[,option2,...] allows one to add
+     additional text to each output.  At present only timestamps
+     are supported: --debug-format=timestamps.
+     Timestamps can also be turned on with the
+     "monitor set debug-format timestamps" command from GDB.
+
 * The 'record instruction-history' command now starts counting instructions
   at one.  This also affects the instruction ranges reported by the
   'record function-call-history' command when given the /i modifier.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e77ca2a..a990d2a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18507,6 +18507,7 @@ connections and even in the @kbd{target extended-remote} mode.  The
 multiple instances of @code{gdbserver} running on the same host, since each
 instance closes its port after the first connection.
 
+@anchor{Other Command-Line Arguments for gdbserver}
 @subsubsection Other Command-Line Arguments for @code{gdbserver}
 
 @cindex @option{--debug}, @code{gdbserver} option
@@ -18517,6 +18518,23 @@ The @option{--remote-debug} option tells @code{gdbserver} to display
 remote protocol debug output.  These options are intended for
 @code{gdbserver} development and for bug reports to the developers.
 
+@cindex @option{--debug-format}, @code{gdbserver} option
+The @option{--debug-format=option1[,option2,...]} option tells
+@code{gdbserver} to include additional information in each output.
+Possible options are:
+
+@table @code
+@item none
+Turn off all extra information in debugging output.
+@item all
+Turn on all extra information in debugging output.
+@item timestamps
+Include a timestamp in each line of debugging output.
+@end table
+
+Options are processed in order.  Thus, for example, if @option{none}
+appears last then no additional information is added to debugging output.
+
 @cindex @option{--wrapper}, @code{gdbserver} option
 The @option{--wrapper} option specifies a wrapper to launch programs
 for debugging.  The option should be followed by the name of the
@@ -18587,6 +18605,22 @@ Disable or enable general debugging messages.
 Disable or enable specific debugging messages associated with the remote
 protocol (@pxref{Remote Protocol}).
 
+@item monitor set debug-format option1@r{[},option2,...@r{]}
+Specify additional text to add to debugging messages.
+Possible options are:
+
+@table @code
+@item none
+Turn off all extra information in debugging output.
+@item all
+Turn on all extra information in debugging output.
+@item timestamps
+Include a timestamp in each line of debugging output.
+@end table
+
+Options are processed in order.  Thus, for example, if @option{none}
+appears last then no additional information is added to debugging output.
+
 @item monitor set libthread-db-search-path [PATH]
 @cindex gdbserver, search path for @code{libthread_db}
 When this command is issued, @var{path} is a colon-separated list of
@@ -44342,6 +44376,11 @@ Instruct @code{gdbserver} to display remote protocol debug output.
 This option is intended for @code{gdbserver} development and for bug reports to
 the developers.
 
+@item --debug-format=option1@r{[},option2,...@r{]}
+Instruct @code{gdbserver} to include extra information in each line
+of debugging output.
+@xref{Other Command-Line Arguments for gdbserver}.
+
 @item --wrapper
 Specify a wrapper to launch programs
 for debugging.  The option should be followed by the name of the
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index e72ee6b..46324e6 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -141,7 +141,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(srcdir)/mem-break.c $(srcdir)/proc-service.c \
 	$(srcdir)/proc-service.list $(srcdir)/regcache.c \
 	$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
-	$(srcdir)/thread-db.c $(srcdir)/utils.c \
+	$(srcdir)/thread-db.c $(srcdir)/utils.c $(srcdir)/debug.c \
 	$(srcdir)/linux-arm-low.c $(srcdir)/linux-bfin-low.c \
 	$(srcdir)/linux-cris-low.c $(srcdir)/linux-crisv32-low.c \
 	${srcdir}/i386-low.c $(srcdir)/i387-fp.c \
@@ -173,7 +173,7 @@ SOURCES = $(SFILES)
 TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
 
 OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \
-      target.o waitstatus.o utils.o version.o vec.o gdb_vecs.o \
+      target.o waitstatus.o utils.o debug.o version.o vec.o gdb_vecs.o \
       mem-break.o hostio.o event-loop.o tracepoint.o xml-utils.o \
       common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \
       tdesc.o $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS)
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index e33cdea..1b9751f 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -66,6 +66,9 @@
 /* Define to 1 if you have the `getrlimit' function. */
 #undef HAVE_GETRLIMIT
 
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index fac7fb3..6d8a6a7 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4728,7 +4728,7 @@ fi
 
 done
 
-for ac_func in pread pwrite pread64 readlink
+for ac_func in gettimeofday pread pwrite pread64 readlink
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index dc8131c..0dfa4a9 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -82,7 +82,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 errno.h fcntl.h signal.h sys/file.h malloc.h dnl
 		 sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
 		 netinet/tcp.h arpa/inet.h)
-AC_CHECK_FUNCS(pread pwrite pread64 readlink)
+AC_CHECK_FUNCS(gettimeofday pread pwrite pread64 readlink)
 AC_REPLACE_FUNCS(vasprintf vsnprintf)
 
 GDB_AC_COMMON
diff --git a/gdb/gdbserver/debug.c b/gdb/gdbserver/debug.c
new file mode 100644
index 0000000..6f4d531
--- /dev/null
+++ b/gdb/gdbserver/debug.c
@@ -0,0 +1,98 @@
+/* Debugging routines for the remote server for GDB.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "server.h"
+#include <sys/time.h>
+
+/* Enable miscellaneous debugging output.  The name is historical - it
+   was originally used to debug LinuxThreads support.  */
+int debug_threads;
+
+/* Include timestamps in debugging output.  */
+int debug_timestamp;
+
+/* Print a debugging message.
+   If the text begins a new line it is preceded by a timestamp, if the
+   system has gettimeofday.
+   We don't get fancy with newline checking, we just check whether the
+   previous call ended with "\n".  */
+
+void
+debug_printf (const char *msg, ...)
+{
+  va_list args;
+#if defined (HAVE_GETTIMEOFDAY) && !defined (IN_PROCESS_AGENT)
+  /* N.B. Not thread safe, and can't be used, as is, with IPA.  */
+  static int new_line = 1;
+
+  if (debug_timestamp && new_line)
+    {
+      struct timeval tm;
+
+      gettimeofday (&tm, NULL);
+
+      /* 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);
+    }
+#endif
+
+  va_start (args, msg);
+  vfprintf (stderr, msg, args);
+  va_end (args);
+
+#if defined (HAVE_GETTIMEOFDAY) && !defined (IN_PROCESS_AGENT)
+  if (*msg)
+    new_line = msg[strlen (msg) - 1] == '\n';
+#endif
+}
+
+/* Flush debugging output.
+   This is called, for example, when starting an inferior to ensure all debug
+   output thus far appears before any inferior output.  */
+
+void
+debug_flush (void)
+{
+  fflush (stderr);
+}
+
+/* Notify the user that the code is entering FUNCTION_NAME.
+   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
+
+   This is intended to be called via the debug_enter macro.  */
+
+void
+do_debug_enter (const char *function_name)
+{
+  if (function_name != NULL)
+    debug_printf (">>>> entering %s\n", function_name);
+}
+
+/* Notify the user that the code is exiting FUNCTION_NAME.
+   FUNCTION_NAME is the name of the calling function, or NULL if unknown.
+
+   This is intended to be called via the debug_exit macro.  */
+
+void
+do_debug_exit (const char *function_name)
+{
+  if (function_name != NULL)
+    debug_printf ("<<<< exiting %s\n", function_name);
+}
diff --git a/gdb/gdbserver/debug.h b/gdb/gdbserver/debug.h
new file mode 100644
index 0000000..0f056ca
--- /dev/null
+++ b/gdb/gdbserver/debug.h
@@ -0,0 +1,55 @@
+/* Debugging routines for the remote server for GDB.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/* We declare debug format variables here, and debug_threads but no other
+   debug content variables (e.g., not remote_debug) because while this file
+   is not currently used by IPA it may be some day, and IPA may have its own
+   set of debug content variables.  It's ok to declare debug_threads here
+   because it is misnamed - a better name is debug_basic or some such,
+   which can work for any program, gdbserver or IPA.  If/when this file is
+   used with IPA it is recommended to fix debug_thread's name.  */
+extern int debug_threads;
+extern int debug_timestamp;
+
+void debug_printf (const char *msg, ...) ATTRIBUTE_PRINTF (1, 2);
+void debug_flush (void);
+void do_debug_enter (const char *function_name);
+void do_debug_exit (const char *function_name);
+
+/* These macros are for use in major functions that produce a lot of
+   debugging output.  They help identify in the mass of debugging output
+   when these functions enter and exit.  debug_enter is intended to be
+   called at the start of a function, before any other debugging output.
+   debug_exit is intended to be called at the end of the same function,
+   after all debugging output.  */
+#ifdef FUNCTION_NAME
+#define debug_enter() \
+  do { do_debug_enter (FUNCTION_NAME); } while (0)
+#define debug_exit() \
+  do { do_debug_exit (FUNCTION_NAME); } while (0)
+#else
+#define debug_enter() \
+  do { } while (0)
+#define debug_exit() \
+  do { } while (0)
+#endif
+
+#endif /* DEBUG_H */
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index 1b0da6c..e7d3e4f 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -323,7 +323,7 @@ aarch64_get_pc (struct regcache *regcache)
 
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index da5085c..fb6ff68 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -256,7 +256,7 @@ arm_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-cris-low.c b/gdb/gdbserver/linux-cris-low.c
index d229d43..2abd987 100644
--- a/gdb/gdbserver/linux-cris-low.c
+++ b/gdb/gdbserver/linux-cris-low.c
@@ -67,7 +67,7 @@ cris_get_pc (struct regcache *regcache, void)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-crisv32-low.c b/gdb/gdbserver/linux-crisv32-low.c
index e4ebb62..a16a656 100644
--- a/gdb/gdbserver/linux-crisv32-low.c
+++ b/gdb/gdbserver/linux-crisv32-low.c
@@ -63,7 +63,7 @@ cris_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 01d0e84..bac6134 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -475,7 +475,7 @@ get_pc (struct lwp_info *lwp)
   pc = (*the_low_target.get_pc) (regcache);
 
   if (debug_threads)
-    fprintf (stderr, "pc is 0x%lx\n", (long) pc);
+    debug_printf ("pc is 0x%lx\n", (long) pc);
 
   current_inferior = saved_inferior;
   return pc;
@@ -520,7 +520,7 @@ get_stop_pc (struct lwp_info *lwp)
     stop_pc -= the_low_target.decr_pc_after_break;
 
   if (debug_threads)
-    fprintf (stderr, "stop pc is 0x%lx\n", (long) stop_pc);
+    debug_printf ("stop pc is 0x%lx\n", (long) stop_pc);
 
   return stop_pc;
 }
@@ -692,8 +692,7 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial)
   if (linux_proc_pid_is_stopped (lwpid))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Attached to a stopped process\n");
+	debug_printf ("Attached to a stopped process\n");
 
       /* The process is definitely stopped.  It is in a job control
 	 stop, unless the kernel predates the TASK_STOPPED /
@@ -824,8 +823,8 @@ linux_attach (unsigned long pid)
 		      new_threads_found++;
 
 		      if (debug_threads)
-			fprintf (stderr, "\
-Found and attached to new lwp %ld\n", lwp);
+			debug_printf ("Found and attached to new lwp %ld\n",
+				      lwp);
 		    }
 		}
 
@@ -898,18 +897,16 @@ linux_kill_one_lwp (struct lwp_info *lwp)
   errno = 0;
   kill (pid, SIGKILL);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 
   errno = 0;
   ptrace (PTRACE_KILL, pid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
   if (debug_threads)
-    fprintf (stderr,
-	     "LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
-	     target_pid_to_str (ptid_of (lwp)),
-	     errno ? strerror (errno) : "OK");
+    debug_printf ("LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
+		  target_pid_to_str (ptid_of (lwp)),
+		  errno ? strerror (errno) : "OK");
 }
 
 /* Callback for `find_inferior'.  Kills an lwp of a given process,
@@ -934,8 +931,8 @@ kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
   if (lwpid_of (lwp) == pid)
     {
       if (debug_threads)
-	fprintf (stderr, "lkop: is last of process %s\n",
-		 target_pid_to_str (entry->id));
+	debug_printf ("lkop: is last of process %s\n",
+		      target_pid_to_str (entry->id));
       return 0;
     }
 
@@ -975,14 +972,14 @@ linux_kill (int pid)
   if (lwp == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: cannot find lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: cannot find lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr, "lk_1: killing lwp %ld, for pid: %d\n",
-		 lwpid_of (lwp), pid);
+	debug_printf ("lk_1: killing lwp %ld, for pid: %d\n",
+		      lwpid_of (lwp), pid);
 
       do
 	{
@@ -1031,9 +1028,8 @@ get_detach_signal (struct thread_info *thread)
   if (!WIFSTOPPED (status))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s hasn't stopped: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s hasn't stopped: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1041,10 +1037,9 @@ get_detach_signal (struct thread_info *thread)
   if (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had stopped with extended "
-		 "status: no pending signal\n",
-		 target_pid_to_str (ptid_of (lp)));
+	debug_printf ("GPS: lwp %s had stopped with extended "
+		      "status: no pending signal\n",
+		      target_pid_to_str (ptid_of (lp)));
       return 0;
     }
 
@@ -1053,10 +1048,9 @@ get_detach_signal (struct thread_info *thread)
   if (program_signals_p && !program_signals[signo])
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, but it is in nopass state\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else if (!program_signals_p
@@ -1066,20 +1060,19 @@ get_detach_signal (struct thread_info *thread)
 	   && (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s had signal %s, "
-		 "but we don't know if we should pass it.  Default to not.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s had signal %s, "
+		      "but we don't know if we should pass it. "
+		      "Default to not.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
       return 0;
     }
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "GPS: lwp %s has pending signal %s: delivering it.\n",
-		 target_pid_to_str (ptid_of (lp)),
-		 gdb_signal_to_string (signo));
+	debug_printf ("GPS: lwp %s has pending signal %s: delivering it.\n",
+		      target_pid_to_str (ptid_of (lp)),
+		      gdb_signal_to_string (signo));
 
       return WSTOPSIG (status);
     }
@@ -1100,9 +1093,8 @@ linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Sending SIGCONT to %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("Sending SIGCONT to %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       kill_lwp (lwpid_of (lwp), SIGCONT);
       lwp->stop_expected = 0;
@@ -1276,7 +1268,7 @@ linux_wait_for_lwp (ptid_t ptid, int *wstatp, int options)
   struct lwp_info *child = NULL;
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
+    debug_printf ("linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
 
   if (ptid_equal (ptid, minus_one_ptid))
     to_wait_for = -1;			/* any child */
@@ -1297,7 +1289,7 @@ retry:
       && (!WIFSTOPPED (*wstatp)
 	  || (WSTOPSIG (*wstatp) != 32
 	      && WSTOPSIG (*wstatp) != 33)))
-    fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp);
+    debug_printf ("Got an event from %d (%x)\n", ret, *wstatp);
 
   child = find_lwp_pid (pid_to_ptid (ret));
 
@@ -1404,7 +1396,7 @@ retry:
       current_inferior = get_lwp_thread (child);
       regcache = get_thread_regcache (current_inferior, 1);
       pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
+      debug_printf ("linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
       current_inferior = saved_inferior;
     }
 
@@ -1450,7 +1442,7 @@ handle_tracepoints (struct lwp_info *lwp)
   if (tpoint_related_event)
     {
       if (debug_threads)
-	fprintf (stderr, "got a tracepoint event\n");
+	debug_printf ("got a tracepoint event\n");
       return 1;
     }
 
@@ -1501,9 +1493,9 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
       int r;
 
       if (debug_threads)
-	fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Checking whether LWP %ld needs to move out of the "
+		      "jump pad.\n",
+		      lwpid_of (lwp));
 
       r = linux_fast_tracepoint_collecting (lwp, &status);
 
@@ -1527,9 +1519,9 @@ Checking whether LWP %ld needs to move out of the jump pad.\n",
 		}
 
 	      if (debug_threads)
-		fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...it does\n",
-		 lwpid_of (lwp));
+		debug_printf ("Checking whether LWP %ld needs to move out of "
+			      "the jump pad...it does\n",
+			      lwpid_of (lwp));
 	      current_inferior = saved_inferior;
 
 	      return 1;
@@ -1582,9 +1574,8 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
 	  if (lwp->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Cancelling fast exit-jump-pad: removing bkpt. "
-			 "stopping all threads momentarily.\n");
+		debug_printf ("Cancelling fast exit-jump-pad: removing bkpt. "
+			      "stopping all threads momentarily.\n");
 
 	      stop_all_lwps (1, lwp);
 	      cancel_breakpoints ();
@@ -1600,9 +1591,9 @@ Checking whether LWP %ld needs to move out of the jump pad...it does\n",
     }
 
   if (debug_threads)
-    fprintf (stderr, "\
-Checking whether LWP %ld needs to move out of the jump pad...no\n",
-	     lwpid_of (lwp));
+    debug_printf ("Checking whether LWP %ld needs to move out of the "
+		  "jump pad...no\n",
+		  lwpid_of (lwp));
 
   current_inferior = saved_inferior;
   return 0;
@@ -1617,8 +1608,8 @@ enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
   struct pending_signals *p_sig;
 
   if (debug_threads)
-    fprintf (stderr, "\
-Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
+    debug_printf ("Deferring signal %d for LWP %ld.\n",
+		  WSTOPSIG (*wstat), lwpid_of (lwp));
 
   if (debug_threads)
     {
@@ -1627,11 +1618,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
       for (sig = lwp->pending_signals_to_report;
 	   sig != NULL;
 	   sig = sig->prev)
-	fprintf (stderr,
-		 "   Already queued %d\n",
-		 sig->signal);
+	debug_printf ("   Already queued %d\n",
+		      sig->signal);
 
-      fprintf (stderr, "   (no more currently queued signals)\n");
+      debug_printf ("   (no more currently queued signals)\n");
     }
 
   /* Don't enqueue non-RT signals if they are already in the deferred
@@ -1648,11 +1638,10 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
 	  if (sig->signal == WSTOPSIG (*wstat))
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Not requeuing already queued non-RT signal %d"
-			 " for LWP %ld\n",
-			 sig->signal,
-			 lwpid_of (lwp));
+		debug_printf ("Not requeuing already queued non-RT signal %d"
+			      " for LWP %ld\n",
+			      sig->signal,
+			      lwpid_of (lwp));
 	      return;
 	    }
 	}
@@ -1690,8 +1679,8 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
       *p_sig = NULL;
 
       if (debug_threads)
-	fprintf (stderr, "Reporting deferred signal %d for LWP %ld.\n",
-		 WSTOPSIG (*wstat), lwpid_of (lwp));
+	debug_printf ("Reporting deferred signal %d for LWP %ld.\n",
+		      WSTOPSIG (*wstat), lwpid_of (lwp));
 
       if (debug_threads)
 	{
@@ -1700,11 +1689,10 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 	  for (sig = lwp->pending_signals_to_report;
 	       sig != NULL;
 	       sig = sig->prev)
-	    fprintf (stderr,
-		     "   Still queued %d\n",
-		     sig->signal);
+	    debug_printf ("   Still queued %d\n",
+			  sig->signal);
 
-	  fprintf (stderr, "   (no more queued signals)\n");
+	  debug_printf ("   (no more queued signals)\n");
 	}
 
       return 1;
@@ -1734,9 +1722,8 @@ cancel_breakpoint (struct lwp_info *lwp)
   if ((*the_low_target.breakpoint_at) (lwp->stop_pc))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: Push back breakpoint for %s\n",
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: Push back breakpoint for %s\n",
+		      target_pid_to_str (ptid_of (lwp)));
 
       /* Back up the PC if necessary.  */
       if (the_low_target.decr_pc_after_break)
@@ -1752,10 +1739,9 @@ cancel_breakpoint (struct lwp_info *lwp)
   else
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "CB: No breakpoint found at %s for [%s]\n",
-		 paddress (lwp->stop_pc),
-		 target_pid_to_str (ptid_of (lwp)));
+	debug_printf ("CB: No breakpoint found at %s for [%s]\n",
+		      paddress (lwp->stop_pc),
+		      target_pid_to_str (ptid_of (lwp)));
     }
 
   current_inferior = saved_inferior;
@@ -1788,7 +1774,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       event_child = (struct lwp_info *)
 	find_inferior (&all_lwps, status_pending_p_callback, &ptid);
       if (debug_threads && event_child)
-	fprintf (stderr, "Got a pending child %ld\n", lwpid_of (event_child));
+	debug_printf ("Got a pending child %ld\n", lwpid_of (event_child));
     }
   else
     {
@@ -1816,8 +1802,8 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
   if (event_child != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
-		 lwpid_of (event_child), event_child->status_pending);
+	debug_printf ("Got an event from pending child %ld (%04x)\n",
+		      lwpid_of (event_child), event_child->status_pending);
       *wstat = event_child->status_pending;
       event_child->status_pending_p = 0;
       event_child->status_pending = 0;
@@ -1847,7 +1833,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if ((options & WNOHANG) && event_child == NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "WNOHANG set, no event found\n");
+	    debug_printf ("WNOHANG set, no event found\n");
 	  return 0;
 	}
 
@@ -1873,14 +1859,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
       if (! WIFSTOPPED (*wstat))
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld exiting\n", lwpid_of (event_child));
+	    debug_printf ("LWP %ld exiting\n", lwpid_of (event_child));
 
 	  /* If the last thread is exiting, just return.  */
 	  if (last_thread_of_process_p (current_inferior))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "LWP %ld is last lwp of process\n",
-			 lwpid_of (event_child));
+		debug_printf ("LWP %ld is last lwp of process\n",
+			      lwpid_of (event_child));
 	      return lwpid_of (event_child);
 	    }
 
@@ -1888,14 +1874,14 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	    {
 	      current_inferior = (struct thread_info *) all_threads.head;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now %ld\n",
-			 lwpid_of (get_thread_lwp (current_inferior)));
+		debug_printf ("Current inferior is now %ld\n",
+			      lwpid_of (get_thread_lwp (current_inferior)));
 	    }
 	  else
 	    {
 	      current_inferior = NULL;
 	      if (debug_threads)
-		fprintf (stderr, "Current inferior is now <NULL>\n");
+		debug_printf ("Current inferior is now <NULL>\n");
 	    }
 
 	  /* If we were waiting for this particular child to do something...
@@ -1938,7 +1924,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 	  int should_stop;
 
 	  if (debug_threads)
-	    fprintf (stderr, "Expected stop.\n");
+	    debug_printf ("Expected stop.\n");
 	  event_child->stop_expected = 0;
 
 	  should_stop = (current_inferior->last_resume_kind == resume_stop
@@ -2082,9 +2068,8 @@ select_event_lwp (struct lwp_info **orig_lp)
   if (event_lp != NULL)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "SEL: Select single-step %s\n",
-		 target_pid_to_str (ptid_of (event_lp)));
+	debug_printf ("SEL: Select single-step %s\n",
+		      target_pid_to_str (ptid_of (event_lp)));
     }
   else
     {
@@ -2099,9 +2084,8 @@ select_event_lwp (struct lwp_info **orig_lp)
 	((num_events * (double) rand ()) / (RAND_MAX + 1.0));
 
       if (debug_threads && num_events > 1)
-	fprintf (stderr,
-		 "SEL: Found %d SIGTRAP events, selecting #%d\n",
-		 num_events, random_selector);
+	debug_printf ("SEL: Found %d SIGTRAP events, selecting #%d\n",
+		      num_events, random_selector);
 
       event_lp = (struct lwp_info *) find_inferior (&all_lwps,
 						    select_event_lwp_callback,
@@ -2191,8 +2175,8 @@ linux_stabilize_threads (void)
   if (lwp_stuck != NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "can't stabilize, LWP %ld is stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("can't stabilize, LWP %ld is stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
       return;
     }
 
@@ -2243,8 +2227,8 @@ linux_stabilize_threads (void)
 	= (struct lwp_info *) find_inferior (&all_lwps,
 					 stuck_in_jump_pad_callback, NULL);
       if (lwp_stuck != NULL)
-	fprintf (stderr, "couldn't stabilize, LWP %ld got stuck in jump pad\n",
-		 lwpid_of (lwp_stuck));
+	debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n",
+		      lwpid_of (lwp_stuck));
     }
 }
 
@@ -2265,6 +2249,12 @@ linux_wait_1 (ptid_t ptid,
   int trace_event;
   int in_step_range;
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("linux_wait_1: [%s]\n", target_pid_to_str (ptid));
+    }
+
   /* Translate generic target options into linux options.  */
   options = __WALL;
   if (target_options & TARGET_WNOHANG)
@@ -2309,13 +2299,20 @@ retry:
   else
     {
       if (debug_threads)
-	fprintf (stderr, "step_over_bkpt set [%s], doing a blocking wait\n",
-		 target_pid_to_str (step_over_bkpt));
+	debug_printf ("step_over_bkpt set [%s], doing a blocking wait\n",
+		      target_pid_to_str (step_over_bkpt));
       pid = linux_wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
     }
 
   if (pid == 0) /* only if TARGET_WNOHANG */
-    return null_ptid;
+    {
+      if (debug_threads)
+	{
+	  debug_printf ("linux_wait_1 ret = null_ptid\n");
+	  debug_exit ();
+	}
+      return null_ptid;
+    }
 
   event_child = get_thread_lwp (current_inferior);
 
@@ -2341,9 +2338,13 @@ retry:
 	      ourstatus->value.integer = WEXITSTATUS (w);
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild exited with retcode = %x \n",
-			 WEXITSTATUS (w));
+		{
+		  debug_printf ("linux_wait_1 ret = %s, exited with "
+				"retcode %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WEXITSTATUS (w));
+		  debug_exit ();
+		}
 	    }
 	  else
 	    {
@@ -2351,10 +2352,13 @@ retry:
 	      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "\nChild terminated with signal = %x \n",
-			 WTERMSIG (w));
-
+		{
+		  debug_printf ("linux_wait_1 ret = %s, terminated with "
+				"signal %d\n",
+				target_pid_to_str (ptid_of (event_child)),
+				WTERMSIG (w));
+		  debug_exit ();
+		}
 	    }
 
 	  return ptid_of (event_child);
@@ -2409,7 +2413,7 @@ retry:
 	     already handled it.  So next time we resume (from this
 	     PC), we should step over it.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 
 	  if (breakpoint_here (event_child->stop_pc))
 	    event_child->need_step_over = 1;
@@ -2435,10 +2439,9 @@ retry:
       && agent_loaded_p ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Got signal %d for LWP %ld.  Check if we need "
-		 "to defer or adjust it.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Got signal %d for LWP %ld.  Check if we need "
+		      "to defer or adjust it.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       /* Allow debugging the jump pad itself.  */
       if (current_inferior->last_resume_kind != resume_step
@@ -2447,9 +2450,8 @@ retry:
 	  enqueue_one_deferred_signal (event_child, &w);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred (in jump pad)\n",
-		     WSTOPSIG (w), lwpid_of (event_child));
+	    debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n",
+			  WSTOPSIG (w), lwpid_of (event_child));
 
 	  linux_resume_one_lwp (event_child, 0, 0, NULL);
 	  goto retry;
@@ -2459,11 +2461,10 @@ retry:
   if (event_child->collecting_fast_tracepoint)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-LWP %ld was trying to move out of the jump pad (%d).  \
-Check if we're already there.\n",
-		 lwpid_of (event_child),
-		 event_child->collecting_fast_tracepoint);
+	debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
+		      "Check if we're already there.\n",
+		      lwpid_of (event_child),
+		      event_child->collecting_fast_tracepoint);
 
       trace_event = 1;
 
@@ -2476,9 +2477,8 @@ Check if we're already there.\n",
 	  if (event_child->exit_jump_pad_bkpt != NULL)
 	    {
 	      if (debug_threads)
-		fprintf (stderr,
-			 "No longer need exit-jump-pad bkpt; removing it."
-			 "stopping all threads momentarily.\n");
+		debug_printf ("No longer need exit-jump-pad bkpt; removing it."
+			      "stopping all threads momentarily.\n");
 
 	      /* Other running threads could hit this breakpoint.
 		 We don't handle moribund locations like GDB does,
@@ -2502,25 +2502,33 @@ Check if we're already there.\n",
       if (event_child->collecting_fast_tracepoint == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "fast tracepoint finished "
-		     "collecting successfully.\n");
+	    debug_printf ("fast tracepoint finished "
+			  "collecting successfully.\n");
 
 	  /* We may have a deferred signal to report.  */
 	  if (dequeue_one_deferred_signal (event_child, &w))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "dequeued one signal.\n");
+		debug_printf ("dequeued one signal.\n");
 	    }
 	  else
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "no deferred signals.\n");
+		debug_printf ("no deferred signals.\n");
 
 	      if (stabilizing_threads)
 		{
 		  ourstatus->kind = TARGET_WAITKIND_STOPPED;
 		  ourstatus->value.sig = GDB_SIGNAL_0;
+
+		  if (debug_threads)
+		    {
+		      debug_printf ("linux_wait_1 ret = %s, stopped "
+				    "while stabilizing threads\n",
+				    target_pid_to_str (ptid_of (event_child)));
+		      debug_exit ();
+		    }
+
 		  return ptid_of (event_child);
 		}
 	    }
@@ -2554,8 +2562,8 @@ Check if we're already there.\n",
       siginfo_t info, *info_p;
 
       if (debug_threads)
-	fprintf (stderr, "Ignored signal %d for LWP %ld.\n",
-		 WSTOPSIG (w), lwpid_of (event_child));
+	debug_printf ("Ignored signal %d for LWP %ld.\n",
+		      WSTOPSIG (w), lwpid_of (event_child));
 
       if (ptrace (PTRACE_GETSIGINFO, lwpid_of (event_child),
 		  (PTRACE_TYPE_ARG3) 0, &info) == 0)
@@ -2600,16 +2608,16 @@ Check if we're already there.\n",
       if (debug_threads)
 	{
 	  if (bp_explains_trap)
-	    fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+	    debug_printf ("Hit a gdbserver breakpoint.\n");
 	  if (step_over_finished)
-	    fprintf (stderr, "Step-over finished.\n");
+	    debug_printf ("Step-over finished.\n");
 	  if (trace_event)
-	    fprintf (stderr, "Tracepoint event.\n");
+	    debug_printf ("Tracepoint event.\n");
 	  if (lwp_in_step_range (event_child))
-	    fprintf (stderr, "Range stepping pc 0x%s [0x%s, 0x%s).\n",
-		     paddress (event_child->stop_pc),
-		     paddress (event_child->step_range_start),
-		     paddress (event_child->step_range_end));
+	    debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).\n",
+			  paddress (event_child->stop_pc),
+			  paddress (event_child->step_range_start),
+			  paddress (event_child->step_range_end));
 	}
 
       /* We're not reporting this breakpoint to GDB, so apply the
@@ -2629,7 +2637,7 @@ Check if we're already there.\n",
 	 going to keep waiting, so use proceed, which handles stepping
 	 over the next breakpoint.  */
       if (debug_threads)
-	fprintf (stderr, "proceeding all threads.\n");
+	debug_printf ("proceeding all threads.\n");
 
       if (step_over_finished)
 	unsuspend_all_lwps (event_child);
@@ -2643,16 +2651,16 @@ Check if we're already there.\n",
       if (current_inferior->last_resume_kind == resume_step)
 	{
 	  if (event_child->step_range_start == event_child->step_range_end)
-	    fprintf (stderr, "GDB wanted to single-step, reporting event.\n");
+	    debug_printf ("GDB wanted to single-step, reporting event.\n");
 	  else if (!lwp_in_step_range (event_child))
-	    fprintf (stderr, "Out of step range, reporting event.\n");
+	    debug_printf ("Out of step range, reporting event.\n");
 	}
       if (event_child->stopped_by_watchpoint)
-	fprintf (stderr, "Stopped by watchpoint.\n");
+	debug_printf ("Stopped by watchpoint.\n");
       if (gdb_breakpoint_here (event_child->stop_pc))
-	fprintf (stderr, "Stopped by GDB breakpoint.\n");
+	debug_printf ("Stopped by GDB breakpoint.\n");
       if (debug_threads)
-	fprintf (stderr, "Hit a non-gdbserver trap event.\n");
+	debug_printf ("Hit a non-gdbserver trap event.\n");
     }
 
   /* Alright, we're going to report a stop.  */
@@ -2730,10 +2738,12 @@ Check if we're already there.\n",
   gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait ret = %s, %d, %d\n",
-	     target_pid_to_str (ptid_of (event_child)),
-	     ourstatus->kind,
-	     ourstatus->value.sig);
+    {
+      debug_printf ("linux_wait_1 ret = %s, %d, %d\n",
+		    target_pid_to_str (ptid_of (event_child)),
+		    ourstatus->kind, ourstatus->value.sig);
+      debug_exit ();
+    }
 
   return ptid_of (event_child);
 }
@@ -2772,9 +2782,6 @@ linux_wait (ptid_t ptid,
 {
   ptid_t event_ptid;
 
-  if (debug_threads)
-    fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
-
   /* Flush the async file first.  */
   if (target_is_async_p ())
     async_file_flush ();
@@ -2837,13 +2844,13 @@ send_sigstop (struct lwp_info *lwp)
   if (lwp->stop_expected)
     {
       if (debug_threads)
-	fprintf (stderr, "Have pending sigstop for lwp %d\n", pid);
+	debug_printf ("Have pending sigstop for lwp %d\n", pid);
 
       return;
     }
 
   if (debug_threads)
-    fprintf (stderr, "Sending sigstop to lwp %d\n", pid);
+    debug_printf ("Sending sigstop to lwp %d\n", pid);
 
   lwp->stop_expected = 1;
   kill_lwp (pid, SIGSTOP);
@@ -2912,8 +2919,8 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "wait_for_sigstop: LWP %ld already stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("wait_for_sigstop: LWP %ld already stopped\n",
+		      lwpid_of (lwp));
       return;
     }
 
@@ -2926,7 +2933,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   ptid = lwp->head.id;
 
   if (debug_threads)
-    fprintf (stderr, "wait_for_sigstop: pulling one event\n");
+    debug_printf ("wait_for_sigstop: pulling one event\n");
 
   pid = linux_wait_for_event (ptid, &wstat, __WALL);
 
@@ -2936,14 +2943,14 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   if (WIFSTOPPED (wstat))
     {
       if (debug_threads)
-	fprintf (stderr, "LWP %ld stopped with signal %d\n",
-		 lwpid_of (lwp), WSTOPSIG (wstat));
+	debug_printf ("LWP %ld stopped with signal %d\n",
+		      lwpid_of (lwp), WSTOPSIG (wstat));
 
       if (WSTOPSIG (wstat) != SIGSTOP)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n",
-		     lwpid_of (lwp), wstat);
+	    debug_printf ("LWP %ld stopped with non-sigstop status %06x\n",
+			  lwpid_of (lwp), wstat);
 
 	  lwp->status_pending_p = 1;
 	  lwp->status_pending = wstat;
@@ -2952,7 +2959,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Process %d exited while stopping LWPs\n", pid);
+	debug_printf ("Process %d exited while stopping LWPs\n", pid);
 
       lwp = find_lwp_pid (pid_to_ptid (pid));
       if (lwp)
@@ -2973,7 +2980,7 @@ wait_for_sigstop (struct inferior_list_entry *entry)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "Previously current thread died.\n");
+	debug_printf ("Previously current thread died.\n");
 
       if (non_stop)
 	{
@@ -3032,9 +3039,8 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
       && maybe_move_out_of_jump_pad (lwp, wstat))
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "LWP %ld needs stabilizing (in jump pad)\n",
-		 lwpid_of (lwp));
+	debug_printf ("LWP %ld needs stabilizing (in jump pad)\n",
+		      lwpid_of (lwp));
 
       if (wstat)
 	{
@@ -3042,10 +3048,9 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
 	  enqueue_one_deferred_signal (lwp, wstat);
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Signal %d for LWP %ld deferred "
-		     "(in jump pad)\n",
-		     WSTOPSIG (*wstat), lwpid_of (lwp));
+	    debug_printf ("Signal %d for LWP %ld deferred "
+			  "(in jump pad)\n",
+			  WSTOPSIG (*wstat), lwpid_of (lwp));
 	}
 
       linux_resume_one_lwp (lwp, 0, 0, NULL);
@@ -3076,6 +3081,16 @@ stop_all_lwps (int suspend, struct lwp_info *except)
   /* Should not be called recursively.  */
   gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("stop_all_lwps (%s, except=%s)\n",
+		    suspend ? "stop-and-suspend" : "stop",
+		    except != NULL
+		    ? target_pid_to_str (ptid_of (except))
+		    : "none");
+    }
+
   stopping_threads = (suspend
 		      ? STOPPING_AND_SUSPENDING_THREADS
 		      : STOPPING_THREADS);
@@ -3086,6 +3101,13 @@ stop_all_lwps (int suspend, struct lwp_info *except)
     find_inferior (&all_lwps, send_sigstop_callback, except);
   for_each_inferior (&all_lwps, wait_for_sigstop);
   stopping_threads = NOT_STOPPING_THREADS;
+
+  if (debug_threads)
+    {
+      debug_printf ("stop_all_lwps done, setting stopping_threads "
+		    "back to !stopping\n");
+      debug_exit ();
+    }
 }
 
 /* Resume execution of the inferior process.
@@ -3138,10 +3160,10 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "Not resuming lwp %ld (%s, signal %d, stop %s);"
-		 " has pending status\n",
-		 lwpid_of (lwp), step ? "step" : "continue", signal,
-		 lwp->stop_expected ? "expected" : "not expected");
+	debug_printf ("Not resuming lwp %ld (%s, signal %d, stop %s);"
+		      " has pending status\n",
+		      lwpid_of (lwp), step ? "step" : "continue", signal,
+		      lwp->stop_expected ? "expected" : "not expected");
       return;
     }
 
@@ -3149,9 +3171,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   current_inferior = get_lwp_thread (lwp);
 
   if (debug_threads)
-    fprintf (stderr, "Resuming lwp %ld (%s, signal %d, stop %s)\n",
-	     lwpid_of (lwp), step ? "step" : "continue", signal,
-	     lwp->stop_expected ? "expected" : "not expected");
+    debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)\n",
+		  lwpid_of (lwp), step ? "step" : "continue", signal,
+		  lwp->stop_expected ? "expected" : "not expected");
 
   /* This bit needs some thinking about.  If we get a signal that
      we must report while a single-step reinsert is still pending,
@@ -3166,8 +3188,8 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "  pending reinsert at 0x%s\n",
-		 paddress (lwp->bp_reinsert));
+	debug_printf ("  pending reinsert at 0x%s\n",
+		      paddress (lwp->bp_reinsert));
 
       if (can_hardware_single_step ())
 	{
@@ -3190,9 +3212,9 @@ linux_resume_one_lwp (struct lwp_info *lwp,
   if (fast_tp_collecting == 1)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " (exit-jump-pad-bkpt)\n",
+		      lwpid_of (lwp));
 
       /* Postpone any pending signal.  It was enqueued above.  */
       signal = 0;
@@ -3200,9 +3222,9 @@ lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
   else if (fast_tp_collecting == 2)
     {
       if (debug_threads)
-	fprintf (stderr, "\
-lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
+		      " single-stepping\n",
+		      lwpid_of (lwp));
 
       if (can_hardware_single_step ())
 	step = 1;
@@ -3226,9 +3248,8 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
       && can_hardware_single_step ())
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "lwp %ld has a while-stepping action -> forcing step.\n",
-		 lwpid_of (lwp));
+	debug_printf ("lwp %ld has a while-stepping action -> forcing step.\n",
+		      lwpid_of (lwp));
       step = 1;
     }
 
@@ -3236,7 +3257,7 @@ lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
     {
       struct regcache *regcache = get_thread_regcache (current_inferior, 1);
       CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
-      fprintf (stderr, "  resuming from pc 0x%lx\n", (long) pc);
+      debug_printf ("  resuming from pc 0x%lx\n", (long) pc);
     }
 
   /* If we have pending signals, consume one unless we are trying to
@@ -3334,11 +3355,12 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      && thread->last_resume_kind == resume_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "already %s LWP %ld at GDB's request\n",
-			 thread->last_status.kind == TARGET_WAITKIND_STOPPED
-			 ? "stopped"
-			 : "stopping",
-			 lwpid_of (lwp));
+		debug_printf ("already %s LWP %ld at GDB's request\n",
+			      (thread->last_status.kind
+			       == TARGET_WAITKIND_STOPPED)
+			      ? "stopped"
+			      : "stopping",
+			      lwpid_of (lwp));
 
 	      continue;
 	    }
@@ -3359,10 +3381,9 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	      lwp->status_pending_p = 1;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "Dequeueing deferred signal %d for LWP %ld, "
-			 "leaving status pending.\n",
-			 WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
+		debug_printf ("Dequeueing deferred signal %d for LWP %ld, "
+			      "leaving status pending.\n",
+			      WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
 	    }
 
 	  return 0;
@@ -3413,9 +3434,8 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, not stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3424,9 +3444,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (thread->last_resume_kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, should remain stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, should remain"
+		      " stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3435,25 +3455,23 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, suspended\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, suspended\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (!lwp->need_step_over)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? No\n", lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? No\n", lwpid_of (lwp));
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Ignoring, has pending status.\n",
-		 lwpid_of (lwp));
+	debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
+		      " status.\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3469,10 +3487,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   if (pc != lwp->stop_pc)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Need step over [LWP %ld]? Cancelling, PC was changed.  "
-		 "Old stop_pc was 0x%s, PC is now 0x%s\n",
-		 lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
+	debug_printf ("Need step over [LWP %ld]? Cancelling, PC was changed. "
+		      "Old stop_pc was 0x%s, PC is now 0x%s\n",
+		      lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
 
       lwp->need_step_over = 0;
       return 0;
@@ -3492,10 +3509,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
 	  && gdb_no_commands_at_breakpoint (pc))
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, but found"
-		     " GDB breakpoint at 0x%s; skipping step over\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, but found"
+			  " GDB breakpoint at 0x%s; skipping step over\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  current_inferior = saved_inferior;
 	  return 0;
@@ -3503,10 +3519,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Need step over [LWP %ld]? yes, "
-		     "found breakpoint at 0x%s\n",
-		     lwpid_of (lwp), paddress (pc));
+	    debug_printf ("Need step over [LWP %ld]? yes, "
+			  "found breakpoint at 0x%s\n",
+			  lwpid_of (lwp), paddress (pc));
 
 	  /* We've found an lwp that needs stepping over --- return 1 so
 	     that find_inferior stops looking.  */
@@ -3521,9 +3536,9 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   current_inferior = saved_inferior;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Need step over [LWP %ld]? No, no breakpoint found at 0x%s\n",
-	     lwpid_of (lwp), paddress (pc));
+    debug_printf ("Need step over [LWP %ld]? No, no breakpoint found"
+		  " at 0x%s\n",
+		  lwpid_of (lwp), paddress (pc));
 
   return 0;
 }
@@ -3554,15 +3569,14 @@ start_step_over (struct lwp_info *lwp)
   int step;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "Starting step-over on LWP %ld.  Stopping all threads\n",
-	     lwpid_of (lwp));
+    debug_printf ("Starting step-over on LWP %ld.  Stopping all threads\n",
+		  lwpid_of (lwp));
 
   stop_all_lwps (1, lwp);
   gdb_assert (lwp->suspended == 0);
 
   if (debug_threads)
-    fprintf (stderr, "Done stopping all threads for step-over.\n");
+    debug_printf ("Done stopping all threads for step-over.\n");
 
   /* Note, we should always reach here with an already adjusted PC,
      either by GDB (if we're resuming due to GDB's request), or by our
@@ -3607,7 +3621,7 @@ finish_step_over (struct lwp_info *lwp)
   if (lwp->bp_reinsert != 0)
     {
       if (debug_threads)
-	fprintf (stderr, "Finished step over.\n");
+	debug_printf ("Finished step over.\n");
 
       /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
 	 may be no breakpoint to reinsert there by now.  */
@@ -3662,12 +3676,12 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (lwp->resume->kind == resume_stop)
     {
       if (debug_threads)
-	fprintf (stderr, "resume_stop request for LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resume_stop request for LWP %ld\n", lwpid_of (lwp));
 
       if (!lwp->stopped)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "stopping LWP %ld\n", lwpid_of (lwp));
+	    debug_printf ("stopping LWP %ld\n", lwpid_of (lwp));
 
 	  /* Stop the thread, and wait for the event asynchronously,
 	     through the event loop.  */
@@ -3676,8 +3690,8 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
       else
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "already stopped LWP %ld\n",
-		     lwpid_of (lwp));
+	    debug_printf ("already stopped LWP %ld\n",
+			  lwpid_of (lwp));
 
 	  /* The LWP may have been stopped in an internal event that
 	     was not meant to be notified back to GDB (e.g., gdbserver
@@ -3719,7 +3733,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   if (!leave_pending)
     {
       if (debug_threads)
-	fprintf (stderr, "resuming LWP %ld\n", lwpid_of (lwp));
+	debug_printf ("resuming LWP %ld\n", lwpid_of (lwp));
 
       step = (lwp->resume->kind == resume_step);
       linux_resume_one_lwp (lwp, step, lwp->resume->sig, NULL);
@@ -3727,7 +3741,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
   else
     {
       if (debug_threads)
-	fprintf (stderr, "leaving LWP %ld stopped\n", lwpid_of (lwp));
+	debug_printf ("leaving LWP %ld stopped\n", lwpid_of (lwp));
 
       /* If we have a new signal, enqueue the signal.  */
       if (lwp->resume->sig != 0)
@@ -3764,6 +3778,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   int any_pending;
   int leave_all_stopped;
 
+  if (debug_threads)
+    {
+      debug_enter ();
+      debug_printf ("linux_resume:\n");
+    }
+
   find_inferior (&all_threads, linux_set_resume_request, &array);
 
   /* If there is a thread which would otherwise be resumed, which has
@@ -3792,13 +3812,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   if (debug_threads)
     {
       if (need_step_over != NULL)
-	fprintf (stderr, "Not resuming all, need step over\n");
+	debug_printf ("Not resuming all, need step over\n");
       else if (any_pending)
-	fprintf (stderr,
-		 "Not resuming, all-stop and found "
-		 "an LWP with pending status\n");
+	debug_printf ("Not resuming, all-stop and found "
+		      "an LWP with pending status\n");
       else
-	fprintf (stderr, "Resuming, no pending status or step over needed\n");
+	debug_printf ("Resuming, no pending status or step over needed\n");
     }
 
   /* Even if we're leaving threads stopped, queue all signals we'd
@@ -3807,6 +3826,12 @@ linux_resume (struct thread_resume *resume_info, size_t n)
 
   if (need_step_over)
     start_step_over (need_step_over);
+
+  if (debug_threads)
+    {
+      debug_printf ("linux_resume done\n");
+      debug_exit ();
+    }
 }
 
 /* This function is called once per thread.  We check the thread's
@@ -3829,13 +3854,12 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr,
-	     "proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
+    debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
 
   if (!lwp->stopped)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld already running\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld already running\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3845,16 +3869,16 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
       && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
     {
       if (debug_threads)
-	fprintf (stderr, "   client wants LWP to remain %ld stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   client wants LWP to remain %ld stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
   if (lwp->status_pending_p)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld has pending status, leaving stopped\n",
-		 lwpid_of (lwp));
+	debug_printf ("   LWP %ld has pending status, leaving stopped\n",
+		      lwpid_of (lwp));
       return 0;
     }
 
@@ -3863,7 +3887,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
   if (lwp->suspended)
     {
       if (debug_threads)
-	fprintf (stderr, "   LWP %ld is suspended\n", lwpid_of (lwp));
+	debug_printf ("   LWP %ld is suspended\n", lwpid_of (lwp));
       return 0;
     }
 
@@ -3882,10 +3906,9 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
 	 pending, this is a no-op.  */
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Client wants LWP %ld to stop. "
-		 "Making sure it has a SIGSTOP pending\n",
-		 lwpid_of (lwp));
+	debug_printf ("Client wants LWP %ld to stop. "
+		      "Making sure it has a SIGSTOP pending\n",
+		      lwpid_of (lwp));
 
       send_sigstop (lwp);
     }
@@ -3932,9 +3955,9 @@ proceed_all_lwps (void)
       if (need_step_over != NULL)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "proceed_all_lwps: found "
-		     "thread %ld needing a step-over\n",
-		     lwpid_of (need_step_over));
+	    debug_printf ("proceed_all_lwps: found "
+			  "thread %ld needing a step-over\n",
+			  lwpid_of (need_step_over));
 
 	  start_step_over (need_step_over);
 	  return;
@@ -3942,7 +3965,7 @@ proceed_all_lwps (void)
     }
 
   if (debug_threads)
-    fprintf (stderr, "Proceeding, no step-over needed\n");
+    debug_printf ("Proceeding, no step-over needed\n");
 
   find_inferior (&all_lwps, proceed_one_lwp, NULL);
 }
@@ -3956,18 +3979,24 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
 {
   if (debug_threads)
     {
+      debug_enter ();
       if (except)
-	fprintf (stderr,
-		 "unstopping all lwps, except=(LWP %ld)\n", lwpid_of (except));
+	debug_printf ("unstopping all lwps, except=(LWP %ld)\n",
+		      lwpid_of (except));
       else
-	fprintf (stderr,
-		 "unstopping all lwps\n");
+	debug_printf ("unstopping all lwps\n");
     }
 
   if (unsuspend)
     find_inferior (&all_lwps, unsuspend_and_proceed_one_lwp, except);
   else
     find_inferior (&all_lwps, proceed_one_lwp, except);
+
+  if (debug_threads)
+    {
+      debug_printf ("unstop_all_lwps done\n");
+      debug_exit ();
+    }
 }
 
 
@@ -4533,8 +4562,8 @@ linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 	val = val & 0xffff;
       else if (len == 3)
 	val = val & 0xffffff;
-      fprintf (stderr, "Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
-	       val, (long)memaddr);
+      debug_printf ("Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
+		    val, (long)memaddr);
     }
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
@@ -4777,9 +4806,9 @@ linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
   pid = lwpid_of (get_thread_lwp (current_inferior));
 
   if (debug_threads)
-    fprintf (stderr, "%s siginfo for lwp %d.\n",
-	     readbuf != NULL ? "Reading" : "Writing",
-	     pid);
+    debug_printf ("%s siginfo for lwp %d.\n",
+		  readbuf != NULL ? "Reading" : "Writing",
+		  pid);
 
   if (offset >= sizeof (siginfo))
     return -1;
@@ -4851,8 +4880,8 @@ linux_async (int enable)
   int previous = (linux_event_pipe[0] != -1);
 
   if (debug_threads)
-    fprintf (stderr, "linux_async (%d), previous=%d\n",
-	     enable, previous);
+    debug_printf ("linux_async (%d), previous=%d\n",
+		  enable, previous);
 
   if (previous != enable)
     {
diff --git a/gdb/gdbserver/linux-m32r-low.c b/gdb/gdbserver/linux-m32r-low.c
index e208523..477e185 100644
--- a/gdb/gdbserver/linux-m32r-low.c
+++ b/gdb/gdbserver/linux-m32r-low.c
@@ -59,7 +59,7 @@ m32r_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-sparc-low.c b/gdb/gdbserver/linux-sparc-low.c
index fcffe05..75c97dd 100644
--- a/gdb/gdbserver/linux-sparc-low.c
+++ b/gdb/gdbserver/linux-sparc-low.c
@@ -231,7 +231,7 @@ sparc_get_pc (struct regcache *regcache)
   unsigned long pc;
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index e1daa7d..1e590e8 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -2027,8 +2027,8 @@ add_insns (unsigned char *start, int len)
   CORE_ADDR buildaddr = current_insn_ptr;
 
   if (debug_threads)
-    fprintf (stderr, "Adding %d bytes of insn at %s\n",
-	     len, paddress (buildaddr));
+    debug_printf ("Adding %d bytes of insn at %s\n",
+		  len, paddress (buildaddr));
 
   append_insns (&buildaddr, len, start);
   current_insn_ptr = buildaddr;
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index fd706e9..b77ce10 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -197,10 +197,9 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -211,9 +210,8 @@ set_raw_breakpoint_at (CORE_ADDR where)
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert breakpoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert breakpoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (bp);
       return NULL;
     }
@@ -334,10 +332,9 @@ delete_fast_tracepoint_jump (struct fast_tracepoint_jump *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert fast tracepoint jump "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert fast tracepoint jump "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -398,10 +395,9 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to read shadow memory of"
-		 " fast tracepoint at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to read shadow memory of"
+		      " fast tracepoint at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
       free (jp);
       return NULL;
     }
@@ -424,9 +420,8 @@ set_fast_tracepoint_jump (CORE_ADDR where,
   if (err != 0)
     {
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to insert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to insert fast tracepoint jump at 0x%s (%s).\n",
+		      paddress (where), strerror (err));
 
       /* Unlink it.  */
       proc->fast_tracepoint_jumps = jp->next;
@@ -450,10 +445,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -480,9 +474,9 @@ uninsert_fast_tracepoint_jumps_at (CORE_ADDR pc)
 	  jp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert fast tracepoint jump at 0x%s (%s).\n",
-		     paddress (pc), strerror (err));
+	    debug_printf ("Failed to uninsert fast tracepoint jump at"
+			  " 0x%s (%s).\n",
+			  paddress (pc), strerror (err));
 	}
     }
 }
@@ -500,10 +494,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       /* This can happen when we remove breakpoints when a tracepoint
 	 hit causes a tracing stop, while handling a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find fast tracepoint jump at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (where));
+	debug_printf ("Could not find fast tracepoint jump at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (where));
       return;
     }
 
@@ -528,9 +521,9 @@ reinsert_fast_tracepoint_jumps_at (CORE_ADDR where)
       jp->inserted = 0;
 
       if (debug_threads)
-	fprintf (stderr,
-		 "Failed to reinsert fast tracepoint jump at 0x%s (%s).\n",
-		 paddress (where), strerror (err));
+	debug_printf ("Failed to reinsert fast tracepoint jump at"
+		      " 0x%s (%s).\n",
+		      paddress (where), strerror (err));
     }
 }
 
@@ -598,10 +591,9 @@ delete_raw_breakpoint (struct process_info *proc, struct raw_breakpoint *todel)
 		  *bp_link = prev_bp_link;
 
 		  if (debug_threads)
-		    fprintf (stderr,
-			     "Failed to uninsert raw breakpoint "
-			     "at 0x%s (%s) while deleting it.\n",
-			     paddress (bp->pc), strerror (ret));
+		    debug_printf ("Failed to uninsert raw breakpoint "
+				  "at 0x%s (%s) while deleting it.\n",
+				  paddress (bp->pc), strerror (ret));
 		  return ret;
 		}
 
@@ -932,9 +924,9 @@ gdb_no_commands_at_breakpoint (CORE_ADDR where)
     return 0;
 
   if (debug_threads)
-    fprintf (stderr, "at 0x%s, bp command_list is 0x%s\n",
-	     paddress (where),
-	     phex_nz ((uintptr_t) bp->command_list, 0));
+    debug_printf ("at 0x%s, bp command_list is 0x%s\n",
+		  paddress (where),
+		  phex_nz ((uintptr_t) bp->command_list, 0));
   return (bp->command_list == NULL);
 }
 
@@ -1034,9 +1026,8 @@ uninsert_raw_breakpoint (struct raw_breakpoint *bp)
 	  bp->inserted = 1;
 
 	  if (debug_threads)
-	    fprintf (stderr,
-		     "Failed to uninsert raw breakpoint at 0x%s (%s).\n",
-		     paddress (bp->pc), strerror (err));
+	    debug_printf ("Failed to uninsert raw breakpoint at 0x%s (%s).\n",
+			  paddress (bp->pc), strerror (err));
 	}
     }
 }
@@ -1052,10 +1043,9 @@ uninsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find breakpoint at 0x%s "
-		 "in list (uninserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find breakpoint at 0x%s "
+		      "in list (uninserting).\n",
+		      paddress (pc));
       return;
     }
 
@@ -1087,9 +1077,8 @@ reinsert_raw_breakpoint (struct raw_breakpoint *bp)
   if (err == 0)
     bp->inserted = 1;
   else if (debug_threads)
-    fprintf (stderr,
-	     "Failed to reinsert breakpoint at 0x%s (%s).\n",
-	     paddress (bp->pc), strerror (err));
+    debug_printf ("Failed to reinsert breakpoint at 0x%s (%s).\n",
+		  paddress (bp->pc), strerror (err));
 }
 
 void
@@ -1103,10 +1092,9 @@ reinsert_breakpoints_at (CORE_ADDR pc)
       /* This can happen when we remove all breakpoints while handling
 	 a step-over.  */
       if (debug_threads)
-	fprintf (stderr,
-		 "Could not find raw breakpoint at 0x%s "
-		 "in list (reinserting).\n",
-		 paddress (pc));
+	debug_printf ("Could not find raw breakpoint at 0x%s "
+		      "in list (reinserting).\n",
+		      paddress (pc));
       return;
     }
 
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 75ace6e..3b88995 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -161,7 +161,7 @@ handle_accept_event (int err, gdb_client_data client_data)
   socklen_t tmp;
 
   if (debug_threads)
-    fprintf (stderr, "handling possible accept event\n");
+    debug_printf ("handling possible accept event\n");
 
   tmp = sizeof (sockaddr);
   remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
@@ -1315,8 +1315,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
 		      struct target_waitstatus *status)
 {
   if (debug_threads)
-    fprintf (stderr, "Writing resume reply for %s:%d\n",
-	     target_pid_to_str (ptid), status->kind);
+    debug_printf ("Writing resume reply for %s:%d\n",
+		  target_pid_to_str (ptid), status->kind);
 
   switch (status->kind)
     {
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 28ea048..88354be 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -22,10 +22,12 @@
 #include "notif.h"
 #include "tdesc.h"
 
+#include <ctype.h>
 #include <unistd.h>
 #if HAVE_SIGNAL_H
 #include <signal.h>
 #endif
+#include "gdb_vecs.h"
 #include "gdb_wait.h"
 #include "btrace-common.h"
 #include "filestuff.h"
@@ -66,10 +68,6 @@ int disable_randomization = 1;
 
 static char **program_argv, **wrapper_argv;
 
-/* Enable miscellaneous debugging output.  The name is historical - it
-   was originally used to debug LinuxThreads support.  */
-int debug_threads;
-
 /* Enable debugging of h/w breakpoint/watchpoint support.  */
 int debug_hw_points;
 
@@ -222,8 +220,8 @@ start_inferior (char **argv)
     {
       int i;
       for (i = 0; new_argv[i]; ++i)
-	fprintf (stderr, "new_argv[%d] = \"%s\"\n", i, new_argv[i]);
-      fflush (stderr);
+	debug_printf ("new_argv[%d] = \"%s\"\n", i, new_argv[i]);
+      debug_flush ();
     }
 
 #ifdef SIGTTOU
@@ -694,6 +692,13 @@ monitor_show_help (void)
   monitor_output ("    Enable h/w breakpoint/watchpoint debugging messages\n");
   monitor_output ("  set remote-debug <0|1>\n");
   monitor_output ("    Enable remote protocol debugging messages\n");
+  monitor_output ("  set debug-format option1[,option2,...]\n");
+  monitor_output ("    Add additional information to debugging messages\n");
+  monitor_output ("    Options: all, none");
+#ifdef HAVE_GETTIMEOFDAY
+  monitor_output (", timestamp");
+#endif
+  monitor_output ("\n");
   monitor_output ("  exit\n");
   monitor_output ("    Quit GDBserver\n");
 }
@@ -921,6 +926,80 @@ handle_search_memory (char *own_buf, int packet_len)
       return;					\
     }
 
+/* Parse options to --debug-format= and "monitor set debug-format".
+   ARG is the text after "--debug-format=" or "monitor set debug-format".
+   IS_MONITOR is non-zero if we're invoked via "monitor set debug-format".
+   This triggers calls to monitor_output.
+   The result is NULL if all options were parsed ok, otherwise an error
+   message which the caller must free.
+
+   N.B. These commands affect all debug format settings, they are not
+   cumulative.  If a format is not specified, it is turned off.
+   However, we don't go to extra trouble with things like
+   "monitor set debug-format all,none,timestamp".
+   Instead we just parse them one at a time, in order.
+
+   The syntax for "monitor set debug" we support here is not identical
+   to gdb's "set debug foo on|off" because we also use this function to
+   parse "--debug-format=foo,bar".  */
+
+static char *
+parse_debug_format_options (const char *arg, int is_monitor)
+{
+  VEC (char_ptr) *options;
+  int ix;
+  char *option;
+
+  /* First turn all debug format options off.  */
+  debug_timestamp = 0;
+
+  /* First remove leading spaces, for "monitor set debug-format".  */
+  while (isspace (*arg))
+    ++arg;
+
+  options = delim_string_to_char_ptr_vec (arg, ',');
+
+  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
+    {
+      if (strcmp (option, "all") == 0)
+	{
+	  debug_timestamp = 1;
+	  if (is_monitor)
+	    monitor_output ("All extra debug format options enabled.\n");
+	}
+      else if (strcmp (option, "none") == 0)
+	{
+	  debug_timestamp = 0;
+	  if (is_monitor)
+	    monitor_output ("All extra debug format options disabled.\n");
+	}
+#ifdef HAVE_GETTIMEOFDAY
+      else if (strcmp (option, "timestamp") == 0)
+	{
+	  debug_timestamp = 1;
+	  if (is_monitor)
+	    monitor_output ("Timestamps will be added to debug output.\n");
+	}
+#endif
+      else if (*option == '\0')
+	{
+	  /* An empty option, e.g., "--debug-format=foo,,bar", is ignored.  */
+	  continue;
+	}
+      else
+	{
+	  char *msg = xstrprintf ("Unknown debug-format argument: \"%s\"\n",
+				  option);
+
+	  free_char_ptr_vec (options);
+	  return msg;
+	}
+    }
+
+  free_char_ptr_vec (options);
+  return NULL;
+}
+
 /* Handle monitor commands not handled by target-specific handlers.  */
 
 static void
@@ -956,6 +1035,21 @@ handle_monitor_command (char *mon, char *own_buf)
       remote_debug = 0;
       monitor_output ("Protocol debug output disabled.\n");
     }
+  else if (strncmp (mon, "set debug-format ",
+		    sizeof ("set debug-format ") - 1) == 0)
+    {
+      char *error_msg
+	= parse_debug_format_options (mon + sizeof ("set debug-format ") - 1,
+				      1);
+
+      if (error_msg != NULL)
+	{
+	  monitor_output (error_msg);
+	  monitor_show_help ();
+	  write_enn (own_buf);
+	  xfree (error_msg);
+	}
+    }
   else if (strcmp (mon, "help") == 0)
     monitor_show_help ();
   else if (strcmp (mon, "exit") == 0)
@@ -2535,10 +2629,9 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
 	      char *status_string
 		= target_waitstatus_to_string (&thread->last_status);
 
-	      fprintf (stderr,
-		       "Reporting thread %s as already stopped with %s\n",
-		       target_pid_to_str (entry->id),
-		       status_string);
+	      debug_printf ("Reporting thread %s as already stopped with %s\n",
+			    target_pid_to_str (entry->id),
+			    status_string);
 
 	      xfree (status_string);
 	    }
@@ -2733,6 +2826,14 @@ gdbserver_usage (FILE *stream)
 	   "\n"
 	   "Options:\n"
 	   "  --debug               Enable general debugging output.\n"
+	   "  --debug-format=opt1[,opt2,...]\n"
+	   "                        Specify extra content in debugging output.\n"
+	   "                          Options:\n"
+	   "                            all\n"
+	   "                            none\n"
+#ifdef HAVE_GETTIMEOFDAY
+	   "                            timestamp\n"
+#endif
 	   "  --remote-debug        Enable remote protocol debugging output.\n"
 	   "  --version             Display version information and exit.\n"
 	   "  --wrapper WRAPPER --  Run WRAPPER to start new programs.\n"
@@ -2908,6 +3009,20 @@ main (int argc, char *argv[])
 	}
       else if (strcmp (*next_arg, "--debug") == 0)
 	debug_threads = 1;
+      else if (strncmp (*next_arg,
+			"--debug-format=",
+			sizeof ("--debug-format=") - 1) == 0)
+	{
+	  char *error_msg
+	    = parse_debug_format_options ((*next_arg)
+					  + sizeof ("--debug-format=") - 1, 0);
+
+	  if (error_msg != NULL)
+	    {
+	      fprintf (stderr, "%s", error_msg);
+	      exit (1);
+	    }
+	}
       else if (strcmp (*next_arg, "--remote-debug") == 0)
 	remote_debug = 1;
       else if (strcmp (*next_arg, "--disable-packet") == 0)
@@ -3204,14 +3319,14 @@ process_point_options (CORE_ADDR point_addr, char **packet)
 	{
 	  /* Conditional expression.  */
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint condition.\n");
+	    debug_printf ("Found breakpoint condition.\n");
 	  add_breakpoint_condition (point_addr, &dataptr);
 	}
       else if (strncmp (dataptr, "cmds:", strlen ("cmds:")) == 0)
 	{
 	  dataptr += strlen ("cmds:");
 	  if (debug_threads)
-	    fprintf (stderr, "Found breakpoint commands %s.\n", dataptr);
+	    debug_printf ("Found breakpoint commands %s.\n", dataptr);
 	  persist = (*dataptr == '1');
 	  dataptr += 2;
 	  add_breakpoint_commands (point_addr, &dataptr, persist);
@@ -3316,7 +3431,7 @@ process_serial_event (void)
 	  if (!non_stop)
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "Forcing non-stop mode\n");
+		debug_printf ("Forcing non-stop mode\n");
 
 	      non_stop = 1;
 	      start_non_stop (1);
@@ -3709,7 +3824,7 @@ int
 handle_serial_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible serial event\n");
+    debug_printf ("handling possible serial event\n");
 
   /* Really handle it.  */
   if (process_serial_event () < 0)
@@ -3728,7 +3843,7 @@ int
 handle_target_event (int err, gdb_client_data client_data)
 {
   if (debug_threads)
-    fprintf (stderr, "handling possible target event\n");
+    debug_printf ("handling possible target event\n");
 
   last_ptid = mywait (minus_one_ptid, &last_status,
 		      TARGET_WNOHANG, 1);
@@ -3770,10 +3885,10 @@ handle_target_event (int err, gdb_client_data client_data)
 	      struct thread_resume resume_info;
 
 	      if (debug_threads)
-		fprintf (stderr,
-			 "GDB not connected; forwarding event %d for [%s]\n",
-			 (int) last_status.kind,
-			 target_pid_to_str (last_ptid));
+		debug_printf ("GDB not connected; forwarding event %d for"
+			      " [%s]\n",
+			      (int) last_status.kind,
+			      target_pid_to_str (last_ptid));
 
 	      resume_info.thread = last_ptid;
 	      resume_info.kind = resume_continue;
@@ -3781,9 +3896,9 @@ handle_target_event (int err, gdb_client_data client_data)
 	      (*the_target->resume) (&resume_info, 1);
 	    }
 	  else if (debug_threads)
-	    fprintf (stderr, "GDB not connected; ignoring event %d for [%s]\n",
-		     (int) last_status.kind,
-		     target_pid_to_str (last_ptid));
+	    debug_printf ("GDB not connected; ignoring event %d for [%s]\n",
+			  (int) last_status.kind,
+			  target_pid_to_str (last_ptid));
 	}
       else
 	{
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index d82556a..6eb1a16 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -110,7 +110,6 @@ extern ptid_t cont_thread;
 extern ptid_t general_thread;
 
 extern int server_waiting;
-extern int debug_threads;
 extern int debug_hw_points;
 extern int pass_signals[];
 extern int program_signals[];
@@ -146,6 +145,7 @@ extern int handle_target_event (int err, gdb_client_data client_data);
 
 #include "common-utils.h"
 #include "utils.h"
+#include "debug.h"
 
 #include "gdb_assert.h"
 
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 8b8f6ce..df06b9d 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -194,7 +194,7 @@ thread_db_create_event (CORE_ADDR where)
     fatal ("unexpected thread_db->td_ta_event_getmsg_p == NULL");
 
   if (debug_threads)
-    fprintf (stderr, "Thread creation event.\n");
+    debug_printf ("Thread creation event.\n");
 
   /* FIXME: This assumes we don't get another event.
      In the LinuxThreads implementation, this is safe,
@@ -289,8 +289,8 @@ find_one_thread (ptid_t ptid)
 	   lwpid, thread_db_err_str (err));
 
   if (debug_threads)
-    fprintf (stderr, "Found thread %ld (LWP %d)\n",
-	     ti.ti_tid, ti.ti_lid);
+    debug_printf ("Found thread %ld (LWP %d)\n",
+		  ti.ti_tid, ti.ti_lid);
 
   if (lwpid != ti.ti_lid)
     {
@@ -326,8 +326,8 @@ attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
   struct lwp_info *lwp;
 
   if (debug_threads)
-    fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
-	     ti_p->ti_tid, ti_p->ti_lid);
+    debug_printf ("Attaching to thread %ld (LWP %d)\n",
+		  ti_p->ti_tid, ti_p->ti_lid);
   linux_attach_lwp (ti_p->ti_lid);
   lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
   if (lwp == NULL)
@@ -432,8 +432,8 @@ thread_db_find_new_threads (void)
 					 TD_THR_LOWEST_PRIORITY,
 					 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
       if (debug_threads)
-	fprintf (stderr, "Found %d threads in iteration %d.\n",
-		 new_thread_count, iteration);
+	debug_printf ("Found %d threads in iteration %d.\n",
+		      new_thread_count, iteration);
 
       if (new_thread_count != 0)
 	{
@@ -546,7 +546,7 @@ thread_db_load_search (void)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -595,7 +595,7 @@ try_thread_db_load_1 (void *handle)
       if ((a) == NULL)						\
 	{							\
 	  if (debug_threads)					\
-	    fprintf (stderr, "dlsym: %s\n", dlerror ());	\
+	    debug_printf ("dlsym: %s\n", dlerror ());		\
 	  if (required)						\
 	    {							\
 	      free (tdb);					\
@@ -613,7 +613,7 @@ try_thread_db_load_1 (void *handle)
   if (err != TD_OK)
     {
       if (debug_threads)
-	fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
+	debug_printf ("td_ta_new(): %s\n", thread_db_err_str (err));
       free (tdb);
       proc->private->thread_db = NULL;
       return 0;
@@ -663,13 +663,13 @@ try_thread_db_load (const char *library)
   void *handle;
 
   if (debug_threads)
-    fprintf (stderr, "Trying host libthread_db library: %s.\n",
-	     library);
+    debug_printf ("Trying host libthread_db library: %s.\n",
+		  library);
   handle = dlopen (library, RTLD_NOW);
   if (handle == NULL)
     {
       if (debug_threads)
-	fprintf (stderr, "dlopen failed: %s.\n", dlerror ());
+	debug_printf ("dlopen failed: %s.\n", dlerror ());
       return 0;
     }
 
@@ -786,7 +786,7 @@ thread_db_load_search (void)
 
   free_char_ptr_vec (dir_vec);
   if (debug_threads)
-    fprintf (stderr, "thread_db_load_search returning %d\n", rc);
+    debug_printf ("thread_db_load_search returning %d\n", rc);
   return rc;
 }
 
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 13b3ff6..3706577 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -61,6 +61,8 @@
 
 */
 
+#ifdef IN_PROCESS_AGENT
+
 static void trace_vdebug (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 static void
@@ -81,6 +83,19 @@ trace_vdebug (const char *fmt, ...)
       trace_vdebug ((fmt), ##args);		\
   } while (0)
 
+#else
+
+#define trace_debug_1(level, fmt, args...)	\
+  do {						\
+    if (level <= debug_threads)			\
+      {						\
+	debug_printf ((fmt), ##args);		\
+	debug_printf ("\n");			\
+      }						\
+  } while (0)
+
+#endif
+
 #define trace_debug(FMT, args...)		\
   trace_debug_1 (1, FMT, ##args)
 
@@ -338,7 +353,7 @@ tracepoint_look_up_symbols (void)
       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name);
+	    debug_printf ("symbol `%s' not found\n", symbol_list[i].name);
 	  return;
 	}
     }
diff --git a/gdb/testsuite/gdb.server/server-mon.exp b/gdb/testsuite/gdb.server/server-mon.exp
index 05f63e7..58b1df2 100644
--- a/gdb/testsuite/gdb.server/server-mon.exp
+++ b/gdb/testsuite/gdb.server/server-mon.exp
@@ -50,3 +50,7 @@ gdb_test "monitor set debug 1" "Debug output enabled\\."
 gdb_test "monitor set debug 0" "Debug output disabled\\."
 gdb_test "monitor set remote-debug 1" "Protocol debug output enabled\\."
 gdb_test "monitor set remote-debug 0" "Protocol debug output disabled\\."
+gdb_test "monitor set debug-format all" \
+    "All extra debug format options enabled\\."
+gdb_test "monitor set debug-format none" \
+    "All extra debug format options disabled\\."

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2014-01-22 23:06 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-17 21:47 [PATCH 4/6] gdbserver: Delimit debugging output for readability Doug Evans
2013-12-18 11:17 ` Pedro Alves
2014-01-15  0:47   ` Doug Evans
2014-01-16 17:22     ` Pedro Alves
2014-01-16 18:43       ` Doug Evans
2014-01-16 18:54         ` Pedro Alves
2014-01-16 23:28           ` [PATCH 0/3] Add debug_printf and timestamps to gdbserver Doug Evans
2014-01-16 23:31             ` [PATCH 1/3] gdbserver debug_printf+timestamps: FUNCTION_NAME Doug Evans
2014-01-17 12:46               ` Pedro Alves
2014-01-16 23:33             ` [PATCH 2/3] gdbserver debug_printf+timestamps: delim_string_to_char_ptr_vec_append Doug Evans
2014-01-16 23:37             ` [PATCH 3/3, doc RFA] gdbserver debug_printf+timestamps: main patch Doug Evans
2014-01-17  2:58               ` Doug Evans
2014-01-17  7:04               ` Eli Zaretskii
2014-01-17 12:46               ` Pedro Alves
2014-01-17 22:45                 ` Doug Evans
2014-01-18  8:25                   ` Eli Zaretskii
2014-01-20 16:14                   ` Pedro Alves
2014-01-22 23:06                     ` Doug Evans
2014-01-16 18:39     ` [PATCH 4/6] gdbserver: Delimit debugging output for readability Yao Qi
2014-01-16 19:01       ` Doug Evans
2014-01-17  2:32         ` Joel Brobecker
2014-01-17  2:40         ` Joel Brobecker
2014-01-17 12:46         ` Pedro Alves
2014-01-17 12:59         ` Yao Qi
2014-01-20  5:42         ` Tom Tromey
2014-01-20 19:51           ` Doug Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).