Add debugger event reporting support, current only TD_CREATE and TD_DEATH

events are reported.
This commit is contained in:
davidxu 2005-04-12 03:00:28 +00:00
parent c874648f8b
commit 2cf5eeb001
9 changed files with 65 additions and 17 deletions

View File

@ -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

View File

@ -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_linkmap;
_thread_off_next;
_thread_off_tcb;
_thread_off_tid;
_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_thr_locklevel;
_thread_off_tcb;
_thread_off_tid;
_thread_off_tlsindex;
_thread_off_isdead;
_thread_size_key;
_thread_state_running;
_thread_state_zoombie;

View File

@ -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 \

View File

@ -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));

View File

@ -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! */
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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_

View File

@ -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);