2001-04-26 Michael Snyder <msnyder@redhat.com>
* thread-db.c (_initialize_thread_db): Add set/show command "debug-linux-threads" for debugging output. * lin-lwp.c (various): Use global "debug_linux_threads to turn on extra debugging output.
This commit is contained in:
parent
4c8de859cc
commit
20b8570d73
|
@ -1,5 +1,9 @@
|
||||||
2001-04-26 Michael Snyder <msnyder@redhat.com>
|
2001-04-26 Michael Snyder <msnyder@redhat.com>
|
||||||
|
|
||||||
|
* thread-db.c (_initialize_thread_db): Add set/show command
|
||||||
|
"debug-linux-threads" for debugging output.
|
||||||
|
* lin-lwp.c (various): Use global "debug_linux_threads to
|
||||||
|
turn on extra debugging output.
|
||||||
* lin-lwp.c: Minor cleanups in comments.
|
* lin-lwp.c: Minor cleanups in comments.
|
||||||
* target.c (normal_pid_to_str): Get rid of an ancient hack.
|
* target.c (normal_pid_to_str): Get rid of an ancient hack.
|
||||||
* remote.c (remote_pid_to_str): New function for remote target.
|
* remote.c (remote_pid_to_str): New function for remote target.
|
||||||
|
|
|
@ -31,11 +31,8 @@
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
extern int debug_linux_threads;
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
extern const char *strsignal (int sig);
|
extern const char *strsignal (int sig);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* On Linux there are no real LWP's. The closest thing to LWP's are
|
/* On Linux there are no real LWP's. The closest thing to LWP's are
|
||||||
processes sharing the same VM space. A multi-threaded process is
|
processes sharing the same VM space. A multi-threaded process is
|
||||||
|
@ -521,9 +518,9 @@ stop_wait_callback (struct lwp_info *lp, void *data)
|
||||||
printf_unfiltered ("[%s exited]\n",
|
printf_unfiltered ("[%s exited]\n",
|
||||||
target_pid_to_str (lp->pid));
|
target_pid_to_str (lp->pid));
|
||||||
}
|
}
|
||||||
#if DEBUG
|
if (debug_linux_threads)
|
||||||
printf ("%s exited.\n", target_pid_to_str (lp->pid));
|
printf ("%s exited.\n", target_pid_to_str (lp->pid));
|
||||||
#endif
|
|
||||||
delete_lwp (lp->pid);
|
delete_lwp (lp->pid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -549,21 +546,21 @@ stop_wait_callback (struct lwp_info *lp, void *data)
|
||||||
If we do not do this, then we run the risk that the
|
If we do not do this, then we run the risk that the
|
||||||
user will delete or disable the breakpoint, but the
|
user will delete or disable the breakpoint, but the
|
||||||
thread will have already tripped on it. */
|
thread will have already tripped on it. */
|
||||||
#if DEBUG
|
|
||||||
printf ("Tripped breakpoint at %lx in LWP %d"
|
if (debug_linux_threads)
|
||||||
" while waiting for SIGSTOP.\n",
|
printf ("Tripped breakpoint at %lx in LWP %d"
|
||||||
(long) read_pc_pid (lp->pid), pid);
|
" while waiting for SIGSTOP.\n",
|
||||||
#endif
|
(long) read_pc_pid (lp->pid), pid);
|
||||||
|
|
||||||
/* Set the PC to before the trap. */
|
/* Set the PC to before the trap. */
|
||||||
if (DECR_PC_AFTER_BREAK)
|
if (DECR_PC_AFTER_BREAK)
|
||||||
write_pc_pid (read_pc_pid (pid) - DECR_PC_AFTER_BREAK, pid);
|
write_pc_pid (read_pc_pid (pid) - DECR_PC_AFTER_BREAK, pid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if DEBUG
|
if (debug_linux_threads)
|
||||||
printf ("Received %s in LWP %d while waiting for SIGSTOP.\n",
|
printf ("Received %s in LWP %d while waiting for SIGSTOP.\n",
|
||||||
strsignal (WSTOPSIG (status)), pid);
|
strsignal (WSTOPSIG (status)), pid);
|
||||||
#endif
|
|
||||||
/* The thread was stopped with a signal other than
|
/* The thread was stopped with a signal other than
|
||||||
SIGSTOP, and didn't accidentiliy trip a breakpoint.
|
SIGSTOP, and didn't accidentiliy trip a breakpoint.
|
||||||
Record the wait status. */
|
Record the wait status. */
|
||||||
|
@ -620,10 +617,9 @@ lin_lwp_wait (int pid, struct target_waitstatus *ourstatus)
|
||||||
lp = iterate_over_lwps (status_callback, NULL);
|
lp = iterate_over_lwps (status_callback, NULL);
|
||||||
if (lp)
|
if (lp)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
if (debug_linux_threads)
|
||||||
printf ("Using pending wait status for LWP %d.\n",
|
printf ("Using pending wait status for LWP %d.\n",
|
||||||
GET_LWP (lp->pid));
|
GET_LWP (lp->pid));
|
||||||
#endif
|
|
||||||
status = lp->status;
|
status = lp->status;
|
||||||
lp->status = 0;
|
lp->status = 0;
|
||||||
}
|
}
|
||||||
|
@ -635,19 +631,18 @@ lin_lwp_wait (int pid, struct target_waitstatus *ourstatus)
|
||||||
}
|
}
|
||||||
else if (is_lwp (pid))
|
else if (is_lwp (pid))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
if (debug_linux_threads)
|
||||||
printf ("Waiting for specific LWP %d.\n", GET_LWP (pid));
|
printf ("Waiting for specific LWP %d.\n", GET_LWP (pid));
|
||||||
#endif
|
|
||||||
/* We have a specific LWP to check. */
|
/* We have a specific LWP to check. */
|
||||||
lp = find_lwp_pid (GET_LWP (pid));
|
lp = find_lwp_pid (GET_LWP (pid));
|
||||||
gdb_assert (lp);
|
gdb_assert (lp);
|
||||||
status = lp->status;
|
status = lp->status;
|
||||||
lp->status = 0;
|
lp->status = 0;
|
||||||
#if DEBUG
|
if (debug_linux_threads)
|
||||||
if (status)
|
if (status)
|
||||||
printf ("Using pending wait status for LWP %d.\n",
|
printf ("Using pending wait status for LWP %d.\n",
|
||||||
GET_LWP (lp->pid));
|
GET_LWP (lp->pid));
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If we have to wait, take into account whether PID is a cloned
|
/* If we have to wait, take into account whether PID is a cloned
|
||||||
process or not. And we have to convert it to something that
|
process or not. And we have to convert it to something that
|
||||||
|
@ -725,9 +720,9 @@ lin_lwp_wait (int pid, struct target_waitstatus *ourstatus)
|
||||||
printf_unfiltered ("[%s exited]\n",
|
printf_unfiltered ("[%s exited]\n",
|
||||||
target_pid_to_str (lp->pid));
|
target_pid_to_str (lp->pid));
|
||||||
}
|
}
|
||||||
#if DEBUG
|
if (debug_linux_threads)
|
||||||
printf ("%s exited.\n", target_pid_to_str (lp->pid));
|
printf ("%s exited.\n", target_pid_to_str (lp->pid));
|
||||||
#endif
|
|
||||||
delete_lwp (lp->pid);
|
delete_lwp (lp->pid);
|
||||||
|
|
||||||
/* Make sure there is at least one thread running. */
|
/* Make sure there is at least one thread running. */
|
||||||
|
@ -743,10 +738,10 @@ lin_lwp_wait (int pid, struct target_waitstatus *ourstatus)
|
||||||
if (lp->signalled && WIFSTOPPED (status)
|
if (lp->signalled && WIFSTOPPED (status)
|
||||||
&& WSTOPSIG (status) == SIGSTOP)
|
&& WSTOPSIG (status) == SIGSTOP)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
if (debug_linux_threads)
|
||||||
printf ("Delayed SIGSTOP caught for %s.\n",
|
printf ("Delayed SIGSTOP caught for %s.\n",
|
||||||
target_pid_to_str (lp->pid));
|
target_pid_to_str (lp->pid));
|
||||||
#endif
|
|
||||||
/* This is a delayed SIGSTOP. */
|
/* This is a delayed SIGSTOP. */
|
||||||
lp->signalled = 0;
|
lp->signalled = 0;
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,16 @@
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "gdbcmd.h"
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
|
|
||||||
#ifndef LIBTHREAD_DB_SO
|
#ifndef LIBTHREAD_DB_SO
|
||||||
#define LIBTHREAD_DB_SO "libthread_db.so.1"
|
#define LIBTHREAD_DB_SO "libthread_db.so.1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int debug_linux_threads = 0; /* Set non-zero for debugging output. */
|
||||||
|
|
||||||
/* If we're running on Linux, we must explicitly attach to any new threads. */
|
/* If we're running on Linux, we must explicitly attach to any new threads. */
|
||||||
|
|
||||||
/* FIXME: There is certainly some room for improvements:
|
/* FIXME: There is certainly some room for improvements:
|
||||||
|
@ -51,7 +55,7 @@ static struct target_ops thread_db_ops;
|
||||||
static struct target_ops *target_beneath;
|
static struct target_ops *target_beneath;
|
||||||
|
|
||||||
/* Pointer to the next function on the objfile event chain. */
|
/* Pointer to the next function on the objfile event chain. */
|
||||||
static void (*target_new_objfile_chain) (struct objfile *objfile);
|
static void (*new_objfile_event_chain) (struct objfile *objfile);
|
||||||
|
|
||||||
/* Non-zero if we're using this module's target vector. */
|
/* Non-zero if we're using this module's target vector. */
|
||||||
static int using_thread_db;
|
static int using_thread_db;
|
||||||
|
@ -588,8 +592,8 @@ thread_db_new_objfile (struct objfile *objfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
quit:
|
quit:
|
||||||
if (target_new_objfile_chain)
|
if (new_objfile_event_chain)
|
||||||
target_new_objfile_chain (objfile);
|
new_objfile_event_chain (objfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -697,11 +701,10 @@ check_event (int pid)
|
||||||
error ("Thread creation event doesn't match breakpoint.");
|
error ("Thread creation event doesn't match breakpoint.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We may already know about this thread, for instance when the
|
if (in_thread_list (pid))
|
||||||
user has issued the `info threads' command before the SIGTRAP
|
error ("Spurious thread creation event.");
|
||||||
for hitting the thread creation breakpoint was reported. */
|
|
||||||
if (! in_thread_list (pid))
|
attach_thread (pid, msg.th_p, &ti, 1);
|
||||||
attach_thread (pid, msg.th_p, &ti, 1);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case TD_DEATH:
|
case TD_DEATH:
|
||||||
|
@ -1023,7 +1026,12 @@ _initialize_thread_db (void)
|
||||||
add_target (&thread_db_ops);
|
add_target (&thread_db_ops);
|
||||||
|
|
||||||
/* Add ourselves to objfile event chain. */
|
/* Add ourselves to objfile event chain. */
|
||||||
target_new_objfile_chain = target_new_objfile_hook;
|
new_objfile_event_chain = target_new_objfile_hook;
|
||||||
target_new_objfile_hook = thread_db_new_objfile;
|
target_new_objfile_hook = thread_db_new_objfile;
|
||||||
}
|
}
|
||||||
|
add_show_from_set (add_set_cmd ("debug-linux-threads", class_support,
|
||||||
|
var_boolean, (char *) &debug_linux_threads,
|
||||||
|
"Set debug output for linux-threads \
|
||||||
|
on or off.\nUse \"on\" to enable, \"off\" to disable.", &setlist),
|
||||||
|
&showlist);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue