summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2005-04-12 03:00:28 +0000
committerdavidxu <davidxu@FreeBSD.org>2005-04-12 03:00:28 +0000
commit2cf5eeb00151f72e5aa07f0289c2889752eb07d9 (patch)
treeb5ca39973148c65442650488e554719cd7db2deb /lib
parentc874648f8b61fce9d0fd977d6502638d882c2f33 (diff)
downloadFreeBSD-src-2cf5eeb00151f72e5aa07f0289c2889752eb07d9.zip
FreeBSD-src-2cf5eeb00151f72e5aa07f0289c2889752eb07d9.tar.gz
Add debugger event reporting support, current only TD_CREATE and TD_DEATH
events are reported.
Diffstat (limited to 'lib')
-rw-r--r--lib/libthr/Makefile1
-rw-r--r--lib/libthr/pthread.map15
-rw-r--r--lib/libthr/thread/Makefile.inc1
-rw-r--r--lib/libthr/thread/thr_create.c21
-rw-r--r--lib/libthr/thread/thr_exit.c4
-rw-r--r--lib/libthr/thread/thr_init.c2
-rw-r--r--lib/libthr/thread/thr_list.c2
-rw-r--r--lib/libthr/thread/thr_private.h29
-rw-r--r--lib/libthr/thread/thr_symbols.c5
9 files changed, 64 insertions, 16 deletions
diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile
index 24ebe7c..0df6873 100644
--- a/lib/libthr/Makefile
+++ b/lib/libthr/Makefile
@@ -16,6 +16,7 @@ CFLAGS+=-I${.CURDIR}/arch/${MACHINE_ARCH}/include
CFLAGS+=-I${.CURDIR}/sys
CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf
CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf/${MACHINE_ARCH}
+CFLAGS+=-I${.CURDIR}/../libthread_db
CFLAGS+=-Winline
# CFLAGS+=-DSYSTEM_SCOPE_ONLY
diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map
index 12f0183..be30e96 100644
--- a/lib/libthr/pthread.map
+++ b/lib/libthr/pthread.map
@@ -344,21 +344,26 @@ global:
# Debugger needs these.
_libthr_debug;
_thread_active_threads;
+ _thread_bp_create;
+ _thread_bp_death;
+ _thread_event_mask;
_thread_keytable;
+ _thread_last_event;
_thread_list;
_thread_max_keys;
_thread_off_attr_flags;
_thread_off_dtv;
+ _thread_off_event_buf;
+ _thread_off_event_mask;
+ _thread_off_key_allocated;
+ _thread_off_key_destructor;
_thread_off_linkmap;
_thread_off_next;
+ _thread_off_report_events;
+ _thread_off_state;
_thread_off_tcb;
_thread_off_tid;
- _thread_off_key_allocated;
- _thread_off_key_destructor;
- _thread_off_state;
- _thread_off_thr_locklevel;
_thread_off_tlsindex;
- _thread_off_isdead;
_thread_size_key;
_thread_state_running;
_thread_state_zoombie;
diff --git a/lib/libthr/thread/Makefile.inc b/lib/libthr/thread/Makefile.inc
index d756a32..595d994 100644
--- a/lib/libthr/thread/Makefile.inc
+++ b/lib/libthr/thread/Makefile.inc
@@ -15,6 +15,7 @@ SRCS+= \
thr_create.c \
thr_detach.c \
thr_equal.c \
+ thr_event.c \
thr_exit.c \
thr_fork.c \
thr_getprio.c \
diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c
index d5e9a62..af0697c 100644
--- a/lib/libthr/thread/thr_create.c
+++ b/lib/libthr/thread/thr_create.c
@@ -56,7 +56,7 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
ucontext_t uc;
sigset_t sigmask, oldsigmask;
struct pthread *curthread, *new_thread;
- int ret = 0;
+ int ret = 0, locked;
_thr_check_init();
@@ -92,9 +92,10 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
else if (_thr_scope_system < 0)
new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM;
+ new_thread->tid = TID_TERMINATED;
+
if (create_stack(&new_thread->attr) != 0) {
/* Insufficient memory to create a stack: */
- new_thread->terminated = 1;
_thr_free(curthread, new_thread);
return (EAGAIN);
}
@@ -151,20 +152,31 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* it can not handle signal, so we should masks all signals here.
*/
SIGFILLSET(sigmask);
+ SIGDELSET(sigmask, SIGTRAP);
__sys_sigprocmask(SIG_SETMASK, &sigmask, &oldsigmask);
new_thread->sigmask = oldsigmask;
/* Add the new thread. */
_thr_link(curthread, new_thread);
/* Return thread pointer eariler so that new thread can use it. */
(*thread) = new_thread;
+ if (SHOULD_REPORT_EVENT(curthread, TD_CREATE)) {
+ THR_THREAD_LOCK(curthread, new_thread);
+ locked = 1;
+ } else
+ locked = 0;
/* Schedule the new thread. */
ret = thr_create(&uc, &new_thread->tid, 0);
__sys_sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
if (ret != 0) {
+ if (locked)
+ THR_THREAD_UNLOCK(curthread, new_thread);
_thr_unlink(curthread, new_thread);
free_thread(curthread, new_thread);
(*thread) = 0;
ret = EAGAIN;
+ } else if (locked) {
+ _thr_report_creation(curthread, new_thread);
+ THR_THREAD_UNLOCK(curthread, new_thread);
}
return (ret);
}
@@ -173,7 +185,7 @@ static void
free_thread(struct pthread *curthread, struct pthread *thread)
{
free_stack(curthread, &thread->attr);
- curthread->terminated = 1;
+ curthread->tid = TID_TERMINATED;
_thr_free(curthread, thread);
}
@@ -215,6 +227,9 @@ thread_start(struct pthread *curthread)
if (curthread->flags & THR_FLAGS_NEED_SUSPEND)
_thr_suspend_check(curthread);
+ THR_LOCK(curthread);
+ THR_UNLOCK(curthread);
+
/* Run the current thread's start routine with argument: */
pthread_exit(curthread->start_routine(curthread->arg));
diff --git a/lib/libthr/thread/thr_exit.c b/lib/libthr/thread/thr_exit.c
index 554646b..4f4eff6 100644
--- a/lib/libthr/thread/thr_exit.c
+++ b/lib/libthr/thread/thr_exit.c
@@ -130,7 +130,9 @@ _pthread_exit(void *status)
THREAD_LIST_UNLOCK(curthread);
if (curthread->joiner)
_thr_umtx_wake(&curthread->state, INT_MAX);
- thr_exit(&curthread->terminated);
+ if (SHOULD_REPORT_EVENT(curthread, TD_DEATH))
+ _thr_report_death(curthread);
+ thr_exit(&curthread->tid);
PANIC("thr_exit() returned");
/* Never reach! */
}
diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c
index a0f4e5c..7636fec 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -309,6 +309,7 @@ _libpthread_init(struct pthread *curthread)
_thr_initial = curthread;
SIGDELSET(oldset, SIGCANCEL);
__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
+ _thr_report_creation(curthread, curthread);
}
}
@@ -384,6 +385,7 @@ init_private(void)
_thr_umtx_init(&_rwlock_static_lock);
_thr_umtx_init(&_keytable_lock);
_thr_umtx_init(&_thr_atfork_lock);
+ _thr_umtx_init(&_thr_event_lock);
_thr_spinlock_init();
_thr_list_init();
diff --git a/lib/libthr/thread/thr_list.c b/lib/libthr/thread/thr_list.c
index 06d14e8..a0d5aaa 100644
--- a/lib/libthr/thread/thr_list.c
+++ b/lib/libthr/thread/thr_list.c
@@ -99,7 +99,7 @@ _thr_gc(struct pthread *curthread)
/* Check the threads waiting for GC. */
for (td = TAILQ_FIRST(&_thread_gc_list); td != NULL; td = td_next) {
td_next = TAILQ_NEXT(td, gcle);
- if (td->terminated == 0) {
+ if (td->tid != TID_TERMINATED) {
/* make sure we are not still in userland */
continue;
}
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index 405340f..3c4f9ed 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -56,6 +56,7 @@
#include "pthread_md.h"
#include "thr_umtx.h"
+#include "thread_db.h"
/*
* Evaluate the storage class specifier.
@@ -345,11 +346,9 @@ struct pthread {
*/
umtx_t lock;
- /* Thread is terminated in kernel, written by kernel. */
- long terminated;
-
/* Kernel thread id. */
long tid;
+#define TID_TERMINATED 1
/* Internal condition variable cycle number. */
umtx_t cycle;
@@ -491,6 +490,15 @@ struct pthread {
/* Cleanup handlers Link List */
struct pthread_cleanup *cleanup;
+
+ /* Enable event reporting */
+ int report_events;
+
+ /* Event mask */
+ int event_mask;
+
+ /* Event */
+ td_event_msg_t event_buf;
};
#define THR_UMTX_TRYLOCK(thrd, lck) \
@@ -573,6 +581,10 @@ do { \
#define THR_IN_SYNCQ(thrd) (((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0)
+#define SHOULD_REPORT_EVENT(curthr, e) \
+ (curthr->report_events && \
+ (((curthr)->event_mask | _thread_event_mask ) & e) != 0)
+
extern int __isthreaded;
/*
@@ -581,9 +593,12 @@ extern int __isthreaded;
SCLASS void *_usrstack SCLASS_PRESET(NULL);
SCLASS struct pthread *_thr_initial SCLASS_PRESET(NULL);
+SCLASS int _thr_scope_system SCLASS_PRESET(0);
+
/* For debugger */
SCLASS int _libthr_debug SCLASS_PRESET(0);
-SCLASS int _thr_scope_system SCLASS_PRESET(0);
+SCLASS int _thread_event_mask SCLASS_PRESET(0);
+SCLASS struct pthread *_thread_last_event;
/* List of all threads: */
SCLASS TAILQ_HEAD(, pthread) _thread_list
@@ -643,6 +658,7 @@ SCLASS umtx_t _cond_static_lock;
SCLASS umtx_t _rwlock_static_lock;
SCLASS umtx_t _keytable_lock;
SCLASS umtx_t _thr_list_lock;
+SCLASS umtx_t _thr_event_lock;
/* Undefine the storage class and preset specifiers: */
#undef SCLASS
@@ -720,6 +736,11 @@ void _thr_link(struct pthread *curthread, struct pthread *thread);
void _thr_unlink(struct pthread *curthread, struct pthread *thread);
void _thr_suspend_check(struct pthread *curthread);
void _thr_assert_lock_level() __dead2;
+void _thr_report_creation(struct pthread *curthread,
+ struct pthread *newthread);
+void _thr_report_death(struct pthread *curthread);
+void _thread_bp_create(void);
+void _thread_bp_death(void);
/* #include <sys/aio.h> */
#ifdef _SYS_AIO_H_
diff --git a/lib/libthr/thread/thr_symbols.c b/lib/libthr/thread/thr_symbols.c
index 313cad7..c35f2c7 100644
--- a/lib/libthr/thread/thr_symbols.c
+++ b/lib/libthr/thread/thr_symbols.c
@@ -45,10 +45,11 @@ int _thread_off_tcb = offsetof(struct pthread, tcb);
int _thread_off_tid = offsetof(struct pthread, tid);
int _thread_off_next = offsetof(struct pthread, tle.tqe_next);
int _thread_off_attr_flags = offsetof(struct pthread, attr.flags);
-int _thread_off_thr_locklevel = offsetof(struct pthread, locklevel);
int _thread_off_linkmap = offsetof(Obj_Entry, linkmap);
int _thread_off_tlsindex = offsetof(Obj_Entry, tlsindex);
-int _thread_off_isdead = offsetof(struct pthread, terminated);
+int _thread_off_report_events = offsetof(struct pthread, report_events);
+int _thread_off_event_mask = offsetof(struct pthread, event_mask);
+int _thread_off_event_buf = offsetof(struct pthread, event_buf);
int _thread_size_key = sizeof(struct pthread_key);
int _thread_off_key_allocated = offsetof(struct pthread_key, allocated);
int _thread_off_key_destructor = offsetof(struct pthread_key, destructor);
OpenPOWER on IntegriCloud