|
@@ -226,14 +226,26 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
|
|
|
+ int ntevs, const char *module)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ for (i = 0; i < ntevs; i++) {
|
|
|
+ tevs[i].point.module = strdup(module);
|
|
|
+ if (!tevs[i].point.module)
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/* Try to find perf_probe_event with debuginfo */
|
|
|
static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
|
|
|
- struct probe_trace_event **tevs,
|
|
|
- int max_tevs, const char *module)
|
|
|
+ struct probe_trace_event **tevs,
|
|
|
+ int max_tevs, const char *module)
|
|
|
{
|
|
|
bool need_dwarf = perf_probe_event_need_dwarf(pev);
|
|
|
struct debuginfo *dinfo = open_debuginfo(module);
|
|
|
- int ntevs;
|
|
|
+ int ntevs, ret = 0;
|
|
|
|
|
|
if (!dinfo) {
|
|
|
if (need_dwarf) {
|
|
@@ -251,7 +263,10 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
|
|
|
|
|
|
if (ntevs > 0) { /* Succeeded to find trace events */
|
|
|
pr_debug("find %d probe_trace_events.\n", ntevs);
|
|
|
- return ntevs;
|
|
|
+ if (module)
|
|
|
+ ret = add_module_to_probe_trace_events(*tevs, ntevs,
|
|
|
+ module);
|
|
|
+ return ret < 0 ? ret : ntevs;
|
|
|
}
|
|
|
|
|
|
if (ntevs == 0) { /* No error but failed to find probe point. */
|
|
@@ -1010,7 +1025,7 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
|
|
|
|
|
|
/* Parse probe_events event into struct probe_point */
|
|
|
static int parse_probe_trace_command(const char *cmd,
|
|
|
- struct probe_trace_event *tev)
|
|
|
+ struct probe_trace_event *tev)
|
|
|
{
|
|
|
struct probe_trace_point *tp = &tev->point;
|
|
|
char pr;
|
|
@@ -1043,8 +1058,14 @@ static int parse_probe_trace_command(const char *cmd,
|
|
|
|
|
|
tp->retprobe = (pr == 'r');
|
|
|
|
|
|
- /* Scan function name and offset */
|
|
|
- ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
|
|
|
+ /* Scan module name(if there), function name and offset */
|
|
|
+ p = strchr(argv[1], ':');
|
|
|
+ if (p) {
|
|
|
+ tp->module = strndup(argv[1], p - argv[1]);
|
|
|
+ p++;
|
|
|
+ } else
|
|
|
+ p = argv[1];
|
|
|
+ ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol,
|
|
|
&tp->offset);
|
|
|
if (ret == 1)
|
|
|
tp->offset = 0;
|
|
@@ -1289,9 +1310,10 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
|
|
|
if (buf == NULL)
|
|
|
return NULL;
|
|
|
|
|
|
- len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
|
|
|
+ len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
|
|
|
tp->retprobe ? 'r' : 'p',
|
|
|
tev->group, tev->event,
|
|
|
+ tp->module ?: "", tp->module ? ":" : "",
|
|
|
tp->symbol, tp->offset);
|
|
|
if (len <= 0)
|
|
|
goto error;
|
|
@@ -1398,6 +1420,8 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
|
|
|
free(tev->group);
|
|
|
if (tev->point.symbol)
|
|
|
free(tev->point.symbol);
|
|
|
+ if (tev->point.module)
|
|
|
+ free(tev->point.module);
|
|
|
for (i = 0; i < tev->nargs; i++) {
|
|
|
if (tev->args[i].name)
|
|
|
free(tev->args[i].name);
|
|
@@ -1749,7 +1773,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
|
|
|
/* Convert perf_probe_event with debuginfo */
|
|
|
ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module);
|
|
|
if (ret != 0)
|
|
|
- return ret;
|
|
|
+ return ret; /* Found in debuginfo or got an error */
|
|
|
|
|
|
/* Allocate trace event buffer */
|
|
|
tev = *tevs = zalloc(sizeof(struct probe_trace_event));
|
|
@@ -1762,6 +1786,11 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
|
|
|
ret = -ENOMEM;
|
|
|
goto error;
|
|
|
}
|
|
|
+ tev->point.module = strdup(module);
|
|
|
+ if (tev->point.module == NULL) {
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
tev->point.offset = pev->point.offset;
|
|
|
tev->point.retprobe = pev->point.retprobe;
|
|
|
tev->nargs = pev->nargs;
|