diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index 34909fbde..0a0854dd7 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -68,7 +68,13 @@ int __futex_wait_ex(volatile void *ftx, int pshared, int val, const struct time #define __likely(cond) __builtin_expect(!!(cond), 1) #define __unlikely(cond) __builtin_expect(!!(cond), 0) -void _thread_created_hook(pid_t thread_id) __attribute__((noinline)); +#ifdef __i386__ +#define ATTRIBUTES __attribute__((noinline)) __attribute__((fastcall)) +#else +#define ATTRIBUTES __attribute__((noinline)) +#endif + +void ATTRIBUTES _thread_created_hook(pid_t thread_id); #define PTHREAD_ATTR_FLAG_DETACHED 0x00000001 #define PTHREAD_ATTR_FLAG_USER_STACK 0x00000002 diff --git a/libc/bionic/ptrace.c b/libc/bionic/ptrace.c index b1ca00ccd..463c0684a 100644 --- a/libc/bionic/ptrace.c +++ b/libc/bionic/ptrace.c @@ -57,7 +57,12 @@ long ptrace(int request, pid_t pid, void * addr, void * data) /* * Hook for gdb to get notified when a thread is created */ -void _thread_created_hook(pid_t thread_id) __attribute__((noinline)); -void _thread_created_hook(pid_t thread_id) +#ifdef __i386__ +#define ATTRIBUTES __attribute__((noinline)) __attribute__((fastcall)) +#else +#define ATTRIBUTES __attribute__((noinline)) +#endif + +void ATTRIBUTES _thread_created_hook(pid_t thread_id) { } diff --git a/libthread_db/Android.mk b/libthread_db/Android.mk index 922b9cf1b..af506edd9 100644 --- a/libthread_db/Android.mk +++ b/libthread_db/Android.mk @@ -22,12 +22,7 @@ include $(CLEAR_VARS) LOCAL_WHOLE_STATIC_LIBRARIES := libthread_db LOCAL_MODULE:=libthread_db LOCAL_SHARED_LIBRARIES := libdl libc - -# NOTE: Using --no-undefined results in a missing symbol that is defined inside -# gdbserver and is resolved at runtime. Since there is no library containing -# this symbol that we can link against, set LOCAL_ALLOW_UNDEFINED_SYMBOLS so -# that --no-undefined is removed from the linker flags. -LOCAL_ALLOW_UNDEFINED_SYMBOLS := true +LOCAL_ALLOW_UNDEFINED_SYMBOLS := false LOCAL_SYSTEM_SHARED_LIBRARIES := include $(BUILD_SHARED_LIBRARY) diff --git a/libthread_db/include/thread_db.h b/libthread_db/include/thread_db.h index 6ff968f41..1ed8ffca8 100644 --- a/libthread_db/include/thread_db.h +++ b/libthread_db/include/thread_db.h @@ -149,6 +149,10 @@ extern td_err_e td_thr_event_enable(td_thrhandle_t const * handle, extern td_err_e td_ta_thr_iter(td_thragent_t const * agent, td_thr_iter_f * func, void * cookie, td_thr_state_e state, int32_t prio, sigset_t * sigmask, uint32_t user_flags); +extern td_err_e td_thr_event_enable(td_thrhandle_t const * handle, td_event_e event); + +extern td_err_e td_thr_get_info(td_thrhandle_t const * handle, td_thrinfo_t * info); + extern char const ** td_symbol_list(void); extern td_err_e td_thr_tls_get_addr(const td_thrhandle_t * th, diff --git a/libthread_db/libthread_db.c b/libthread_db/libthread_db.c index 2cf4d3856..86e1cf443 100644 --- a/libthread_db/libthread_db.c +++ b/libthread_db/libthread_db.c @@ -81,6 +81,25 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr) { void * pc; +#ifdef __i386__ + /* Get the eip from offset 12*4 = 48 as defined in the struct + * user_regs_struct in user_32.h + */ + pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)48 /* eip */, NULL); + /* FIXME - pc is a non-decremented breakpoint address, hence the + * addition of 1 on test. This seems to work for the thread hook + * function in libc.so but should be properly fixed. + */ + if (pc == ((int)bkpt_addr + 1)) { + /* The hook function takes the id of the new thread as it's first + * param, so grab it from ecx at offset 4 in struct user_regs_struct + * (using fastcall convention for x86) + */ + gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)4 /* ecx */, NULL); + gEventMsgHandle.tid = gEventMsgHandle.pid; + return 0x42; + } +#else pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL); if (pc == bkpt_addr) { @@ -90,6 +109,7 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr) gEventMsgHandle.tid = gEventMsgHandle.pid; return 0x42; } +#endif return 0; } @@ -156,7 +176,7 @@ td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * no { int32_t err; - /* + /* * This is nasty, ps_pglobal_lookup is implemented in gdbserver and looks up * the symbol from it's cache, which is populated at start time with the * symbols returned from td_symbol_list via calls back to the host.