Fix "addresses instead of names" problem for Library Only Instrumentation
authorEkaterina Gorelkina <ekaterina@ekaterina-desktop.(none)>
Thu, 30 Sep 2010 11:51:16 +0000 (15:51 +0400)
committerEkaterina Gorelkina <ekaterina@ekaterina-desktop.(none)>
Thu, 30 Sep 2010 11:51:16 +0000 (15:51 +0400)
driver/debug.h
driver/us_proc_inst.c
kprobe/arch/asm-arm/dbi_kprobes.c
kprobe/dbi_kprobes_deps.c
kprobe/dbi_uprobes.c

index 75b8bb9..e1590f0 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/kernel.h>
 #include <linux/string.h>      // strrchr
 
+#undef __DEBUG
+
 #ifdef __DEBUG
 #define DPRINTF(format, args...) do { \
        char *f = __FILE__; \
index 4b5867b..01c6953 100644 (file)
@@ -314,7 +314,7 @@ static void us_vtp_event_handler (unsigned long arg1, unsigned long arg2, unsign
 static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_inst_info, int atomic)
 {
        struct vm_area_struct *vma;
-       int i, k;
+       int i, k, err;
        unsigned long addr;
        unsigned int old_ips_count, old_vtps_count;
        struct mm_struct *mm;
@@ -337,6 +337,34 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
                        vma = vma->vm_next;
                        continue;
                }
+
+               /**
+                * After process was forked, some time it inherits parent process environment.
+                * We need to renew instrumentation when we detect that process gets own environment.
+                */
+               if (vma->vm_flags & VM_EXECUTABLE) {
+                   if (!task_inst_info->m_f_dentry) {
+                       task_inst_info->m_f_dentry = vma->vm_file->f_dentry;
+                       printk("initiate dentry tgid = %d\n", task->tgid, task->comm);
+                   } else if (task_inst_info->m_f_dentry != vma->vm_file->f_dentry) {
+                       printk("we have detected that detry was changed tgid = %d\n", task->tgid, task->comm);
+                       for (i = 0; i < task_inst_info->libs_count; i++) {
+                           task_inst_info->p_libs[i].loaded = 0;
+                           for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++) {
+                               task_inst_info->p_libs[i].p_ips[k].installed = 0;
+                               task_inst_info->unres_ips_count++;
+                           }
+
+                           for (k = 0; k < task_inst_info->p_libs[i].vtps_count; k++) {
+                               task_inst_info->p_libs[i].p_vtps[k].installed = 0;
+                               task_inst_info->unres_vtps_count++;
+                           }
+
+                           task_inst_info->m_f_dentry = vma->vm_file->f_dentry;
+                       }
+                   }
+               }
+               
                for (i = 0; i < task_inst_info->libs_count; i++) {      
                        //TODO: test - try to instrument non-existing libs
                        if (vma->vm_file->f_dentry == task_inst_info->p_libs[i].m_f_dentry) {
@@ -354,7 +382,6 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
                                                        task->tgid, p, vma->vm_start, vma->vm_end-vma->vm_start);
                                }
 
-                               //DPRINTF ("    if (vma->vm_file->f_dentry == task_inst_info->p_libs[i].m_f_dentry)\n");
                                for (k = 0; k < task_inst_info->p_libs[i].ips_count; k++) {
                                        if (!task_inst_info->p_libs[i].p_ips[k].installed)
                                        {
@@ -365,12 +392,12 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
                                                        DPRINTF ("pid %d, %s sym is loaded at %lx/%lx.", task->pid, task_inst_info->p_libs[i].path, task_inst_info->p_libs[i].p_ips[k].offset, addr);
                                                        task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr = (kprobe_opcode_t *) addr;
                                                        task_inst_info->p_libs[i].p_ips[k].retprobe.kp.addr = (kprobe_opcode_t *) addr;
-                                                               if (!register_usprobe (task, mm, &task_inst_info->p_libs[i].p_ips[k], atomic, 0)) {
-                                                               task_inst_info->p_libs[i].p_ips[k].installed = 1;
-                                                               task_inst_info->unres_ips_count--;
-
-                                                       } else {
-                                                               EPRINTF ("failed to install IP at %lx/%p. Error %d!", task_inst_info->p_libs[i].p_ips[k].offset, 
+                                                       task_inst_info->p_libs[i].p_ips[k].installed = 1;
+                                                       task_inst_info->unres_ips_count--;
+                                                       
+                                                       err = register_usprobe (task, mm, &task_inst_info->p_libs[i].p_ips[k], atomic, 0);
+                                                       if (!err) {
+                                                               DPRINTF ("failed to install IP at %lx/%p. Error %d!", task_inst_info->p_libs[i].p_ips[k].offset, 
                                                                                task_inst_info->p_libs[i].p_ips[k].jprobe.kp.addr);
                                                        }
                                                }
@@ -388,11 +415,11 @@ static int install_mapped_ips (struct task_struct *task, inst_us_proc_t* task_in
                                                        task_inst_info->p_libs[i].p_vtps[k].jprobe.entry = (kprobe_opcode_t *) us_vtp_event_handler;
                                                        task_inst_info->p_libs[i].p_vtps[k].jprobe.pre_entry = (kprobe_pre_entry_handler_t) us_vtp_event_pre_handler;
                                                        task_inst_info->p_libs[i].p_vtps[k].jprobe.priv_arg = &task_inst_info->p_libs[i].p_vtps[k];
-                                                               if (!register_ujprobe (task, mm, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic)) {
-                                                               task_inst_info->p_libs[i].p_vtps[k].installed = 1;
-                                                               task_inst_info->unres_vtps_count--;
-
-                                                       } else {
+                                                       task_inst_info->p_libs[i].p_vtps[k].installed = 1;
+                                                       task_inst_info->unres_vtps_count--;
+                                                       
+                                                       err = register_ujprobe (task, mm, &task_inst_info->p_libs[i].p_vtps[k].jprobe, atomic);
+                                                       if (!err) {
                                                                EPRINTF ("failed to install VTP at %p. Error %d!", 
                                                                                task_inst_info->p_libs[i].p_vtps[k].jprobe.kp.addr);
                                                        }
@@ -874,7 +901,7 @@ static int register_usprobe (struct task_struct *task, struct mm_struct *mm, us_
        ret = register_ujprobe (task, mm, &ip->jprobe, atomic);
        if (ret)
        {
-               EPRINTF ("register_ujprobe() failure %d", ret);
+               DPRINTF ("register_ujprobe() failure %d", ret);
                return ret;
        }
        ip->retprobe.kp.tgid = task->tgid;
index e2e754b..d7befeb 100644 (file)
@@ -199,9 +199,10 @@ int prep_pc_dep_insn_execbuf (kprobe_opcode_t * insns, kprobe_opcode_t insn, int
 int arch_check_insn (struct arch_specific_insn *ainsn)
 {
        int ret = 0;
+
        // check instructions that can change PC by nature 
        if (ARM_INSN_MATCH (UNDEF, ainsn->insn[0]) ||
-                       ARM_INSN_MATCH (AUNDEF, ainsn->insn[0]) ||
+             ARM_INSN_MATCH (AUNDEF, ainsn->insn[0]) ||
                        ARM_INSN_MATCH (SWI, ainsn->insn[0]) ||
                        ARM_INSN_MATCH (BREAK, ainsn->insn[0]) ||
                        ARM_INSN_MATCH (B, ainsn->insn[0]) ||
@@ -211,7 +212,7 @@ int arch_check_insn (struct arch_specific_insn *ainsn)
                        ARM_INSN_MATCH (BX, ainsn->insn[0]) || 
                        ARM_INSN_MATCH (BXJ, ainsn->insn[0]))
        {
-               DBPRINTF ("arch_check_insn: %lx\n", ainsn->insn[0]);
+               DBPRINTF ("Bad insn arch_check_insn: %lx\n", ainsn->insn[0]);
                ret = -EFAULT;
        }
 #ifndef CONFIG_CPU_V7
@@ -223,7 +224,7 @@ int arch_check_insn (struct arch_specific_insn *ainsn)
                                ARM_INSN_MATCH (LRO, ainsn->insn[0])) && 
                        (ARM_INSN_REG_RD (ainsn->insn[0]) == 15))
        {
-               DBPRINTF ("arch_check_insn: %lx\n", ainsn->insn[0]);
+               DBPRINTF ("Bad arch_check_insn: %lx\n", ainsn->insn[0]);
                ret = -EFAULT;
        }
 #endif // CONFIG_CPU_V7
@@ -234,7 +235,7 @@ int arch_check_insn (struct arch_specific_insn *ainsn)
                         // store/load with pc update
                         ((ARM_INSN_REG_RN (ainsn->insn[0]) == 15) && (ainsn->insn[0] & 0x200000))))
        {
-               DBPRINTF ("arch_check_insn: %lx\n", ainsn->insn[0]);
+               DBPRINTF ("Bad insn arch_check_insn: %lx\n", ainsn->insn[0]);
                ret = -EFAULT;
        }
        return ret;
index a124bcd..d3c1f96 100644 (file)
@@ -421,7 +421,7 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
        if (!mm)
                return 0;
 
-       down_read(&mm->mmap_sem);
+       //down_read(&mm->mmap_sem);
        /* ignore errors, just check how much was successfully transferred */
        while (len) {
                int bytes, ret, offset;
@@ -468,7 +468,7 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
                buf += bytes;
                addr += bytes;
        }
-       up_read(&mm->mmap_sem);
+       //up_read(&mm->mmap_sem);
        mmput(mm);
 
        return buf - old_buf;
index 7c1bd8e..9931740 100644 (file)
@@ -70,10 +70,12 @@ int __register_uprobe (struct kprobe *p, struct task_struct *task, int atomic, u
                ret = register_aggr_kprobe (old_p, p);
                if (!ret)
                        atomic_inc (&kprobe_count);
+               DBPRINTF ("goto out\n", ret);
                goto out;
        }
        if ((ret = arch_prepare_uprobe (p, task, atomic)) != 0)
        {
+               DBPRINTF ("goto out\n", ret);
                goto out;
        }