From 91843044de4ea0aee1281fba9b9a8f17387d0190 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Thu, 16 Jul 2015 19:43:19 +0300 Subject: [PATCH] [FIX] simultaneously work nsp and function profiling Currently it is impossible to probe one function more then once. Because of it we cann't use nsp and main() function profiling simultaneously. Add main() function profiling message in nsp handler. Change-Id: Ibb9708c511f4f8497a4eac04b417dd4abd207559 Signed-off-by: Vyacheslav Cherkashin --- nsp/nsp.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- retprobe/rp_msg.c | 2 ++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/nsp/nsp.c b/nsp/nsp.c index 1132a4c..034d259 100644 --- a/nsp/nsp.c +++ b/nsp/nsp.c @@ -55,8 +55,9 @@ static struct probe_new p_dlsym = { }; /* main */ -static int main_h(struct kprobe *p, struct pt_regs *regs); -static struct probe_info_new pin_main = MAKE_UPROBE(main_h); +static int main_eh(struct uretprobe_instance *ri, struct pt_regs *regs); +static int main_rh(struct uretprobe_instance *ri, struct pt_regs *regs); +static struct probe_info_new pin_main = MAKE_URPROBE(main_eh, main_rh, 0); /* appcore_efl_main */ static int ac_efl_main_h(struct kprobe *p, struct pt_regs *regs); @@ -687,6 +688,50 @@ static int main_h(struct kprobe *p, struct pt_regs *regs) return 0; } +/* FIXME: workaround for simultaneously nsp and main() function profiling */ +#include +#include + +static int main_eh(struct uretprobe_instance *ri, struct pt_regs *regs) +{ + struct uretprobe *rp = ri->rp; + + if (rp) { + main_h(&rp->up.kp, regs); + + if (get_quiet() == QT_OFF) { + struct us_ip *ip; + unsigned long func_addr; + + ip = container_of(rp, struct us_ip, retprobe); + func_addr = (unsigned long)ip->orig_addr; + rp_msg_entry(regs, func_addr, "p"); + } + } + + return 0; +} + +static int main_rh(struct uretprobe_instance *ri, struct pt_regs *regs) +{ + struct uretprobe *rp = ri->rp; + + if (rp && get_quiet() == QT_OFF) { + struct us_ip *ip; + char ret_type; + unsigned long func_addr; + unsigned long ret_addr; + + ip = container_of(rp, struct us_ip, retprobe); + func_addr = (unsigned long)ip->orig_addr; + ret_addr = (unsigned long)ri->ret_addr; + ret_type = ip->info->rp_i.ret_type; + rp_msg_exit(regs, func_addr, 'n', ret_addr); + } + + return 0; +} + static int ac_efl_main_h(struct kprobe *p, struct pt_regs *regs) { stage_end(NPS_MAIN_E, NPS_AC_EFL_MAIN_E, NMS_MAIN); diff --git a/retprobe/rp_msg.c b/retprobe/rp_msg.c index 32b9771..9d184b2 100644 --- a/retprobe/rp_msg.c +++ b/retprobe/rp_msg.c @@ -83,6 +83,7 @@ void rp_msg_entry(struct pt_regs *regs, unsigned long func_addr, put_msg: swap_msg_put(m); } +EXPORT_SYMBOL_GPL(rp_msg_entry); void rp_msg_exit(struct pt_regs *regs, unsigned long func_addr, char ret_type, unsigned long ret_addr) @@ -117,3 +118,4 @@ void rp_msg_exit(struct pt_regs *regs, unsigned long func_addr, put_msg: swap_msg_put(m); } +EXPORT_SYMBOL_GPL(rp_msg_exit); -- 2.7.4