From: Ulrich Drepper Date: Wed, 10 Nov 1999 05:05:07 +0000 (+0000) Subject: Add from main branch. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=89dbd0a12f4353738dae9b7a48ef7c06b8b05a4c;p=thirdparty%2Fglibc.git Add from main branch. --- diff --git a/linuxthreads_db/ChangeLog b/linuxthreads_db/ChangeLog new file mode 100644 index 00000000000..f450d4828ed --- /dev/null +++ b/linuxthreads_db/ChangeLog @@ -0,0 +1,164 @@ +1999-11-08 Ulrich Drepper + + * td_thr_get_info.c: Make sure ti_lid is never zero. + + * proc_service.h: Add ps_getpid prototype. + +1999-11-03 Ulrich Drepper + + * thread_dbP.h (ta_ok): New function. + * td_ta_new.c: Add new handle to list. + * td_ta_delete.c: Remove handle from list. + * td_ta_clear_event.c: Use ta_ok to check for correct ta parameter. + * td_ta_enable_stats.c: Likewise. + * td_ta_event_addr.c: Likewise. + * td_ta_event_getmsg.c: Likewise. + * td_ta_get_nthreads.c: Likewise. + * td_ta_get_ph.c: Likewise. + * td_ta_get_stats.c: Likewise. + * td_ta_map_id2thr.c: Likewise. + * td_ta_map_lwp2thr.c: Likewise. + * td_ta_reset_stats.c: Likewise. + * td_ta_set_event.c: Likewise. + * td_ta_setconcurrency.c: Likewise. + * td_ta_thr_iter.c: Likewise. + + * td_ta_tsd_iter.c: Optimize memory retrieving. + + * Versions: New file. + + * td_thr_get_info.c (td_thr_get_info): Initialize ti_traceme. + +1999-11-02 Ulrich Drepper + + * td_ta_thr_iter.c (td_ta_thr_iter): Optimize a bit. Read all + handles at once. + + * thread_dbP.h (struct th_thragent): Add pthread_handle_num. + * td_ta_new.c: Initialize pthread_handle_num. + * td_ta_event_getmsg.c: If last event was already reported search + for another unreported event. + + * td_thr_get_info.c (td_thr_get_info): Initialize ti_events. + + * Makefile (libthread_db-routines): Add td_ta_set_event, + td_ta_event_getmsg, and td_ta_clear_event. + * td_ta_clear_event.c: New file. + * td_ta_event_getmsg.c: New file. + * td_ta_new.c: Get address of __pthread_last_event in target. + * td_ta_set_event.c: Don't overwrite old mask, set additional bits. + * td_thr_set_event.c: Likewise. + * td_thr_clear_event.c: Implement. + * thread_db.h: Declare td_ta_clear_event and td_ta_event_getmsg. + * thread_dbP.h (struct td_thragent): Add pthread_last_event. + + * td_ta_new.c: Don't test for __pthread_threads_debug. Get address + of __pthread_threads_events and fail if this is not possible. + * td_ta_event_addr.c: Implement. + * td_thr_event_enable.c: Implement. + * td_thr_event_getmsg.c: Implement. + * td_thr_set_event.c: Implement. + * td_ta_set_event.c: New file. + * thread_db.h (td_eventbuf_t): Define. + Declare td_ta_set_event. + * thread_dbP.h (struct td_thragent): Add pthread_threads_eventsp. + + * td_thr_getfpregs.c: For terminated threads return empty structure. + * td_thr_getgregs.c: Likewise. + * td_thr_setfpregs.c: Likewise. + * td_thr_setgregs.c: Likewise. + +1999-11-01 Ulrich Drepper + + * thread_db.h: Shuffle types around to make things work for gdb. + * thread_dbP.h: Include proc_service.h before thread_db.h. + + * thread_db.h: It's TD_NOLIBTHREAD, not TD_LIBTHREAD. + * td_ta_new.c: Likewise. + +1999-10-14 Ulrich Drepper + + * td_ta_new.c: p_startfct does not exist anymore. + + * td_thr_get_info.c: Always initialize start function. + + * td_ta_thr_iter.c: Don't return threads which exited (but are not + joined). + + * td_thr_validate.c: Don't skip manager thread. + +1999-10-13 Ulrich Drepper + + * td_ta_thr_iter.c: Use size of descriptor from *TA. + Don't return manager thread before it's actually running. + Actually use state parameter to distingusih at least a few states. + + * td_thr_get_info.c: Handle manager thread special. Fill in ti_lid, + ti_state, and ti_startfunc fields. + +1999-10-12 Andreas Jaeger + + * thread_dbP.h: Include for strlen declaration. Remove + __libc_write prototype since this is already declared in + linuxthreads/internals.h. + +1999-10-11 Ulrich Drepper + + * thread_db.h: Fix comment for ti_type. + + * td_thr_get_info.c: Initialize ti_type field. + + * td_ta_thr_iter.c: Also report the manager thread. + +1999-10-08 Andreas Jaeger + + * thread_db.h: Fix typos in comments. + + * td_ta_get_nthreads.c (td_ta_get_nthreads): Don't hardcode + libpthread library name, get it from instead. + * td_ta_new.c (td_ta_new): Likewise. + +1999-10-08 Ulrich Drepper + + * shlib-versions: New file. + +1999-10-07 Ulrich Drepper + + * Makefile: New file. + * proc_service.h: New file. + * td_init.c: New file. + * td_log.c: New file. + * td_ta_delete.c: New file. + * td_ta_enable_stats.c: New file. + * td_ta_event_addr.c: New file. + * td_ta_get_nthreads.c: New file. + * td_ta_get_ph.c: New file. + * td_ta_get_stats.c: New file. + * td_ta_map_id2thr.c: New file. + * td_ta_map_lwp2thr.c: New file. + * td_ta_new.c: New file. + * td_ta_reset_stats.c: New file. + * td_ta_setconcurrency.c: New file. + * td_ta_thr_iter.c: New file. + * td_ta_tsd_iter.c: New file. + * td_thr_clear_event.c: New file. + * td_thr_dbresume.c: New file. + * td_thr_dbsuspend.c: New file. + * td_thr_event_enable.c: New file. + * td_thr_event_getmsg.c: New file. + * td_thr_get_info.c: New file. + * td_thr_getfpregs.c: New file. + * td_thr_getgregs.c: New file. + * td_thr_getxregs.c: New file. + * td_thr_getxregsize.c: New file. + * td_thr_set_event.c: New file. + * td_thr_setfpregs.c: New file. + * td_thr_setgregs.c: New file. + * td_thr_setprio.c: New file. + * td_thr_setsigpending.c: New file. + * td_thr_setxregs.c: New file. + * td_thr_sigsetmask.c: New file. + * td_thr_tsd.c: New file. + * td_thr_validate.c: New file. + * thread_db.h: New file. + * thread_dbP.h: New file. diff --git a/linuxthreads_db/Makefile b/linuxthreads_db/Makefile new file mode 100644 index 00000000000..fa6b3bca5f5 --- /dev/null +++ b/linuxthreads_db/Makefile @@ -0,0 +1,51 @@ +# Copyright (C) 1999 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. + +# The GNU C Library 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 +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public +# License along with the GNU C Library; see the file COPYING.LIB. If not, +# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# Makefile for linuxthreads debug library subdirectory of GNU C Library. + +subdir := linuxthreads_db + +libthread_db-version = 1 + +extra-libs = libthread_db +extra-libs-others := $(extra-libs) + +headers = thread_db.h +libthread_db-routines = td_init td_log td_ta_delete td_ta_get_nthreads \ + td_ta_get_ph td_ta_map_id2thr td_ta_map_lwp2thr \ + td_ta_new td_ta_thr_iter td_ta_tsd_iter \ + td_thr_get_info td_thr_getfpregs td_thr_getgregs \ + td_thr_getxregs td_thr_getxregsize td_thr_setfpregs \ + td_thr_setgregs td_thr_setprio td_thr_setsigpending \ + td_thr_setxregs td_thr_sigsetmask td_thr_tsd \ + td_thr_validate td_thr_dbsuspend td_thr_dbresume \ + td_ta_setconcurrency td_ta_enable_stats \ + td_ta_reset_stats td_ta_get_stats td_ta_event_addr \ + td_thr_event_enable td_thr_set_event \ + td_thr_clear_event td_thr_event_getmsg \ + td_ta_set_event td_ta_event_getmsg \ + td_ta_clear_event + +libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes)) + +include ../Rules + +# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +# This ensures they will load libc.so for needed symbols if loaded by +# a statically-linked program that hasn't already loaded it. +$(objpfx)libpthread.so: $(common-objpfx)libc.so diff --git a/linuxthreads_db/proc_service.h b/linuxthreads_db/proc_service.h new file mode 100644 index 00000000000..8907b475f59 --- /dev/null +++ b/linuxthreads_db/proc_service.h @@ -0,0 +1,63 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* The definitions in this file must correspond to those in the debugger. */ +#include + +typedef enum +{ + PS_OK, /* generic "call succeeded" */ + PS_ERR, /* generic. */ + PS_BADPID, /* bad process handle */ + PS_BADLID, /* bad lwp identifier */ + PS_BADADDR, /* bad address */ + PS_NOSYM, /* p_lookup() could not find given symbol */ + PS_NOFREGS + /* + * FPU register set not available for given + * lwp + */ +} ps_err_e; + + +struct ps_prochandle; /* user defined. */ + + +extern ps_err_e ps_pdread(struct ps_prochandle *, + psaddr_t, void *, size_t); +extern ps_err_e ps_pdwrite(struct ps_prochandle *, + psaddr_t, const void *, size_t); +extern ps_err_e ps_ptread(struct ps_prochandle *, + psaddr_t, void *, size_t); +extern ps_err_e ps_ptwrite(struct ps_prochandle *, + psaddr_t, const void *, size_t); + +extern ps_err_e ps_pglobal_lookup(struct ps_prochandle *, + const char *object_name, const char *sym_name, psaddr_t *sym_addr); + + +extern ps_err_e ps_lgetregs(struct ps_prochandle *, + lwpid_t, prgregset_t); +extern ps_err_e ps_lsetregs(struct ps_prochandle *, + lwpid_t, const prgregset_t); +extern ps_err_e ps_lgetfpregs(struct ps_prochandle *, + lwpid_t, prfpregset_t *); +extern ps_err_e ps_lsetfpregs(struct ps_prochandle *, + lwpid_t, const prfpregset_t *); + +extern pid_t ps_getpid (struct ps_prochandle *); diff --git a/linuxthreads_db/shlib-versions b/linuxthreads_db/shlib-versions new file mode 100644 index 00000000000..592f7fa284e --- /dev/null +++ b/linuxthreads_db/shlib-versions @@ -0,0 +1,2 @@ +# The thread debug library +.*-.*-linux.* libthread_db=1 diff --git a/linuxthreads_db/td_init.c b/linuxthreads_db/td_init.c new file mode 100644 index 00000000000..e65edc4e933 --- /dev/null +++ b/linuxthreads_db/td_init.c @@ -0,0 +1,30 @@ +/* Initialization function of thread debugger support library. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_init (void) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/linuxthreads_db/td_log.c b/linuxthreads_db/td_log.c new file mode 100644 index 00000000000..0c4a3670f50 --- /dev/null +++ b/linuxthreads_db/td_log.c @@ -0,0 +1,32 @@ +/* Noop, left for historical reasons. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_log (void) +{ + /* This interface is deprecated in the Sun interface. We provide it + for compatibility but don't do anyhting ourself. We might in + future do some logging if this seems reasonable. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_clear_event.c b/linuxthreads_db/td_ta_clear_event.c new file mode 100644 index 00000000000..02d83360fa2 --- /dev/null +++ b/linuxthreads_db/td_ta_clear_event.c @@ -0,0 +1,53 @@ +/* Globally disable events. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_clear_event (ta, event) + const td_thragent_t *ta; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Write the new value into the thread data structure. */ + if (ps_pdread (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Remove the set bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] &= ~event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_delete.c b/linuxthreads_db/td_ta_delete.c new file mode 100644 index 00000000000..e9835776656 --- /dev/null +++ b/linuxthreads_db/td_ta_delete.c @@ -0,0 +1,58 @@ +/* Detach to target process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "thread_dbP.h" + + +td_err_e +td_ta_delete (td_thragent_t *ta) +{ + LOG (__FUNCTION__); + + /* Safety check. */ + if (ta == NULL || __td_agent_list == NULL) + return TD_BADTA; + + /* Remove the handle from the list. */ + if (ta == __td_agent_list->ta) + /* It's the first element of the list. */ + __td_agent_list = __td_agent_list->next; + else + { + /* We have to search for it. */ + struct agent_list *runp = __td_agent_list; + + while (runp->next != NULL && runp->next->ta != ta) + runp = runp->next; + + if (runp->next == NULL) + /* It's not a valid decriptor since it is not in the list. */ + return TD_BADTA; + + runp->next = runp->next->next; + } + + /* The handle was allocated in `td_ta_new'. */ + free (ta); + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_enable_stats.c b/linuxthreads_db/td_ta_enable_stats.c new file mode 100644 index 00000000000..abf4d200a9b --- /dev/null +++ b/linuxthreads_db/td_ta_enable_stats.c @@ -0,0 +1,35 @@ +/* Enable collection of statistics for process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_enable_stats (const td_thragent_t *ta, int enable) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_event_addr.c b/linuxthreads_db/td_ta_event_addr.c new file mode 100644 index 00000000000..7f217f10240 --- /dev/null +++ b/linuxthreads_db/td_ta_event_addr.c @@ -0,0 +1,75 @@ +/* Get event address. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "thread_dbP.h" + + +td_err_e +td_ta_event_addr (const td_thragent_t *ta, td_event_e event, td_notify_t *addr) +{ + td_err_e res = TD_NOEVENT; + const char *symbol = NULL; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + switch (event) + { + case TD_CREATE: + symbol = "__linuxthreads_create_event"; + break; + + case TD_DEATH: + symbol = "__linuxthreads_death_event"; + break; + + case TD_REAP: + symbol = "__linuxthreads_reap_event"; + break; + + default: + /* Event cannot be handled. */ + break; + } + + /* Now get the address. */ + if (symbol != NULL) + { + psaddr_t taddr; + + if (ps_pglobal_lookup (ta->ph, LIBPTHREAD_SO, symbol, &taddr) == PS_OK) + { + /* Success, we got the address. */ + addr->type = NOTIFY_BPT; + addr->u.bptaddr = taddr; + + res = TD_OK; + } + else + res = TD_ERR; + } + + return res; +} diff --git a/linuxthreads_db/td_ta_event_getmsg.c b/linuxthreads_db/td_ta_event_getmsg.c new file mode 100644 index 00000000000..4c635dc10da --- /dev/null +++ b/linuxthreads_db/td_ta_event_getmsg.c @@ -0,0 +1,128 @@ +/* Retrieve event. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include + +#include "thread_dbP.h" + + +td_err_e +td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg) +{ + /* XXX I cannot think of another way but using a static variable. */ + static td_thrhandle_t th; + td_eventbuf_t event; + psaddr_t addr; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Get the pointer to the thread descriptor with the last event. */ + if (ps_pdread (ta->ph, ta->pthread_last_event, + &addr, sizeof (void *)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* If the pointer is NULL no event occurred. */ + if (addr == 0) + return TD_NOMSG; + + /* Read the even structure from the target. */ + if (ps_pdread (ta->ph, + ((char *) addr + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Check whether an event occurred. */ + if (event.eventnum == TD_EVENT_NONE) + { + /* Oh well, this means the last event was already read. So + we have to look for any other event. */ + struct pthread_handle_struct handles[ta->pthread_threads_max]; + int num; + int i; + + /* Read the number of currently active threads. */ + if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) + != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Now read the handles. */ + if (ps_pdread (ta->ph, ta->handles, handles, + ta->pthread_threads_max * sizeof (handles[0])) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + for (i = 0; i < ta->pthread_threads_max && num > 0; ++i) + { + if (handles[i].h_descr == NULL) + /* No entry here. */ + continue; + + /* First count this active thread. */ + --num; + + if (handles[i].h_descr == addr) + /* We already handled this. */ + continue; + + /* Read the event data for this thread. */ + if (ps_pdread (ta->ph, + ((char *) handles[i].h_descr + + offsetof (struct _pthread_descr_struct, + p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; + + if (event.eventnum != TD_EVENT_NONE) + { + /* We found a thread with an unreported event. */ + addr = handles[i].h_descr; + break; + } + } + + /* If we haven't found any other event signal this to the user. */ + if (event.eventnum == TD_EVENT_NONE) + return TD_NOMSG; + } + + /* Generate the thread descriptor. */ + th.th_ta_p = (td_thragent_t *) ta; + th.th_unique = addr; + + /* Fill the user's data structure. */ + msg->event = event.eventnum; + msg->th_p = &th; + msg->msg.data = (uintptr_t) event.eventdata; + + /* And clear the event message in the target. */ + memset (&event, '\0', sizeof (td_eventbuf_t)); + if (ps_pdwrite (ta->ph, + ((char *) addr + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_get_nthreads.c b/linuxthreads_db/td_ta_get_nthreads.c new file mode 100644 index 00000000000..9396250534c --- /dev/null +++ b/linuxthreads_db/td_ta_get_nthreads.c @@ -0,0 +1,44 @@ +/* Get the number of threads in the process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" +#include + +td_err_e +td_ta_get_nthreads (const td_thragent_t *ta, int *np) +{ + psaddr_t addr; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Access the variable `__pthread_handles_num'. */ + if (ps_pglobal_lookup (ta->ph, LIBPTHREAD_SO, "__pthread_handles_num", + &addr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (ps_pdread (ta->ph, addr, np, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_get_ph.c b/linuxthreads_db/td_ta_get_ph.c new file mode 100644 index 00000000000..b748916ba1f --- /dev/null +++ b/linuxthreads_db/td_ta_get_ph.c @@ -0,0 +1,36 @@ +/* Get external process handle. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_get_ph (const td_thragent_t *ta, struct ps_prochandle **ph) +{ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + *ph = ta->ph; + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_get_stats.c b/linuxthreads_db/td_ta_get_stats.c new file mode 100644 index 00000000000..1741d8145f8 --- /dev/null +++ b/linuxthreads_db/td_ta_get_stats.c @@ -0,0 +1,35 @@ +/* Retrieve statistics for process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_get_stats (const td_thragent_t *ta, td_ta_stats_t *statsp) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_map_id2thr.c b/linuxthreads_db/td_ta_map_id2thr.c new file mode 100644 index 00000000000..6fb1ba96aa0 --- /dev/null +++ b/linuxthreads_db/td_ta_map_id2thr.c @@ -0,0 +1,63 @@ +/* Map thread ID to thread handle. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th) +{ + struct pthread_handle_struct phc; + struct _pthread_descr_struct pds; + int pthread_threads_max; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Make the following expression a bit smaller. */ + pthread_threads_max = ta->pthread_threads_max; + + /* We can compute the entry in the handle array we want. */ + if (ps_pdread (ta->ph, ta->handles + pt % pthread_threads_max, &phc, + sizeof (struct pthread_handle_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Test whether this entry is in use. */ + if (phc.h_descr == NULL) + return TD_BADTH; + + /* Next test: get the descriptor to see whether this is not an old + thread handle. */ + if (ps_pdread (ta->ph, phc.h_descr, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (pds.p_tid != pt) + return TD_BADTH; + + /* Create the `td_thrhandle_t' object. */ + th->th_ta_p = (td_thragent_t *) ta; + th->th_unique = phc.h_descr; + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_map_lwp2thr.c b/linuxthreads_db/td_ta_map_lwp2thr.c new file mode 100644 index 00000000000..f51bc18f169 --- /dev/null +++ b/linuxthreads_db/td_ta_map_lwp2thr.c @@ -0,0 +1,81 @@ +/* Which thread is running on an lwp? + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) +{ + int pthread_threads_max = ta->pthread_threads_max; + size_t sizeof_descr = ta->sizeof_descr; + struct pthread_handle_struct phc[pthread_threads_max]; + size_t cnt; +#ifdef ALL_THREADS_STOPPED + int num; +#else +# define num 1 +#endif + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Read all the descriptors. */ + if (ps_pdread (ta->ph, ta->handles, phc, + sizeof (struct pthread_handle_struct) * pthread_threads_max) + != PS_OK) + return TD_ERR; /* XXX Other error value? */ + +#ifdef ALL_THREADS_STOPPED + /* Read the number of currently active threads. */ + if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ +#endif + + /* Get the entries one after the other and find out whether the ID + matches. */ + for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt) + if (phc[cnt].h_descr != NULL) + { + struct _pthread_descr_struct pds; + +#ifdef ALL_THREADS_STOPPED + /* First count this active thread. */ + --num; +#endif + + if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (pds.p_pid == lwpid) + { + /* Found it. Now fill in the `td_thrhandle_t' object. */ + th->th_ta_p = (td_thragent_t *) ta; + th->th_unique = phc[cnt].h_descr; + + return TD_OK; + } + } + + return TD_NOLWP; +} diff --git a/linuxthreads_db/td_ta_new.c b/linuxthreads_db/td_ta_new.c new file mode 100644 index 00000000000..8d6ee9a7c56 --- /dev/null +++ b/linuxthreads_db/td_ta_new.c @@ -0,0 +1,154 @@ +/* Attach to target process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include + +#include "thread_dbP.h" + + +/* Datatype for the list of known thread agents. Normally there will + be exactly one so we don't spend much though on making it fast. */ +struct agent_list *__td_agent_list; + + +td_err_e +td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta) +{ + psaddr_t addr; + struct agent_list *elemp; + + LOG (__FUNCTION__); + + /* Get the global event mask. This is one of the variables which + are new in the thread library to enable debugging. If it is + not available we cannot debug. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, + "__pthread_threads_events", &addr) != PS_OK) + return TD_NOLIBTHREAD; + + /* Fill in the appropriate information. */ + *ta = (td_thragent_t *) malloc (sizeof (td_thragent_t)); + if (*ta == NULL) + return TD_MALLOC; + + /* Store the proc handle which we will pass to the callback functions + back into the debugger. */ + (*ta)->ph = ps; + + /* Remember the address. */ + (*ta)->pthread_threads_eventsp = (td_thr_events_t *) addr; + + /* Get the pointer to the variable pointing to the thread descriptor + with the last event. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, + "__pthread_last_event", + &(*ta)->pthread_last_event) != PS_OK) + { + free_return: + free (*ta); + return TD_ERR; + } + + /* Get the pointer to the variable containing the number of active + threads. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, + "__pthread_handles_num", + &(*ta)->pthread_handles_num) != PS_OK) + goto free_return; + + /* See whether the library contains the necessary symbols. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, "__pthread_handles", + &addr) != PS_OK) + goto free_return; + + (*ta)->handles = (struct pthread_handle_struct *) addr; + + + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, "pthread_keys", + &addr) != PS_OK) + goto free_return; + + /* Cast to the right type. */ + (*ta)->keys = (struct pthread_key_struct *) addr; + + /* Find out about the maximum number of threads. Old implementations + don't provide this information. In this case we assume that the + debug library is compiled with the same values. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, + "__linuxthreads_pthread_threads_max", &addr) != PS_OK) + (*ta)->pthread_threads_max = PTHREAD_THREADS_MAX; + else + { + if (ps_pdread (ps, addr, &(*ta)->pthread_threads_max, sizeof (int)) + != PS_OK) + goto free_return; + } + + /* Similar for the maximum number of thread local data keys. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, + "__linuxthreads_pthread_keys_max", &addr) != PS_OK) + (*ta)->pthread_keys_max = PTHREAD_KEYS_MAX; + else + { + if (ps_pdread (ps, addr, &(*ta)->pthread_keys_max, sizeof (int)) + != PS_OK) + goto free_return; + } + + /* And for the size of the second level arrays for the keys. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, + "__linuxthreads_pthread_sizeof_descr", &addr) + != PS_OK) + (*ta)->sizeof_descr = sizeof (struct _pthread_descr_struct); + else + { + if (ps_pdread (ps, addr, &(*ta)->sizeof_descr, sizeof (int)) != PS_OK) + goto free_return; + } + + /* Similar for the maximum number of thread local data keys. */ + if (ps_pglobal_lookup (ps, LIBPTHREAD_SO, + "__linuxthreads_pthread_keys_max", &addr) != PS_OK) + (*ta)->pthread_keys_max = PTHREAD_KEYS_MAX; + else + { + if (ps_pdread (ps, addr, &(*ta)->pthread_keys_max, sizeof (int)) + != PS_OK) + goto free_return; + } + + /* Now add the new agent descriptor to the list. */ + elemp = (struct agent_list *) malloc (sizeof (struct agent_list)); + if (elemp == NULL) + { + /* Argh, now that everything else worked... */ + free (*ta); + return TD_MALLOC; + } + + /* We don't care for thread-safety here. */ + elemp->ta = *ta; + elemp->next = __td_agent_list; + __td_agent_list = elemp; + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_reset_stats.c b/linuxthreads_db/td_ta_reset_stats.c new file mode 100644 index 00000000000..11401b9502c --- /dev/null +++ b/linuxthreads_db/td_ta_reset_stats.c @@ -0,0 +1,35 @@ +/* Reset statistics. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_reset_stats (const td_thragent_t *ta) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_set_event.c b/linuxthreads_db/td_ta_set_event.c new file mode 100644 index 00000000000..4d87fe1b556 --- /dev/null +++ b/linuxthreads_db/td_ta_set_event.c @@ -0,0 +1,53 @@ +/* Globally enable events. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_set_event (ta, event) + const td_thragent_t *ta; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Write the new value into the thread data structure. */ + if (ps_pdread (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Or the new bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] |= event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_setconcurrency.c b/linuxthreads_db/td_ta_setconcurrency.c new file mode 100644 index 00000000000..5bb2601b474 --- /dev/null +++ b/linuxthreads_db/td_ta_setconcurrency.c @@ -0,0 +1,35 @@ +/* Set suggested concurrency level for process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_setconcurrency (const td_thragent_t *ta, int level) +{ + /* This is something LinuxThreads does not support. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_NOCAPAB; +} diff --git a/linuxthreads_db/td_ta_thr_iter.c b/linuxthreads_db/td_ta_thr_iter.c new file mode 100644 index 00000000000..ecc86c78711 --- /dev/null +++ b/linuxthreads_db/td_ta_thr_iter.c @@ -0,0 +1,113 @@ +/* Iterate over a process's threads. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_thr_iter (const td_thragent_t *ta, td_thr_iter_f *callback, + void *cbdata_p, td_thr_state_e state, int ti_pri, + sigset_t *ti_sigmask_p, unsigned int ti_user_flags) +{ + int pthread_threads_max; + size_t sizeof_descr; + struct pthread_handle_struct *phc; + int cnt; +#ifdef ALL_THREADS_STOPPED + int num; +#else +# define num 1 +#endif + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + pthread_threads_max = ta->pthread_threads_max; + sizeof_descr = ta->sizeof_descr; + phc = (struct pthread_handle_struct *) alloca (sizeof (phc[0]) + * pthread_threads_max); + + /* Read all the descriptors. */ + if (ps_pdread (ta->ph, ta->handles, phc, + sizeof (struct pthread_handle_struct) * pthread_threads_max) + != PS_OK) + return TD_ERR; /* XXX Other error value? */ + +#ifdef ALL_THREADS_STOPPED + /* Read the number of currently active threads. */ + if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ +#endif + + /* Now get all descriptors, one after the other. */ + for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt) + if (phc[cnt].h_descr != NULL) + { + struct _pthread_descr_struct pds; + td_thrhandle_t th; + +#ifdef ALL_THREADS_STOPPED + /* First count this active thread. */ + --num; +#endif + + if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr) + != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* The manager thread must be handled special. The descriptor + exists but the thread only gets created when the first + `pthread_create' call is issued. A clear indication that + this happened is when the p_pid field is non-zero. */ + if (cnt == 1 && pds.p_pid == 0) + continue; + + /* Now test whether this thread matches the specified + conditions. */ + + /* Only if the priority level is as high or higher. */ + if (pds.p_priority < ti_pri) + continue; + + /* Test the state. + XXX This is incomplete. */ + if (state != TD_THR_ANY_STATE) + continue; + + /* XXX For now we ignore threads which are not running anymore. + The reason is that gdb tries to get the registers and fails. + In future we should have a special mode of the thread library + in which we keep the process around until the actual join + operation happened. */ + if (pds.p_exited != 0) + continue; + + /* Yep, it matches. Call the callback function. */ + th.th_ta_p = (td_thragent_t *) ta; + th.th_unique = phc[cnt].h_descr; + if (callback (&th, cbdata_p) != 0) + return TD_DBERR; + } + + return TD_OK; +} diff --git a/linuxthreads_db/td_ta_tsd_iter.c b/linuxthreads_db/td_ta_tsd_iter.c new file mode 100644 index 00000000000..c58928c9862 --- /dev/null +++ b/linuxthreads_db/td_ta_tsd_iter.c @@ -0,0 +1,55 @@ +/* Iterate over a process's thread-specific data. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback, + void *cbdata_p) +{ + struct pthread_key_struct *keys; + int pthread_keys_max; + int cnt; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + pthread_keys_max = ta->pthread_keys_max; + keys = (struct pthread_key_struct *) alloca (sizeof (keys[0]) + * pthread_keys_max); + + /* Read all the information about the keys. */ + if (ps_pdread (ta->ph, ta->keys, keys, + sizeof (keys[0]) * pthread_keys_max) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Now get all descriptors, one after the other. */ + for (cnt = 0; cnt < pthread_keys_max; ++cnt) + if (keys[cnt].in_use + /* Return with an error if the callback returns a nonzero value. */ + && callback (cnt, keys[cnt].destr, cbdata_p) != 0) + return TD_DBERR; + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_clear_event.c b/linuxthreads_db/td_thr_clear_event.c new file mode 100644 index 00000000000..8ef8cbbc40d --- /dev/null +++ b/linuxthreads_db/td_thr_clear_event.c @@ -0,0 +1,57 @@ +/* Disable specific event for thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "thread_dbP.h" + + +td_err_e +td_thr_clear_event (th, event) + const td_thrhandle_t *th; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Write the new value into the thread data structure. */ + if (ps_pdread (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Remove the set bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] &= ~event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_dbresume.c b/linuxthreads_db/td_thr_dbresume.c new file mode 100644 index 00000000000..692943a74f3 --- /dev/null +++ b/linuxthreads_db/td_thr_dbresume.c @@ -0,0 +1,30 @@ +/* Resume execution of given thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_dbresume (const td_thrhandle_t *th) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_NOCAPAB; +} diff --git a/linuxthreads_db/td_thr_dbsuspend.c b/linuxthreads_db/td_thr_dbsuspend.c new file mode 100644 index 00000000000..9e7ceb6532a --- /dev/null +++ b/linuxthreads_db/td_thr_dbsuspend.c @@ -0,0 +1,30 @@ +/* Suspend execution of given thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_dbsuspend (const td_thrhandle_t *th) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_NOCAPAB; +} diff --git a/linuxthreads_db/td_thr_event_enable.c b/linuxthreads_db/td_thr_event_enable.c new file mode 100644 index 00000000000..79e7d3a2aa3 --- /dev/null +++ b/linuxthreads_db/td_thr_event_enable.c @@ -0,0 +1,41 @@ +/* Enable event process-wide. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "thread_dbP.h" + + +td_err_e +td_thr_event_enable (th, onoff) + const td_thrhandle_t *th; + int onoff; +{ + LOG (__FUNCTION__); + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, p_report_events)), + &onoff, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_event_getmsg.c b/linuxthreads_db/td_thr_event_getmsg.c new file mode 100644 index 00000000000..4812ece4dd3 --- /dev/null +++ b/linuxthreads_db/td_thr_event_getmsg.c @@ -0,0 +1,60 @@ +/* Retrieve event. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include + +#include "thread_dbP.h" + + +td_err_e +td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg) +{ + td_eventbuf_t event; + + LOG (__FUNCTION__); + + /* Read the even structure from the target. */ + if (ps_pdread (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Check whether an event occurred. */ + if (event.eventnum == TD_EVENT_NONE) + /* Nothing. */ + return TD_NOMSG; + + /* Fill the user's data structure. */ + msg->event = event.eventnum; + msg->th_p = th; + msg->msg.data = (uintptr_t) event.eventdata; + + /* And clear the event message in the target. */ + memset (&event, '\0', sizeof (td_eventbuf_t)); + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_get_info.c b/linuxthreads_db/td_thr_get_info.c new file mode 100644 index 00000000000..25ad3408a9a --- /dev/null +++ b/linuxthreads_db/td_thr_get_info.c @@ -0,0 +1,75 @@ +/* Get thread information. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include + +#include "thread_dbP.h" + + +td_err_e +td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* Get the thread descriptor. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + th->th_ta_p->sizeof_descr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Fill in information. Clear first to provide reproducable + results for the fields we do not fill in. */ + memset (infop, '\0', sizeof (td_thrinfo_t)); + + /* We have to handle the manager thread special since the thread + descriptor in older versions is not fully initialized. */ + if (pds.p_nr == 1) + { + infop->ti_tid = th->th_ta_p->pthread_threads_max * 2 + 1; + infop->ti_type = TD_THR_SYSTEM; + infop->ti_state = TD_THR_RUN; + } + else + { + infop->ti_tid = pds.p_tid; + infop->ti_tls = (char *) pds.p_specific; + infop->ti_pri = pds.p_priority; + infop->ti_type = TD_THR_USER; + + if (pds.p_exited) + /* This should not happen. */ + infop->ti_state = TD_THR_ZOMBIE; + else + /* XXX For now there is no way to get more information. */ + infop->ti_state = TD_THR_RUN; + } + + /* Initialization which are the same in both cases. */ + infop->ti_lid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph); + infop->ti_ta_p = th->th_ta_p; + infop->ti_startfunc = pds.p_start_args.start_routine; + memcpy (&infop->ti_events, &pds.p_eventbuf.eventmask, + sizeof (td_thr_events_t)); + infop->ti_traceme = pds.p_report_events != 0; + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_getfpregs.c b/linuxthreads_db/td_thr_getfpregs.c new file mode 100644 index 00000000000..e6635d26445 --- /dev/null +++ b/linuxthreads_db/td_thr_getfpregs.c @@ -0,0 +1,44 @@ +/* Get a thread's floating-point register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* If the thread already terminated we return all zeroes. */ + if (pds.p_terminated) + memset (regset, '\0', sizeof (*regset)); + /* Otherwise get the register content through the callback. */ + else if (ps_lgetfpregs (th->th_ta_p->ph, pds.p_pid, regset) != PS_OK) + return TD_ERR; + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_getgregs.c b/linuxthreads_db/td_thr_getgregs.c new file mode 100644 index 00000000000..549c7d8b837 --- /dev/null +++ b/linuxthreads_db/td_thr_getgregs.c @@ -0,0 +1,44 @@ +/* Get a thread's general register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getgregs (const td_thrhandle_t *th, prgregset_t gregs) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* If the thread already terminated we return all zeroes. */ + if (pds.p_terminated) + memset (gregs, '\0', sizeof (gregs)); + /* Otherwise get the register content through the callback. */ + else if (ps_lgetregs (th->th_ta_p->ph, pds.p_pid, gregs) != PS_OK) + return TD_ERR; + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_getxregs.c b/linuxthreads_db/td_thr_getxregs.c new file mode 100644 index 00000000000..d8d568351b0 --- /dev/null +++ b/linuxthreads_db/td_thr_getxregs.c @@ -0,0 +1,30 @@ +/* Get a thread's extra state register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getxregs (const td_thrhandle_t *th, void *xregs) +{ + /* XXX This might be platform specific. */ + LOG (__FUNCTION__); + return TD_NOXREGS; +} diff --git a/linuxthreads_db/td_thr_getxregsize.c b/linuxthreads_db/td_thr_getxregsize.c new file mode 100644 index 00000000000..f704a31e81b --- /dev/null +++ b/linuxthreads_db/td_thr_getxregsize.c @@ -0,0 +1,30 @@ +/* Get the size of the extra state register set for this architecture. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getxregsize (const td_thrhandle_t *th, int *sizep) +{ + /* XXX This might be platform specific. */ + LOG (__FUNCTION__); + return TD_NOXREGS; +} diff --git a/linuxthreads_db/td_thr_set_event.c b/linuxthreads_db/td_thr_set_event.c new file mode 100644 index 00000000000..583a2f8042c --- /dev/null +++ b/linuxthreads_db/td_thr_set_event.c @@ -0,0 +1,57 @@ +/* Enable specific event for thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include + +#include "thread_dbP.h" + + +td_err_e +td_thr_set_event (th, event) + const td_thrhandle_t *th; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Write the new value into the thread data structure. */ + if (ps_pdread (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Or the new bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] |= event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_setfpregs.c b/linuxthreads_db/td_thr_setfpregs.c new file mode 100644 index 00000000000..0c426b3d364 --- /dev/null +++ b/linuxthreads_db/td_thr_setfpregs.c @@ -0,0 +1,42 @@ +/* Set a thread's floating-point register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setfpregs (const td_thrhandle_t *th, const prfpregset_t *fpregs) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* Only set the registers if the thread hasn't yet terminated. */ + if (pds.p_terminated == 0 + && ps_lsetfpregs (th->th_ta_p->ph, pds.p_pid, fpregs) != PS_OK) + return TD_ERR; + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_setgregs.c b/linuxthreads_db/td_thr_setgregs.c new file mode 100644 index 00000000000..72f95b1ca78 --- /dev/null +++ b/linuxthreads_db/td_thr_setgregs.c @@ -0,0 +1,42 @@ +/* Set a thread's general register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setgregs (const td_thrhandle_t *th, prgregset_t gregs) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* Only set the registers if the thread hasn't yet terminated. */ + if (pds.p_terminated == 0 + && ps_lsetregs (th->th_ta_p->ph, pds.p_pid, gregs) != PS_OK) + return TD_ERR; + + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_setprio.c b/linuxthreads_db/td_thr_setprio.c new file mode 100644 index 00000000000..03a503d01ea --- /dev/null +++ b/linuxthreads_db/td_thr_setprio.c @@ -0,0 +1,30 @@ +/* Set a thread's priority. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setprio (const td_thrhandle_t *th, int prio) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_setsigpending.c b/linuxthreads_db/td_thr_setsigpending.c new file mode 100644 index 00000000000..815cd2226d7 --- /dev/null +++ b/linuxthreads_db/td_thr_setsigpending.c @@ -0,0 +1,31 @@ +/* Raise a signal for a thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setsigpending (const td_thrhandle_t *th, unsigned char n, + const sigset_t *ss) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_setxregs.c b/linuxthreads_db/td_thr_setxregs.c new file mode 100644 index 00000000000..4b4fc34752d --- /dev/null +++ b/linuxthreads_db/td_thr_setxregs.c @@ -0,0 +1,30 @@ +/* Set a thread's extra state register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setxregs (const td_thrhandle_t *ta, const void *addr) +{ + /* XXX This might have to be platform specific. */ + LOG (__FUNCTION__); + return TD_NOXREGS; +} diff --git a/linuxthreads_db/td_thr_sigsetmask.c b/linuxthreads_db/td_thr_sigsetmask.c new file mode 100644 index 00000000000..88115976ce5 --- /dev/null +++ b/linuxthreads_db/td_thr_sigsetmask.c @@ -0,0 +1,30 @@ +/* Set a thread's signal mask. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_sigsetmask (const td_thrhandle_t *th, const sigset_t *ss) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/linuxthreads_db/td_thr_tsd.c b/linuxthreads_db/td_thr_tsd.c new file mode 100644 index 00000000000..0453c981ea8 --- /dev/null +++ b/linuxthreads_db/td_thr_tsd.c @@ -0,0 +1,76 @@ +/* Get a thread-specific data pointer for a thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_tsd (const td_thrhandle_t *th, const thread_key_t tk, void **data) +{ + struct _pthread_descr_struct pds; + struct pthread_key_struct *keys = th->th_ta_p->keys; + struct pthread_key_struct key; + int pthread_keys_max = th->th_ta_p->pthread_keys_max; + int pthread_key_2ndlevel_size = th->th_ta_p->pthread_key_2ndlevel_size; + unsigned int idx1st; + unsigned int idx2nd; + void *p; + + LOG (__FUNCTION__); + + /* Get the thread descriptor. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Check correct value of key. */ + if (tk >= pthread_keys_max) + return TD_BADKEY; + + /* Get the key entry. */ + if (ps_pdread (th->th_ta_p->ph, keys, &key, + sizeof (struct pthread_key_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Fail if this key is not at all used. */ + if (! key.in_use) + return TD_BADKEY; + + /* Compute the indeces. */ + idx1st = tk / pthread_key_2ndlevel_size; + idx2nd = tk % pthread_key_2ndlevel_size; + + /* Check the pointer to the second level array. */ + if (pds.p_specific[idx1st] == NULL) + return TD_NOTSD; + + /* Now get the real key. + XXX I don't know whether it's correct but there is currently no + easy way to determine whether a key was never set or the value + is NULL. We return an error whenever the value is NULL. */ + if (ps_pdread (th->th_ta_p->ph, &pds.p_specific[idx1st][idx2nd], &p, + sizeof (void *)) != PS_OK) + return TD_ERR; + + if (p != NULL) + *data = p; + + return p != NULL ? TD_OK : TD_NOTSD; +} diff --git a/linuxthreads_db/td_thr_validate.c b/linuxthreads_db/td_thr_validate.c new file mode 100644 index 00000000000..81c3b50214e --- /dev/null +++ b/linuxthreads_db/td_thr_validate.c @@ -0,0 +1,51 @@ +/* Validate a thread handle. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_validate (const td_thrhandle_t *th) +{ + struct pthread_handle_struct *handles = th->th_ta_p->handles; + int pthread_threads_max = th->th_ta_p->pthread_threads_max; + int cnt; + + LOG (__FUNCTION__); + + /* Now get all descriptors, one after the other. */ + for (cnt = 0; cnt < pthread_threads_max; ++cnt, ++handles) + { + struct pthread_handle_struct phc; + + if (ps_pdread (th->th_ta_p->ph, handles, &phc, + sizeof (struct pthread_handle_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (phc.h_descr != NULL && phc.h_descr == th->th_unique) + { + /* XXX There should be another test using the TID but this is + currently not available. */ + return TD_OK; + } + } + + return TD_ERR; +} diff --git a/linuxthreads_db/thread_db.h b/linuxthreads_db/thread_db.h new file mode 100644 index 00000000000..6301d7fa5fb --- /dev/null +++ b/linuxthreads_db/thread_db.h @@ -0,0 +1,436 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _THREAD_DB_H +#define _THREAD_DB_H 1 + +/* This is the debugger interface for the LinuxThreads library. It is + modelled closely after the interface with same names in Solaris with + the goal to share the same code in the debugger. */ +#include +#include +#include +#include + + +/* Error codes of the library. */ +typedef enum +{ + TD_OK, /* No error. */ + TD_ERR, /* No further specified error. */ + TD_NOTHR, /* No matching thread found. */ + TD_NOSV, /* No matching synchronization handle found. */ + TD_NOLWP, /* No matching light-weighted process found. */ + TD_BADPH, /* Invalid process handle. */ + TD_BADTH, /* Invalid thread handle. */ + TD_BADSH, /* Invalid synchronization handle. */ + TD_BADTA, /* Invalid thread agent. */ + TD_BADKEY, /* Invalid key. */ + TD_NOMSG, /* No event available. */ + TD_NOFPREGS, /* No floating-point register content available. */ + TD_NOLIBTHREAD, /* Application not linked with thread library. */ + TD_NOEVENT, /* Requested event is not supported. */ + TD_NOCAPAB, /* Capability not available. */ + TD_DBERR, /* Internal debug library error. */ + TD_NOAPLIC, /* Operation is not applicable. */ + TD_NOTSD, /* No thread-specific data available. */ + TD_MALLOC, /* Out of memory. */ + TD_PARTIALREG, /* Not entire register set was read or written. */ + TD_NOXREGS /* X register set not available for given thread. */ +} td_err_e; + + +/* Possible thread states. TD_THR_ANY_STATE is a pseudo-state used to + select threads regardless of state in td_ta_thr_iter(). */ +typedef enum +{ + TD_THR_ANY_STATE, + TD_THR_UNKNOWN, + TD_THR_STOPPED, + TD_THR_RUN, + TD_THR_ACTIVE, + TD_THR_ZOMBIE, + TD_THR_SLEEP, + TD_THR_STOPPED_ASLEEP +} td_thr_state_e; + +/* Thread type: user or system. TD_THR_ANY_TYPE is a pseudo-type used + to select threads regardless of type in td_ta_thr_iter(). */ +typedef enum +{ + TD_THR_ANY_TYPE, + TD_THR_USER, + TD_THR_SYSTEM +} td_thr_type_e; + + +/* Types of the debugging library. */ + +/* Handle for a process. This type is opaque. */ +typedef struct td_thragent td_thragent_t; + +/* The actual thread handle type. This is also opaque. */ +typedef struct td_thrhandle +{ + td_thragent_t *th_ta_p; + psaddr_t th_unique; +} td_thrhandle_t; + + +/* Flags for `td_ta_thr_iter'. */ +#define TD_THR_ANY_USER_FLAGS 0xffffffff +#define TD_THR_LOWEST_PRIORITY -20 +#define TD_SIGNO_MASK NULL + + +#define TD_EVENTSIZE 2 +#define BT_UISHIFT 5 /* log base 2 of BT_NBIPUI, to extract word index */ +#define BT_NBIPUI (1 << BT_UISHIFT) /* n bits per uint */ +#define BT_UIMASK (BT_NBIPUI - 1) /* to extract bit index */ + +/* Bitmask of enabled events. */ +typedef struct td_thr_events +{ + uint32_t event_bits[TD_EVENTSIZE]; +} td_thr_events_t; + +/* Event set manipulation macros. */ +#define __td_eventmask(n) \ + (UINT32_C (1) << (((n) - 1) & BT_UIMASK)) +#define __td_eventword(n) \ + ((UINT32_C ((n) - 1)) >> BT_UISHIFT) + +#define td_event_emptyset(setp) \ + do { \ + int __i; \ + for (__i = TD_EVENTSIZE; __i > 0; --__i) \ + (setp)->event_bits[__i - 1] = 0; \ + } while (0) + +#define td_event_fillset(setp) \ + do { \ + int __i; \ + for (__i = TD_EVENTSIZE; __i > 0; --__i) \ + (setp)->event_bits[__i - 1] = UINT32_C (0xffffffff); \ + } while (0) + +#define td_event_addset(setp, n) \ + (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n)) +#define td_event_delset(setp, n) \ + (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n)) +#define td_eventismember(setp, n) \ + (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)])) +#if TD_EVENTSIZE == 2 +# define td_eventisempty(setp) \ + (!((setp)->event_bits[0]) && !((setp)->event_bits[1])) +#else +# error "td_eventisempty must be changed to match TD_EVENTSIZE" +#endif + +/* Events reportable by the thread implementation. */ +typedef enum +{ + TD_ALL_EVENTS, /* Pseudo-event number. */ + TD_EVENT_NONE = TD_ALL_EVENTS, /* Depends on context. */ + TD_READY, /* Is executable now. */ + TD_SLEEP, /* Blocked in a synchronization obj. */ + TD_SWITCHTO, /* Now assigned to a process. */ + TD_SWITCHFROM, /* Not anymore assigned to a process. */ + TD_LOCK_TRY, /* Trying to get an unavailable lock. */ + TD_CATCHSIG, /* Signal posted to the thread. */ + TD_IDLE, /* Process getting idle. */ + TD_CREATE, /* New thread created. */ + TD_DEATH, /* Thread terminated. */ + TD_PREEMPT, /* Preempted. */ + TD_PRI_INHERIT, /* Inherited elevated priority. */ + TD_REAP, /* Reaped. */ + TD_CONCURRENCY, /* Number of processes changing. */ + TD_TIMEOUT, /* Conditional variable wait timed out. */ + TD_MIN_EVENT_NUM = TD_READY, + TD_MAX_EVENT_NUM = TD_TIMEOUT, + TD_EVENTS_ENABLE = 31 /* Event reporting enabled. */ +} td_event_e; + +/* Values representing the different ways events are reported. */ +typedef enum +{ + NOTIFY_BPT, /* User must insert breakpoint at u.bptaddr. */ + NOTIFY_AUTOBPT, /* Breakpoint at u.bptaddr is automatically + inserted. */ + NOTIFY_SYSCALL /* System call u.syscallno will be invoked. */ +} td_notify_e; + +/* Description how event type is reported. */ +typedef struct td_notify +{ + td_notify_e type; /* Way the event is reported. */ + union + { + psaddr_t bptaddr; /* Address of breakpoint. */ + int syscallno; /* Number of system call used. */ + } u; +} td_notify_t; + +/* Structure used to report event. */ +typedef struct td_event_msg +{ + td_event_e event; /* Event type being reported. */ + const td_thrhandle_t *th_p; /* Thread reporting the event. */ + union + { +# if 0 + td_synchandle_t *sh; /* Handle of synchronization object. */ +#endif + uintptr_t data; /* Event specific data. */ + } msg; +} td_event_msg_t; + +/* Structure containing event data available in each thread structure. */ +typedef struct +{ + td_thr_events_t eventmask; /* Mask of enabled events. */ + td_event_e eventnum; /* Number of last event. */ + void *eventdata; /* Data associated with event. */ +} td_eventbuf_t; + + +/* Gathered statistics about the process. */ +typedef struct td_ta_stats +{ + int nthreads; /* Total number of threads in use. */ + int r_concurrency; /* Concurrency level requested by user. */ + int nrunnable_num; /* Average runnable threads, numerator. */ + int nrunnable_den; /* Average runnable threads, denominator. */ + int a_concurrency_num; /* Achieved concurrency level, numerator. */ + int a_concurrency_den; /* Achieved concurrency level, denominator. */ + int nlwps_num; /* Average number of processes in use, + numerator. */ + int nlwps_den; /* Average number of processes in use, + denominator. */ + int nidle_num; /* Average number of idling processes, + numerator. */ + int nidle_den; /* Average number of idling processes, + denominator. */ +} td_ta_stats_t; + + +/* Since Sun's library is based on Solaris threads we have to define a few + types to map them to POSIX threads. */ +typedef pthread_t thread_t; +typedef pthread_key_t thread_key_t; + + +/* Callback for iteration over threads. */ +typedef int td_thr_iter_f (const td_thrhandle_t *, void *); + +/* Callback for iteration over thread local data. */ +typedef int td_key_iter_f (thread_key_t, void (*) (void *), void *); + + + +/* Forward declaration. This has to be defined by the user. */ +struct ps_prochandle; + + +/* Information about the thread. */ +typedef struct td_thrinfo +{ + td_thragent_t *ti_ta_p; /* Process handle. */ + unsigned int ti_user_flags; /* Unused. */ + thread_t ti_tid; /* Thread ID returned by + pthread_create(). */ + char *ti_tls; /* Pointer to thread-local data. */ + psaddr_t ti_startfunc; /* Start function passed to + pthread_create(). */ + psaddr_t ti_stkbase; /* Base of thread's stack. */ + long int ti_stksize; /* Size of thread's stack. */ + psaddr_t ti_ro_area; /* Unused. */ + int ti_ro_size; /* Unused. */ + td_thr_state_e ti_state; /* Thread state. */ + unsigned char ti_db_suspended; /* Nonzero if suspended by debugger. */ + td_thr_type_e ti_type; /* Type of the thread (system vs + user thread). */ + intptr_t ti_pc; /* Unused. */ + intptr_t ti_sp; /* Unused. */ + short int ti_flags; /* Unused. */ + int ti_pri; /* Thread priority. */ + lwpid_t ti_lid; /* Unused. */ + sigset_t ti_sigmask; /* Signal mask. */ + unsigned char ti_traceme; /* Nonzero if event reporting + enabled. */ + unsigned char ti_preemptflag; /* Unused. */ + unsigned char ti_pirecflag; /* Unused. */ + sigset_t ti_pending; /* Set of pending signals. */ + td_thr_events_t ti_events; /* Set of enabled events. */ +} td_thrinfo_t; + + + +/* Prototypes for exported library functions. */ + +/* Initialize the thread debug support library. */ +extern td_err_e td_init (void); + +/* Historical relict. Should not be used anymore. */ +extern td_err_e td_log (void); + +/* Generate new thread debug library handle for process PS. */ +extern td_err_e td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta); + +/* Free resources allocated for TA. */ +extern td_err_e td_ta_delete (td_thragent_t *__ta); + +/* Get number of currently running threads in process associated with TA. */ +extern td_err_e td_ta_get_nthreads (const td_thragent_t *__ta, int *__np); + +/* Return process handle passed in `td_ta_new' for process associated with + TA. */ +extern td_err_e td_ta_get_ph (const td_thragent_t *__ta, + struct ps_prochandle **__ph); + +/* Map thread library handle PT to thread debug library handle for process + associated with TA and store result in *TH. */ +extern td_err_e td_ta_map_id2thr (const td_thragent_t *__ta, pthread_t __pt, + td_thrhandle_t *__th); + +/* Map process ID LWPID to thread debug library handle for process + associated with TA and store result in *TH. */ +extern td_err_e td_ta_map_lwp2thr (const td_thragent_t *__ta, lwpid_t __lwpid, + td_thrhandle_t *__th); + + +/* Call for each thread in a process associated with TA the callback function + CALLBACK. */ +extern td_err_e td_ta_thr_iter (const td_thragent_t *__ta, + td_thr_iter_f *__callback, void *__cbdata_p, + td_thr_state_e __state, int __ti_pri, + sigset_t *__ti_sigmask_p, + unsigned int __ti_user_flags); + +/* Call for each defined thread local data entry the callback function KI. */ +extern td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki, + void *__p); + + +/* Get event address for EVENT. */ +extern td_err_e td_ta_event_addr (const td_thragent_t *__ta, + td_event_e __event, td_notify_t *__ptr); + +/* Enable EVENT in global mask. */ +extern td_err_e td_ta_set_event (const td_thragent_t *__ta, + td_thr_events_t *__event); + +/* Disable EVENT in global mask. */ +extern td_err_e td_ta_clear_event (const td_thragent_t *__ta, + td_thr_events_t *__event); + +/* Return information about last event. */ +extern td_err_e td_ta_event_getmsg (const td_thragent_t *__ta, + td_event_msg_t *msg); + + +/* Set suggested concurrency level for process associated with TA. */ +extern td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level); + + +/* Enable collecting statistics for process associated with TA. */ +extern td_err_e td_ta_enable_stats (const td_thragent_t *__ta, int __enable); + +/* Reset statistics. */ +extern td_err_e td_ta_reset_stats (const td_thragent_t *__ta); + +/* Retrieve statistics from process associated with TA. */ +extern td_err_e td_ta_get_stats (const td_thragent_t *__ta, + td_ta_stats_t *__statsp); + + +/* Validate that TH is a thread handle. */ +extern td_err_e td_thr_validate (const td_thrhandle_t *__th); + +/* Return information about thread TH. */ +extern td_err_e td_thr_get_info (const td_thrhandle_t *__th, + td_thrinfo_t *__infop); + +/* Retrieve floating-point register contents of process running thread TH. */ +extern td_err_e td_thr_getfpregs (const td_thrhandle_t *__th, + prfpregset_t *__regset); + +/* Retrieve general register contents of process running thread TH. */ +extern td_err_e td_thr_getgregs (const td_thrhandle_t *__th, + prgregset_t __gregs); + +/* Retrieve extended register contents of process running thread TH. */ +extern td_err_e td_thr_getxregs (const td_thrhandle_t *__th, void *__xregs); + +/* Get size of extended register set of process running thread TH. */ +extern td_err_e td_thr_getxregsize (const td_thrhandle_t *__th, int *__sizep); + +/* Set floating-point register contents of process running thread TH. */ +extern td_err_e td_thr_setfpregs (const td_thrhandle_t *__th, + const prfpregset_t *__fpregs); + +/* Set general register contents of process running thread TH. */ +extern td_err_e td_thr_setgregs (const td_thrhandle_t *__th, + prgregset_t __gregs); + +/* Set extended register contents of process running thread TH. */ +extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th, + const void *__addr); + + +/* Enable reporting for EVENT for thread TH. */ +extern td_err_e td_thr_event_enable (const td_thrhandle_t *__th, int __event); + +/* Enable EVENT for thread TH. */ +extern td_err_e td_thr_set_event (const td_thrhandle_t *__th, + td_thr_events_t *__event); + +/* Disable EVENT for thread TH. */ +extern td_err_e td_thr_clear_event (const td_thrhandle_t *__th, + td_thr_events_t *__event); + +/* Get event message for thread TH. */ +extern td_err_e td_thr_event_getmsg (const td_thrhandle_t *__th, + td_event_msg_t *__msg); + + +/* Set priority of thread TH. */ +extern td_err_e td_thr_setprio (const td_thrhandle_t *__th, int __prio); + + +/* Set pending signals for thread TH. */ +extern td_err_e td_thr_setsigpending (const td_thrhandle_t *__th, + unsigned char __n, const sigset_t *__ss); + +/* Set signal mask for thread TH. */ +extern td_err_e td_thr_sigsetmask (const td_thrhandle_t *__th, + const sigset_t *__ss); + + +/* Return thread local data associated with key TK in thread TH. */ +extern td_err_e td_thr_tsd (const td_thrhandle_t *__th, + const thread_key_t __tk, void **__data); + + +/* Suspend execution of thread TH. */ +extern td_err_e td_thr_dbsuspend (const td_thrhandle_t *__th); + +/* Resume execution of thread TH. */ +extern td_err_e td_thr_dbresume (const td_thrhandle_t *__th); + +#endif /* thread_db.h */ diff --git a/linuxthreads_db/thread_dbP.h b/linuxthreads_db/thread_dbP.h new file mode 100644 index 00000000000..7e9fb486c66 --- /dev/null +++ b/linuxthreads_db/thread_dbP.h @@ -0,0 +1,78 @@ +/* Private header for thread debug library. */ +#ifndef _THREAD_DBP_H +#define _THREAD_DBP_H 1 + +#include +#include "proc_service.h" +#include "thread_db.h" +#include "../linuxthreads/internals.h" + + +/* Comment out the following for less verbose output. */ +#define LOG(c) __libc_write (2, c "\n", strlen (c "\n")) + + +/* Handle for a process. This type is opaque. */ +struct td_thragent +{ + /* Delivered by the debugger and we have to pass it back in the + proc callbacks. */ + struct ps_prochandle *ph; + + /* Some cached information. */ + + /* Address of the `__pthread_handles' array. */ + struct pthread_handle_struct *handles; + + /* Address of the `pthread_kyes' array. */ + struct pthread_key_struct *keys; + + /* Maximum number of threads. */ + int pthread_threads_max; + + /* Maximum number of thread-local data keys. */ + int pthread_keys_max; + + /* Size of 2nd level array for thread-local data keys. */ + int pthread_key_2ndlevel_size; + + /* Sizeof struct _pthread_descr_struct. */ + int sizeof_descr; + + /* Pointer to the `__pthread_threads_events' variable in the target. */ + psaddr_t pthread_threads_eventsp; + + /* Pointer to the `__pthread_last_event' variable in the target. */ + psaddr_t pthread_last_event; + + /* Pointer to the `__pthread_handles_num' variable. */ + psaddr_t pthread_handles_num; +}; + + +/* Type used internally to keep track of thread agent descriptors. */ +struct agent_list +{ + td_thragent_t *ta; + struct agent_list *next; +}; + +/* List of all known descriptors. */ +extern struct agent_list *__td_agent_list; + +/* Function used to test for correct thread agent pointer. */ +static inline int +ta_ok (const td_thragent_t *ta) +{ + struct agent_list *runp = __td_agent_list; + + if (ta == NULL) + return 0; + + while (runp != NULL && runp->ta != ta) + runp = runp->next; + + return runp != NULL; +} + +#endif /* thread_dbP.h */