From a17b49199f82d5a5abadbbaf84e67f80c81fb228 Mon Sep 17 00:00:00 2001 From: Alexander Aksenov Date: Thu, 6 Aug 2015 16:31:57 +0300 Subject: [PATCH] [FIX] Preload: probes in newly created threads Previously the second exit from pthread_create (exit in new thread) was not handled correctly and this lead to messages missing. Fixed "process data not found" case - now it doesn't lead to drop. Change-Id: I9c6470758b759ae430b23e0aedb93fc525cea395 Signed-off-by: Alexander Aksenov --- preload/preload_control.c | 9 +++++++++ preload/preload_control.h | 1 + preload/preload_module.c | 38 ++++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/preload/preload_control.c b/preload/preload_control.c index 93bdfd3..5a79c84 100644 --- a/preload/preload_control.c +++ b/preload/preload_control.c @@ -210,6 +210,15 @@ static bool __is_instrumented(void *caller) } +/* Called only form handlers. If we're there, then it is instrumented. */ +enum preload_call_type preload_control_call_type_always_inst(void *caller) +{ + if (__is_instrumented(caller)) + return INTERNAL_CALL; + + return EXTERNAL_CALL; + +} enum preload_call_type preload_control_call_type(struct us_ip *ip, void *caller) { diff --git a/preload/preload_control.h b/preload/preload_control.h index 170adb6..27244f7 100644 --- a/preload/preload_control.h +++ b/preload/preload_control.h @@ -10,6 +10,7 @@ enum preload_call_type { int preload_control_init(void); void preload_control_exit(void); +enum preload_call_type preload_control_call_type_always_inst(void *caller); enum preload_call_type preload_control_call_type(struct us_ip *ip, void *caller); int preload_control_add_instrumented_binary(char *filename); int preload_control_clean_instrumented_bins(void); diff --git a/preload/preload_module.c b/preload/preload_module.c index 87575f8..069596f 100644 --- a/preload/preload_module.c +++ b/preload/preload_module.c @@ -425,24 +425,30 @@ static bool __should_we_preload_handlers(struct task_struct *task, static inline void __write_data_to_msg(char *msg, size_t len, unsigned long call_type_off, - unsigned long caller_off) + unsigned long caller_off, + unsigned long caller_addr) { unsigned char call_type = 0; unsigned long caller = 0; int ret; - ret = preload_threads_get_caller(current, &caller); - if (ret != 0) { - caller = 0xbadbeef; - printk(PRELOAD_PREFIX "Error! Cannot get caller address for %d/%d\n", - current->tgid, current->pid); - } + if (caller_addr != 0) { + caller = caller_addr; + call_type = preload_control_call_type_always_inst((void *)caller); + } else { + ret = preload_threads_get_caller(current, &caller); + if (ret != 0) { + caller = 0xbadbeef; + printk(PRELOAD_PREFIX "Error! Cannot get caller address for %d/%d\n", + current->tgid, current->pid); + } - ret = preload_threads_get_call_type(current, &call_type); - if (ret != 0) { - call_type = 0xff; - printk(PRELOAD_PREFIX "Error! Cannot get call type for %d/%d\n", - current->tgid, current->pid); + ret = preload_threads_get_call_type(current, &call_type); + if (ret != 0) { + call_type = 0xff; + printk(PRELOAD_PREFIX "Error! Cannot get call type for %d/%d\n", + current->tgid, current->pid); + } } /* Using the same types as in the library. */ @@ -775,7 +781,7 @@ static int write_msg_handler(struct kprobe *p, struct pt_regs *regs) } ret = preload_threads_get_drop(current, &drop); - if (ret != 0 || drop) + if (ret == 0 && drop) return 0; buf = kmalloc(len, GFP_KERNEL); @@ -796,11 +802,7 @@ static int write_msg_handler(struct kprobe *p, struct pt_regs *regs) call_type_offset = (unsigned long)(call_type_p - user_buf); caller_offset = (unsigned long)(caller_p - user_buf); - __write_data_to_msg(buf, len, call_type_offset, caller_offset); - - /* FIXME refactor this hack for opengl tizen probes */ - if (caller_addr) - *(uintptr_t *)(buf + caller_offset) = (uintptr_t)caller_addr; + __write_data_to_msg(buf, len, call_type_offset, caller_offset, caller_addr); ret = swap_msg_raw(buf, len); if (ret != len) -- 2.7.4