From e356ea321c8098cf1a83a67e27d64c44de08a298 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Wed, 20 Feb 2002 09:18:50 +0000 Subject: Merge in the pthread library. This is the linuxthreads library taken from glibc 2.1.3 and ported to work with uClibc by Stefan Soucek and Erik Andersen (me). Stefan has hacked things up such that linuxthreads runs on MMU-less systems (tested only on arm-nommu). Erik cleaned things up and made it work properly as a shared library. -Erik --- libpthread/linuxthreads_db/ChangeLog | 208 +++++++++++ libpthread/linuxthreads_db/Makefile | 68 ++++ libpthread/linuxthreads_db/Versions | 15 + libpthread/linuxthreads_db/proc_service.h | 70 ++++ libpthread/linuxthreads_db/td_init.c | 32 ++ libpthread/linuxthreads_db/td_log.c | 32 ++ libpthread/linuxthreads_db/td_ta_clear_event.c | 53 +++ libpthread/linuxthreads_db/td_ta_delete.c | 58 +++ libpthread/linuxthreads_db/td_ta_enable_stats.c | 35 ++ libpthread/linuxthreads_db/td_ta_event_addr.c | 75 ++++ libpthread/linuxthreads_db/td_ta_event_getmsg.c | 128 +++++++ libpthread/linuxthreads_db/td_ta_get_nthreads.c | 44 +++ libpthread/linuxthreads_db/td_ta_get_ph.c | 36 ++ libpthread/linuxthreads_db/td_ta_get_stats.c | 35 ++ libpthread/linuxthreads_db/td_ta_map_id2thr.c | 63 ++++ libpthread/linuxthreads_db/td_ta_map_lwp2thr.c | 81 ++++ libpthread/linuxthreads_db/td_ta_new.c | 154 ++++++++ libpthread/linuxthreads_db/td_ta_reset_stats.c | 35 ++ libpthread/linuxthreads_db/td_ta_set_event.c | 53 +++ libpthread/linuxthreads_db/td_ta_setconcurrency.c | 35 ++ libpthread/linuxthreads_db/td_ta_thr_iter.c | 143 +++++++ libpthread/linuxthreads_db/td_ta_tsd_iter.c | 56 +++ libpthread/linuxthreads_db/td_thr_clear_event.c | 57 +++ libpthread/linuxthreads_db/td_thr_dbresume.c | 30 ++ libpthread/linuxthreads_db/td_thr_dbsuspend.c | 30 ++ libpthread/linuxthreads_db/td_thr_event_enable.c | 41 ++ libpthread/linuxthreads_db/td_thr_event_getmsg.c | 60 +++ libpthread/linuxthreads_db/td_thr_get_info.c | 75 ++++ libpthread/linuxthreads_db/td_thr_getfpregs.c | 44 +++ libpthread/linuxthreads_db/td_thr_getgregs.c | 44 +++ libpthread/linuxthreads_db/td_thr_getxregs.c | 30 ++ libpthread/linuxthreads_db/td_thr_getxregsize.c | 30 ++ libpthread/linuxthreads_db/td_thr_set_event.c | 57 +++ libpthread/linuxthreads_db/td_thr_setfpregs.c | 42 +++ libpthread/linuxthreads_db/td_thr_setgregs.c | 42 +++ libpthread/linuxthreads_db/td_thr_setprio.c | 30 ++ libpthread/linuxthreads_db/td_thr_setsigpending.c | 31 ++ libpthread/linuxthreads_db/td_thr_setxregs.c | 30 ++ libpthread/linuxthreads_db/td_thr_sigsetmask.c | 30 ++ libpthread/linuxthreads_db/td_thr_tsd.c | 76 ++++ libpthread/linuxthreads_db/td_thr_validate.c | 51 +++ libpthread/linuxthreads_db/thread_db.h | 436 ++++++++++++++++++++++ libpthread/linuxthreads_db/thread_dbP.h | 83 ++++ 43 files changed, 2858 insertions(+) create mode 100644 libpthread/linuxthreads_db/ChangeLog create mode 100644 libpthread/linuxthreads_db/Makefile create mode 100644 libpthread/linuxthreads_db/Versions create mode 100644 libpthread/linuxthreads_db/proc_service.h create mode 100644 libpthread/linuxthreads_db/td_init.c create mode 100644 libpthread/linuxthreads_db/td_log.c create mode 100644 libpthread/linuxthreads_db/td_ta_clear_event.c create mode 100644 libpthread/linuxthreads_db/td_ta_delete.c create mode 100644 libpthread/linuxthreads_db/td_ta_enable_stats.c create mode 100644 libpthread/linuxthreads_db/td_ta_event_addr.c create mode 100644 libpthread/linuxthreads_db/td_ta_event_getmsg.c create mode 100644 libpthread/linuxthreads_db/td_ta_get_nthreads.c create mode 100644 libpthread/linuxthreads_db/td_ta_get_ph.c create mode 100644 libpthread/linuxthreads_db/td_ta_get_stats.c create mode 100644 libpthread/linuxthreads_db/td_ta_map_id2thr.c create mode 100644 libpthread/linuxthreads_db/td_ta_map_lwp2thr.c create mode 100644 libpthread/linuxthreads_db/td_ta_new.c create mode 100644 libpthread/linuxthreads_db/td_ta_reset_stats.c create mode 100644 libpthread/linuxthreads_db/td_ta_set_event.c create mode 100644 libpthread/linuxthreads_db/td_ta_setconcurrency.c create mode 100644 libpthread/linuxthreads_db/td_ta_thr_iter.c create mode 100644 libpthread/linuxthreads_db/td_ta_tsd_iter.c create mode 100644 libpthread/linuxthreads_db/td_thr_clear_event.c create mode 100644 libpthread/linuxthreads_db/td_thr_dbresume.c create mode 100644 libpthread/linuxthreads_db/td_thr_dbsuspend.c create mode 100644 libpthread/linuxthreads_db/td_thr_event_enable.c create mode 100644 libpthread/linuxthreads_db/td_thr_event_getmsg.c create mode 100644 libpthread/linuxthreads_db/td_thr_get_info.c create mode 100644 libpthread/linuxthreads_db/td_thr_getfpregs.c create mode 100644 libpthread/linuxthreads_db/td_thr_getgregs.c create mode 100644 libpthread/linuxthreads_db/td_thr_getxregs.c create mode 100644 libpthread/linuxthreads_db/td_thr_getxregsize.c create mode 100644 libpthread/linuxthreads_db/td_thr_set_event.c create mode 100644 libpthread/linuxthreads_db/td_thr_setfpregs.c create mode 100644 libpthread/linuxthreads_db/td_thr_setgregs.c create mode 100644 libpthread/linuxthreads_db/td_thr_setprio.c create mode 100644 libpthread/linuxthreads_db/td_thr_setsigpending.c create mode 100644 libpthread/linuxthreads_db/td_thr_setxregs.c create mode 100644 libpthread/linuxthreads_db/td_thr_sigsetmask.c create mode 100644 libpthread/linuxthreads_db/td_thr_tsd.c create mode 100644 libpthread/linuxthreads_db/td_thr_validate.c create mode 100644 libpthread/linuxthreads_db/thread_db.h create mode 100644 libpthread/linuxthreads_db/thread_dbP.h (limited to 'libpthread/linuxthreads_db') diff --git a/libpthread/linuxthreads_db/ChangeLog b/libpthread/linuxthreads_db/ChangeLog new file mode 100644 index 000000000..4d29ae0bb --- /dev/null +++ b/libpthread/linuxthreads_db/ChangeLog @@ -0,0 +1,208 @@ +2000-01-19 Ulrich Drepper + + * td_thr_getgregs.c: Correct size parameter of memset call. + +1999-12-02 Ulrich Drepper + + * proc_service.h: Fix typoes in last added declaractions. + +1999-12-01 Ulrich Drepper + + * proc_service.h: Add ps_pstop, ps_pcontinue, ps_lstop, and + ps_lcontinue prototypes. + +1999-11-23 Ulrich Drepper + + * Makefile: Correct dependency for shared object. + +1999-11-22 Ulrich Drepper + + * td_ta_map_lwp2thr.c: Add missing brace in comparison. + + * thread_dbP.h (LOG): Only print message if __td_debug is nonzero. + * td_init.c: Add __td_debug. + +1999-11-12 Ulrich Drepper + + * td_ta_thr_iter.c: Start copying list of descriptors from right + position in target process. + + * td_ta_thr_iter.c: Fix loop starting point over all but main and + manager thread. + + * td_ta_thr_iter.c: Read descriptors for main and manager thread + special since after this we can assume that no new threads will be + created anymore (at least in the gdb implementation). + + * Makefile: Define version correctly. + +1999-11-10 Ulrich Drepper + + * td_ta_map_lwp2thr.c: If p_pid field is zero, this is before the + thread library is initialized and we get the PID from the + debugger. + +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/libpthread/linuxthreads_db/Makefile b/libpthread/linuxthreads_db/Makefile new file mode 100644 index 000000000..eea12c7a4 --- /dev/null +++ b/libpthread/linuxthreads_db/Makefile @@ -0,0 +1,68 @@ +# Makefile for uClibc's pthread library +# +# Copyright (C) 2002 Erik Andersen +# +# This program 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. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more +# details. +# +# You should have received a copy of the GNU Library General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Makefile for uClibc + +TOPDIR=../../ +include $(TOPDIR)Rules.mak + +#Adjust the soname version to avoid namespace collisions with glibc's libpthread +PT_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) +LIBPTHREAD=../libpthread.a + +# set up system dependencies include dirs (NOTE: order matters!) +PTDIR = $(TOPDIR)libpthread/linuxthreads/ +SYSDEPINC = -I$(PTDIR)sysdeps/unix/sysv/linux \ + -I$(PTDIR)sysdeps/pthread \ + -I$(PTDIR)sysdeps/unix/sysv \ + -I$(PTDIR)sysdeps/unix/unix \ + -I$(PTDIR)sysdeps/$(TARGET_ARCH) \ + -I$(PTDIR)sysdeps \ + -I$(TOPDIR)libc/sysdeps/linux/$(TARGET_ARCH) +CFLAGS += $(SYSDEPINC) -DLIBPTHREAD_SO="\"libpthread.so.$(PT_VERSION)\"" -D_GNU_SOURCE + +CSRC=td_init.c td_log.c td_ta_clear_event.c td_ta_delete.c \ + td_ta_enable_stats.c td_ta_event_addr.c td_ta_event_getmsg.c \ + td_ta_get_nthreads.c td_ta_get_ph.c td_ta_get_stats.c \ + td_ta_map_id2thr.c td_ta_map_lwp2thr.c td_ta_new.c td_ta_reset_stats.c \ + td_ta_set_event.c td_ta_setconcurrency.c td_ta_thr_iter.c \ + td_ta_tsd_iter.c td_thr_clear_event.c td_thr_dbresume.c \ + td_thr_dbsuspend.c td_thr_event_enable.c td_thr_event_getmsg.c \ + td_thr_get_info.c td_thr_getfpregs.c td_thr_getgregs.c \ + td_thr_getxregs.c td_thr_getxregsize.c td_thr_set_event.c \ + td_thr_setfpregs.c td_thr_setgregs.c td_thr_setprio.c \ + td_thr_setsigpending.c td_thr_setxregs.c td_thr_sigsetmask.c \ + td_thr_tsd.c td_thr_validate.c +COBJS=$(patsubst %.c,%.o, $(CSRC)) +OBJS=$(COBJS) + +all: $(OBJS) $(LIBPTHREAD) + +$(LIBPTHREAD): ar-target + +ar-target: $(OBJS) + $(AR) $(ARFLAGS) $(LIBPTHREAD) $(OBJS) + +$(COBJS): %.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + $(STRIPTOOL) -x -R .note -R .comment $*.o + +clean: + rm -f *.[oa] *~ core + + + diff --git a/libpthread/linuxthreads_db/Versions b/libpthread/linuxthreads_db/Versions new file mode 100644 index 000000000..83b30ee6e --- /dev/null +++ b/libpthread/linuxthreads_db/Versions @@ -0,0 +1,15 @@ +libthread_db { + GLIBC_2.1.3 { + # t* + td_init; td_log; td_ta_clear_event; td_ta_delete; td_ta_enable_stats; + td_ta_event_addr; td_ta_event_getmsg; td_ta_get_nthreads; td_ta_get_ph; + td_ta_get_stats; td_ta_map_id2thr; td_ta_map_lwp2thr; td_ta_new; + td_ta_reset_stats; td_ta_set_event; td_ta_setconcurrency; + td_ta_thr_iter; td_ta_tsd_iter; td_thr_clear_event; td_thr_dbresume; + td_thr_dbsuspend; td_thr_event_enable; td_thr_event_getmsg; + td_thr_get_info; td_thr_getfpregs; td_thr_getgregs; td_thr_getxregs; + td_thr_getxregsize; td_thr_set_event; td_thr_setfpregs; td_thr_setgregs; + td_thr_setprio; td_thr_setsigpending; td_thr_setxregs; td_thr_sigsetmask; + td_thr_tsd; td_thr_validate; + } +} diff --git a/libpthread/linuxthreads_db/proc_service.h b/libpthread/linuxthreads_db/proc_service.h new file mode 100644 index 000000000..8f9a7d98f --- /dev/null +++ b/libpthread/linuxthreads_db/proc_service.h @@ -0,0 +1,70 @@ +/* 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 *); + + +extern ps_err_e ps_pstop (const struct ps_prochandle *); +extern ps_err_e ps_pcontinue (const struct ps_prochandle *); + +extern ps_err_e ps_lstop (const struct ps_prochandle *, lwpid_t); +extern ps_err_e ps_lcontinue (const struct ps_prochandle *, lwpid_t); diff --git a/libpthread/linuxthreads_db/td_init.c b/libpthread/linuxthreads_db/td_init.c new file mode 100644 index 000000000..683aec427 --- /dev/null +++ b/libpthread/linuxthreads_db/td_init.c @@ -0,0 +1,32 @@ +/* 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" + +int __td_debug; + + +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/libpthread/linuxthreads_db/td_log.c b/libpthread/linuxthreads_db/td_log.c new file mode 100644 index 000000000..0c4a3670f --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_clear_event.c b/libpthread/linuxthreads_db/td_ta_clear_event.c new file mode 100644 index 000000000..02d83360f --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_delete.c b/libpthread/linuxthreads_db/td_ta_delete.c new file mode 100644 index 000000000..e98357766 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_enable_stats.c b/libpthread/linuxthreads_db/td_ta_enable_stats.c new file mode 100644 index 000000000..abf4d200a --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_event_addr.c b/libpthread/linuxthreads_db/td_ta_event_addr.c new file mode 100644 index 000000000..e610e4422 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_event_getmsg.c b/libpthread/linuxthreads_db/td_ta_event_getmsg.c new file mode 100644 index 000000000..4c635dc10 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_get_nthreads.c b/libpthread/linuxthreads_db/td_ta_get_nthreads.c new file mode 100644 index 000000000..7800487a8 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_get_ph.c b/libpthread/linuxthreads_db/td_ta_get_ph.c new file mode 100644 index 000000000..b748916ba --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_get_stats.c b/libpthread/linuxthreads_db/td_ta_get_stats.c new file mode 100644 index 000000000..1741d8145 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_map_id2thr.c b/libpthread/linuxthreads_db/td_ta_map_id2thr.c new file mode 100644 index 000000000..6fb1ba96a --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_map_lwp2thr.c b/libpthread/linuxthreads_db/td_ta_map_lwp2thr.c new file mode 100644 index 000000000..8c934294b --- /dev/null +++ b/libpthread/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 ?: ps_getpid (ta->ph)) == 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/libpthread/linuxthreads_db/td_ta_new.c b/libpthread/linuxthreads_db/td_ta_new.c new file mode 100644 index 000000000..32b9b04c9 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_reset_stats.c b/libpthread/linuxthreads_db/td_ta_reset_stats.c new file mode 100644 index 000000000..11401b950 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_set_event.c b/libpthread/linuxthreads_db/td_ta_set_event.c new file mode 100644 index 000000000..4d87fe1b5 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_setconcurrency.c b/libpthread/linuxthreads_db/td_ta_setconcurrency.c new file mode 100644 index 000000000..5bb2601b4 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_ta_thr_iter.c b/libpthread/linuxthreads_db/td_ta_thr_iter.c new file mode 100644 index 000000000..f1223d113 --- /dev/null +++ b/libpthread/linuxthreads_db/td_ta_thr_iter.c @@ -0,0 +1,143 @@ +/* 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 +#include "thread_dbP.h" + + +static int +handle_descr (const td_thragent_t *ta, td_thr_iter_f *callback, + void *cbdata_p, td_thr_state_e state, int ti_pri, + size_t cnt, pthread_descr descr) +{ + struct _pthread_descr_struct pds; + size_t sizeof_descr = ta->sizeof_descr; + td_thrhandle_t th; + + if (ps_pdread (ta->ph, 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) + return TD_OK; + + /* 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) + return TD_OK; + + /* Test the state. + XXX This is incomplete. */ + if (state != TD_THR_ANY_STATE) + return TD_OK; + + /* 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) + return TD_OK; + + /* Yep, it matches. Call the callback function. */ + th.th_ta_p = (td_thragent_t *) ta; + th.th_unique = descr; + if (callback (&th, cbdata_p) != 0) + return TD_DBERR; + + /* All done successfully. */ + return TD_OK; +} + + +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; + struct pthread_handle_struct *phc; + td_err_e result = TD_OK; + 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; + phc = (struct pthread_handle_struct *) alloca (sizeof (phc[0]) + * pthread_threads_max); + + /* First read only the main thread and manager thread information. */ + if (ps_pdread (ta->ph, ta->handles, phc, + sizeof (struct pthread_handle_struct) * 2) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Now handle these descriptors. */ + result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 0, + phc[0].h_descr); + if (result != TD_OK) + return result; + result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 1, + phc[1].h_descr); + if (result != TD_OK) + return result; + + /* Read all the descriptors. */ + if (ps_pdread (ta->ph, ta->handles + 2, &phc[2], + (sizeof (struct pthread_handle_struct) + * (pthread_threads_max - 2))) != 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 = 2; cnt < pthread_threads_max && num > 0; ++cnt) + if (phc[cnt].h_descr != NULL) + { +#ifdef ALL_THREADS_STOPPED + /* First count this active thread. */ + --num; +#endif + + result = handle_descr (ta, callback, cbdata_p, state, ti_pri, cnt, + phc[cnt].h_descr); + if (result != TD_OK) + break; + } + + return result; +} diff --git a/libpthread/linuxthreads_db/td_ta_tsd_iter.c b/libpthread/linuxthreads_db/td_ta_tsd_iter.c new file mode 100644 index 000000000..b761be1df --- /dev/null +++ b/libpthread/linuxthreads_db/td_ta_tsd_iter.c @@ -0,0 +1,56 @@ +/* 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 +#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/libpthread/linuxthreads_db/td_thr_clear_event.c b/libpthread/linuxthreads_db/td_thr_clear_event.c new file mode 100644 index 000000000..8ef8cbbc4 --- /dev/null +++ b/libpthread/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/libpthread/linuxthreads_db/td_thr_dbresume.c b/libpthread/linuxthreads_db/td_thr_dbresume.c new file mode 100644 ind