}
+#if defined(STAPCONF_UNREGISTER_KPROBES)
+
+// The actual size is set later on in
+// dwarf_derived_probe_group::emit_module_decls().
+static void * stap_unreg_kprobes[];
+
+#endif
+
+
static int
stapkp_init(struct stap_dwarf_probe *probes,
struct stap_dwarf_kprobe *kprobes,
} // for loop
}
+
+static void
+stapkp_exit(struct stap_dwarf_probe *probes,
+ struct stap_dwarf_kprobe *kprobes,
+ size_t nprobes)
+{
+ size_t i, j;
+
+#if defined(STAPCONF_UNREGISTER_KPROBES)
+
+ //Unregister kprobes by batch interfaces.
+ j = 0;
+ for (i = 0; i < nprobes; i++) {
+
+ struct stap_dwarf_probe *sdp = &probes[i];
+ struct stap_dwarf_kprobe *kp = &kprobes[i];
+
+ if (! sdp->registered_p)
+ continue;
+ if (!sdp->return_p)
+ stap_unreg_kprobes[j++] = &kp->u.kp;
+ }
+
+ unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);
+
+ j = 0;
+ for (i = 0; i < nprobes; i++) {
+
+ struct stap_dwarf_probe *sdp = &probes[i];
+ struct stap_dwarf_kprobe *kp = &kprobes[i];
+
+ if (! sdp->registered_p)
+ continue;
+ if (sdp->return_p)
+ stap_unreg_kprobes[j++] = &kp->u.krp;
+ }
+
+ unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, j);
+
+#ifdef __ia64__
+ j = 0;
+ for (i = 0; i < nprobes; i++) {
+
+ struct stap_dwarf_probe *sdp = &probes[i];
+ struct stap_dwarf_kprobe *kp = &kprobes[i];
+
+ if (! sdp->registered_p)
+ continue;
+ stap_unreg_kprobes[j++] = &kp->dummy;
+ }
+
+ unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);
+#endif
+
+#endif /* STAPCONF_UNREGISTER_KPROBES */
+
+ for (i = 0; i < nprobes; i++) {
+
+ struct stap_dwarf_probe *sdp = &probes[i];
+ struct stap_dwarf_kprobe *kp = &kprobes[i];
+
+ if (!sdp->registered_p)
+ continue;
+
+ if (sdp->return_p) {
+
+#if !defined(STAPCONF_UNREGISTER_KPROBES)
+ unregister_kretprobe (&kp->u.krp);
+#endif
+
+ atomic_add (kp->u.krp.nmissed, skipped_count());
+
+#ifdef STP_TIMING
+ if (kp->u.krp.nmissed)
+ _stp_warn ("Skipped due to missed kretprobe/1 on '%s': %d\n",
+ sdp->probe->pp, kp->u.krp.nmissed);
+#endif
+
+ atomic_add (kp->u.krp.kp.nmissed, skipped_count());
+
+#ifdef STP_TIMING
+ if (kp->u.krp.kp.nmissed)
+ _stp_warn ("Skipped due to missed kretprobe/2 on '%s': %lu\n",
+ sdp->probe->pp, kp->u.krp.kp.nmissed);
+#endif
+
+ } else {
+
+#if !defined(STAPCONF_UNREGISTER_KPROBES)
+ unregister_kprobe (&kp->u.kp);
+#endif
+
+ atomic_add (kp->u.kp.nmissed, skipped_count());
+
+#ifdef STP_TIMING
+ if (kp->u.kp.nmissed)
+ _stp_warn ("Skipped due to missed kprobe on '%s': %lu\n",
+ sdp->probe->pp, kp->u.kp.nmissed);
+#endif
+
+ }
+
+#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)
+ unregister_kprobe (&kp->dummy);
+#endif
+ sdp->registered_p = 0;
+ }
+}
+
+
#endif /* _KPROBES_C_ */
void
dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
{
- //Unregister kprobes by batch interfaces.
- s.op->newline() << "#if defined(STAPCONF_UNREGISTER_KPROBES)";
- s.op->newline() << "j = 0;";
- s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
- s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
- s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
- s.op->newline() << "if (! sdp->registered_p) continue;";
- s.op->newline() << "if (!sdp->return_p)";
- s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.kp;";
- s.op->newline(-2) << "}";
- s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);";
- s.op->newline() << "j = 0;";
- s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
- s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
- s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
- s.op->newline() << "if (! sdp->registered_p) continue;";
- s.op->newline() << "if (sdp->return_p)";
- s.op->newline(1) << "stap_unreg_kprobes[j++] = &kp->u.krp;";
- s.op->newline(-2) << "}";
- s.op->newline() << "unregister_kretprobes((struct kretprobe **)stap_unreg_kprobes, j);";
- s.op->newline() << "#ifdef __ia64__";
- s.op->newline() << "j = 0;";
- s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
- s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
- s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
- s.op->newline() << "if (! sdp->registered_p) continue;";
- s.op->newline() << "stap_unreg_kprobes[j++] = &kp->dummy;";
- s.op->newline(-1) << "}";
- s.op->newline() << "unregister_kprobes((struct kprobe **)stap_unreg_kprobes, j);";
- s.op->newline() << "#endif";
- s.op->newline() << "#endif";
+ if (probes_by_module.empty()) return;
- s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
- s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
- s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
- s.op->newline() << "if (! sdp->registered_p) continue;";
- s.op->newline() << "if (sdp->return_p) {";
- s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
- s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
- s.op->newline() << "#endif";
- s.op->newline() << "atomic_add (kp->u.krp.nmissed, skipped_count());";
- s.op->newline() << "#ifdef STP_TIMING";
- s.op->newline() << "if (kp->u.krp.nmissed)";
- s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/1 on '%s': %d\\n\", sdp->probe->pp, kp->u.krp.nmissed);";
- s.op->newline(-1) << "#endif";
- s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, skipped_count());";
- s.op->newline() << "#ifdef STP_TIMING";
- s.op->newline() << "if (kp->u.krp.kp.nmissed)";
- s.op->newline(1) << "_stp_warn (\"Skipped due to missed kretprobe/2 on '%s': %lu\\n\", sdp->probe->pp, kp->u.krp.kp.nmissed);";
- s.op->newline(-1) << "#endif";
- s.op->newline(-1) << "} else {";
- s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES)";
- s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
- s.op->newline() << "#endif";
- s.op->newline() << "atomic_add (kp->u.kp.nmissed, skipped_count());";
- s.op->newline() << "#ifdef STP_TIMING";
- s.op->newline() << "if (kp->u.kp.nmissed)";
- s.op->newline(1) << "_stp_warn (\"Skipped due to missed kprobe on '%s': %lu\\n\", sdp->probe->pp, kp->u.kp.nmissed);";
- s.op->newline(-1) << "#endif";
- s.op->newline(-1) << "}";
- s.op->newline() << "#if !defined(STAPCONF_UNREGISTER_KPROBES) && defined(__ia64__)";
- s.op->newline() << "unregister_kprobe (&kp->dummy);";
- s.op->newline() << "#endif";
- s.op->newline() << "sdp->registered_p = 0;";
- s.op->newline(-1) << "}";
+ s.op->newline() << "/* ---- dwarf probes ---- */";
+
+ s.op->newline() << "stapkp_exit( "
+ << "stap_dwarf_probes, "
+ << "stap_dwarf_kprobes, "
+ << "ARRAY_SIZE(stap_dwarf_probes));";
}
static void sdt_v3_tokenize(const string& str, vector<string>& tokens)