Add debugger event reporting support, current only TD_CREATE and TD_DEATH
events are reported.
This commit is contained in:
parent
c874648f8b
commit
2cf5eeb001
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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! */
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user