Exemple #1
0
static void
stapkp_unregister_probe(struct stap_dwarf_probe *sdp)
{
   struct stap_dwarf_kprobe *sdk = sdp->kprobe;

   if (!sdp->registered_p)
      return;

   if (sdp->return_p) {
      unregister_kretprobe (&sdk->u.krp);
      dbug_stapkp("-kretprobe %p\n", sdk->u.krp.kp.addr);
   } else {
      unregister_kprobe (&sdk->u.kp);
      dbug_stapkp("-kprobe %p\n", sdk->u.kp.addr);
   }

#if defined(__ia64__)
   unregister_kprobe (&sdk->dummy);
   dbug_stapkp("-kprobe %p\n", sdk->dummy.addr);
#endif

   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(sdk, 0, sizeof(struct stap_dwarf_kprobe));
}
static int
stapkp_arch_register_kprobe(struct stap_kprobe_probe *skp)
{
    int ret = 0;
    struct kprobe *kp = &skp->kprobe->u.kp;

#ifndef __ia64__
    ret = register_kprobe(kp);
    if (ret == 0) {
        if (skp->symbol_name)
            dbug_stapkp("+kprobe %s+%u\n", kp->symbol_name, kp->offset);
        else
            dbug_stapkp("+kprobe %p\n", kp->addr);
    }
#else // PR6028
    ret = register_kprobe(&skp->kprobe->dummy);
    if (ret == 0) {
        ret = register_kprobe(kp);
        if (ret != 0)
            unregister_kprobe(&skp->kprobe->dummy);
    }
    dbug_stapkp_cond(ret == 0, "+kprobe %p\n", skp->kprobe->dummy.addr);
    dbug_stapkp_cond(ret == 0, "+kprobe %p\n", kp->addr);
#endif

    skp->registered_p = (ret ? 0 : 1);

    return ret;
}
static int
stapkp_init(struct stap_kprobe_probe *probes,
            size_t nprobes)
{
    size_t i;

#ifdef STAPCONF_KALLSYMS_ON_EACH_SYMBOL
    // If we have any symbol_name+offset probes, we need to try to
    // convert those into address-based probes.
    size_t probe_max = 0;
    for (i = 0; i < nprobes; i++) {
        struct stap_kprobe_probe *skp = &probes[i];

        if (! skp->symbol_name)
            continue;
        ++probe_max;
    }
    if (probe_max > 0) {
        // Here we're going to try to convert any symbol_name+offset
        // probes into address probes.
        struct stapkp_symbol_data sd;
        dbug_stapkp("looking up %lu probes\n", probe_max);
        sd.probes = probes;
        sd.nprobes = nprobes;
        sd.probe_max = probe_max;
        sd.modname = NULL;
        preempt_disable();
        kallsyms_on_each_symbol(stapkp_symbol_callback, &sd);
        preempt_enable();
        dbug_stapkp("found %lu probes\n", sd.probe_max);
    }
#endif

    for (i = 0; i < nprobes; i++) {
        struct stap_kprobe_probe *skp = &probes[i];
        int rc = 0;

        rc = stapkp_register_probe(skp);
        if (rc == 1) // failed to relocate addr?
            continue; // don't fuss about it, module probably not loaded

        // NB: We keep going even if a probe failed to register (PR6749). We only
        // warn about it if it wasn't optional and isn't in a module.
        if (rc && !skp->optional_p
                && ((skp->module == NULL) || skp->module[0] == '\0'
                    || strcmp(skp->module, "kernel") == 0)) {
            if (skp->symbol_name)
                _stp_warn("probe %s (%s+%u) registration error (rc %d)",
                          skp->probe->pp, skp->symbol_name, skp->offset, rc);
            else
                _stp_warn("probe %s (address 0x%lx) registration error (rc %d)",
                          skp->probe->pp, stapkp_relocate_addr(skp), rc);
        }
    }

    return 0;
}
static void
stapkp_unregister_probe(struct stap_kprobe_probe *skp)
{
    struct stap_kprobe *sk = skp->kprobe;

    if (!skp->registered_p)
        return;

    if (skp->return_p) {
        unregister_kretprobe (&sk->u.krp);
        if (skp->symbol_name)
            dbug_stapkp("-kretprobe %s:%d\n", sk->u.krp.kp.symbol_name,
                        sk->u.krp.kp.offset);
        else
            dbug_stapkp("-kretprobe %p\n", sk->u.krp.kp.addr);
    } else {
        unregister_kprobe (&sk->u.kp);
        if (skp->symbol_name)
            dbug_stapkp("-kprobe %s:%u\n", sk->u.kp.symbol_name,
                        sk->u.kp.offset);
        else
            dbug_stapkp("-kprobe %p\n", sk->u.kp.addr);
    }

#if defined(__ia64__)
    unregister_kprobe (&sk->dummy);
    dbug_stapkp("-kprobe %p\n", sk->dummy.addr);
#endif

    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 (sk->u.krp.kp.symbol_name != NULL)
                kfree(sk->u.krp.kp.symbol_name);
        }
        else {
            if (sk->u.kp.symbol_name != NULL)
                kfree(sk->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(sk, 0, sizeof(struct stap_kprobe));
}