static int test_kretprobes(void)
{
	int ret;
	struct kretprobe *rps[2] = {&rp, &rp2};

	/*                                                     */
	rp.kp.addr = NULL;
	rp.kp.flags = 0;
	ret = register_kretprobes(rps, 2);
	if (ret < 0) {
		printk(KERN_ERR "Kprobe smoke test failed: "
				"register_kretprobe returned %d\n", ret);
		return ret;
	}

	krph_val = 0;
	ret = target(rand1);
	if (krph_val != rand1) {
		printk(KERN_ERR "Kprobe smoke test failed: "
				"kretprobe handler not called\n");
		handler_errors++;
	}

	krph_val = 0;
	ret = target2(rand1);
	if (krph_val != rand1) {
		printk(KERN_ERR "Kprobe smoke test failed: "
				"kretprobe handler2 not called\n");
		handler_errors++;
	}
	unregister_kretprobes(rps, 2);
	return 0;
}
static void
stapkp_batch_unregister_probes(struct stap_kprobe_probe *probes,
                               size_t nprobes)
{
    size_t i, n;

    n = stapkp_collect_registered_probes(probes,
                                         nprobes, COLLECT_KPROBES);
    unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n);
    dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n);

    n = stapkp_collect_registered_probes(probes,
                                         nprobes, COLLECT_KRETPROBES);
    unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, n);
    dbug_stapkp_cond(n > 0, "-kretprobe * %zd\n", n);

#ifdef __ia64__
    n = stapkp_collect_registered_probes(probes,
                                         nprobes, COLLECT_DUMMYS);
    unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n);
    dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n);
#endif

    // Now for all of those we just unregistered, we need to update registered_p
    // and account for (and possibly report) missed hits.
    for (i = 0; i < nprobes; i++) {

        struct stap_kprobe_probe *skp = &probes[i];

        if (!skp->registered_p)
            continue;

        skp->registered_p = 0;

        stapkp_add_missed(skp);

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
        if (skp->symbol_name != NULL) {
            if (skp->return_p) {
                if (skp->kprobe->u.krp.kp.symbol_name != NULL)
                    kfree(skp->kprobe->u.krp.kp.symbol_name);
            }
            else {
                if (skp->kprobe->u.kp.symbol_name != NULL)
                    kfree(skp->kprobe->u.kp.symbol_name);
            }
        }
#endif

        // PR16861: kprobes may have left some things in the k[ret]probe struct.
        // Let's reset it to be sure it's safe for re-use.
        memset(skp->kprobe, 0, sizeof(struct stap_kprobe));
    }
}
Exemple #3
0
static void
stapkp_batch_unregister_probes(struct stap_dwarf_probe *probes,
                               size_t nprobes)
{
   size_t i, n;

   n = stapkp_collect_registered_probes(probes,
                                        nprobes, COLLECT_KPROBES);
   unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n);
   dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n);

   n = stapkp_collect_registered_probes(probes,
                                        nprobes, COLLECT_KRETPROBES);
   unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, n);
   dbug_stapkp_cond(n > 0, "-kretprobe * %zd\n", n);

#ifdef __ia64__
   n = stapkp_collect_registered_probes(probes,
                                        nprobes, COLLECT_DUMMYS);
   unregister_kprobes((struct kprobe **)stap_unreg_kprobes, n);
   dbug_stapkp_cond(n > 0, "-kprobe * %zd\n", n);
#endif

   // Now for all of those we just unregistered, we need to update registered_p
   // and account for (and possibly report) missed hits.
   for (i = 0; i < nprobes; i++) {

      struct stap_dwarf_probe *sdp = &probes[i];

      if (!sdp->registered_p)
         continue;

      sdp->registered_p = 0;

      stapkp_add_missed(sdp);

      // PR16861: kprobes may have left some things in the k[ret]probe struct.
      // Let's reset it to be sure it's safe for re-use.
      memset(sdp->kprobe, 0, sizeof(struct stap_dwarf_kprobe));
   }
}