|
@@ -62,9 +62,23 @@ static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
|
|
|
return strncmp(mod->name, name, len) == 0 && name[len] == ':';
|
|
|
}
|
|
|
|
|
|
-static nokprobe_inline bool trace_kprobe_is_on_module(struct trace_kprobe *tk)
|
|
|
+static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
|
|
|
{
|
|
|
- return !!strchr(trace_kprobe_symbol(tk), ':');
|
|
|
+ char *p;
|
|
|
+ bool ret;
|
|
|
+
|
|
|
+ if (!tk->symbol)
|
|
|
+ return false;
|
|
|
+ p = strchr(tk->symbol, ':');
|
|
|
+ if (!p)
|
|
|
+ return true;
|
|
|
+ *p = '\0';
|
|
|
+ mutex_lock(&module_mutex);
|
|
|
+ ret = !!find_module(tk->symbol);
|
|
|
+ mutex_unlock(&module_mutex);
|
|
|
+ *p = ':';
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
|
|
@@ -374,19 +388,13 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
|
|
|
else
|
|
|
ret = register_kprobe(&tk->rp.kp);
|
|
|
|
|
|
- if (ret == 0)
|
|
|
+ if (ret == 0) {
|
|
|
tk->tp.flags |= TP_FLAG_REGISTERED;
|
|
|
- else {
|
|
|
- if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) {
|
|
|
- pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
|
|
|
- ret = 0;
|
|
|
- } else if (ret == -EILSEQ) {
|
|
|
- pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
|
|
|
- tk->rp.kp.addr);
|
|
|
- ret = -EINVAL;
|
|
|
- }
|
|
|
+ } else if (ret == -EILSEQ) {
|
|
|
+ pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
|
|
|
+ tk->rp.kp.addr);
|
|
|
+ ret = -EINVAL;
|
|
|
}
|
|
|
-
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -449,6 +457,11 @@ static int register_trace_kprobe(struct trace_kprobe *tk)
|
|
|
|
|
|
/* Register k*probe */
|
|
|
ret = __register_trace_kprobe(tk);
|
|
|
+ if (ret == -ENOENT && !trace_kprobe_module_exist(tk)) {
|
|
|
+ pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
|
|
|
+ ret = 0;
|
|
|
+ }
|
|
|
+
|
|
|
if (ret < 0)
|
|
|
unregister_kprobe_event(tk);
|
|
|
else
|