[ltt-dev] [lttng-tools PATCH] Add kretprobe support (new --function implementation)
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Thu Jul 28 18:45:37 EDT 2011
Add kretprobe support (new --function implementation)
Also support probe "symbol" (without +offset) by checking first
character with isalpha().
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
include/lttng-kernel.h | 9 ++++++
include/lttng/lttng.h | 1
ltt-sessiond/ltt-sessiond.h | 1
ltt-sessiond/trace.c | 8 +++++
lttng/commands/enable_events.c | 58 +++++++++++++++++++++++++++++++++--------
5 files changed, 66 insertions(+), 11 deletions(-)
Index: lttng-tools/include/lttng-kernel.h
===================================================================
--- lttng-tools.orig/include/lttng-kernel.h
+++ lttng-tools/include/lttng-kernel.h
@@ -35,6 +35,7 @@ enum lttng_kernel_instrumentation {
LTTNG_KERNEL_TRACEPOINT = 0,
LTTNG_KERNEL_KPROBE = 1,
LTTNG_KERNEL_FUNCTION = 2,
+ LTTNG_KERNEL_KRETPROBE = 3,
};
enum lttng_kernel_context_type {
@@ -65,6 +66,13 @@ struct lttng_kernel_context {
} u;
};
+struct lttng_kernel_kretprobe {
+ uint64_t addr;
+
+ uint64_t offset;
+ char symbol_name[LTTNG_SYM_NAME_LEN];
+};
+
/*
* Either addr is used, or symbol_name and offset.
*/
@@ -85,6 +93,7 @@ struct lttng_kernel_event {
enum lttng_kernel_instrumentation instrumentation;
/* Per instrumentation type configuration */
union {
+ struct lttng_kernel_kretprobe kretprobe;
struct lttng_kernel_kprobe kprobe;
struct lttng_kernel_function ftrace;
} u;
Index: lttng-tools/include/lttng/lttng.h
===================================================================
--- lttng-tools.orig/include/lttng/lttng.h
+++ lttng-tools/include/lttng/lttng.h
@@ -73,6 +73,7 @@ enum lttng_event_type {
LTTNG_EVENT_TRACEPOINT,
LTTNG_EVENT_PROBE,
LTTNG_EVENT_FUNCTION,
+ LTTNG_EVENT_FUNCTION_ENTRY,
};
/*
Index: lttng-tools/ltt-sessiond/ltt-sessiond.h
===================================================================
--- lttng-tools.orig/ltt-sessiond/ltt-sessiond.h
+++ lttng-tools/ltt-sessiond/ltt-sessiond.h
@@ -36,6 +36,7 @@ const char *kernel_modules_list[] = {
"ltt-ring-buffer-metadata-mmap-client",
"lttng-ftrace",
"lttng-kprobes",
+ "lttng-kretprobes",
"lttng-probe-block",
"lttng-probe-irq",
"lttng-probe-kvm",
Index: lttng-tools/ltt-sessiond/trace.c
===================================================================
--- lttng-tools.orig/ltt-sessiond/trace.c
+++ lttng-tools/ltt-sessiond/trace.c
@@ -185,6 +185,14 @@ struct ltt_kernel_event *trace_create_ke
ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN);
break;
case LTTNG_EVENT_FUNCTION:
+ attr->instrumentation = LTTNG_KERNEL_KRETPROBE;
+ attr->u.kretprobe.addr = ev->attr.probe.addr;
+ attr->u.kretprobe.offset = ev->attr.probe.offset;
+ attr->u.kretprobe.offset = ev->attr.probe.offset;
+ strncpy(attr->u.kretprobe.symbol_name,
+ ev->attr.probe.symbol_name, LTTNG_SYM_NAME_LEN);
+ break;
+ case LTTNG_EVENT_FUNCTION_ENTRY:
attr->instrumentation = LTTNG_KERNEL_FUNCTION;
strncpy(attr->u.ftrace.symbol_name,
ev->attr.ftrace.symbol_name, LTTNG_SYM_NAME_LEN);
Index: lttng-tools/lttng/commands/enable_events.c
===================================================================
--- lttng-tools.orig/lttng/commands/enable_events.c
+++ lttng-tools/lttng/commands/enable_events.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <inttypes.h>
+#include <ctype.h>
#include "../cmd.h"
#include "../conf.h"
@@ -40,7 +41,8 @@ static int opt_userspace;
static int opt_enable_all;
static pid_t opt_pid;
static char *opt_probe;
-static char *opt_function_symbol;
+static char *opt_function;
+static char *opt_function_entry_symbol;
static char *opt_channel_name;
enum {
@@ -50,6 +52,7 @@ enum {
OPT_MARKER,
OPT_PROBE,
OPT_FUNCTION,
+ OPT_FUNCTION_ENTRY,
};
static struct poptOption long_options[] = {
@@ -66,6 +69,7 @@ static struct poptOption long_options[]
{"marker", 0, POPT_ARG_NONE, 0, OPT_MARKER, 0, 0},
{"probe", 0, POPT_ARG_STRING, 0, OPT_PROBE, 0, 0},
{"function", 0, POPT_ARG_STRING, 0, OPT_FUNCTION, 0, 0},
+ {"function:entry", 0, POPT_ARG_STRING, 0, OPT_FUNCTION_ENTRY, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
@@ -87,11 +91,16 @@ static void usage(FILE *ofp)
fprintf(ofp, "\n");
fprintf(ofp, "Event options:\n");
fprintf(ofp, " --tracepoint Tracepoint event (default)\n");
- fprintf(ofp, " --probe [addr | symbol+offset]\n");
+ fprintf(ofp, " --probe [addr | symbol | symbol+offset]\n");
fprintf(ofp, " Dynamic probe.\n");
fprintf(ofp, " Addr and offset can be octal (0NNN...),\n");
fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n");
- fprintf(ofp, " --function SYMBOL Function tracer event\n");
+ fprintf(ofp, " --function [addr | symbol | symbol+offset]\n");
+ fprintf(ofp, " Dynamic function entry/return probe.\n");
+ fprintf(ofp, " Addr and offset can be octal (0NNN...),\n");
+ fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n");
+ fprintf(ofp, " --function:entry symbol\n");
+ fprintf(ofp, " Function tracer event\n");
fprintf(ofp, " --marker User-space marker (deprecated)\n");
fprintf(ofp, "\n");
}
@@ -109,7 +118,7 @@ static int parse_probe_opts(struct lttng
if (opt == NULL) {
ret = -1;
- goto error;
+ goto end;
}
/* Check for symbol+offset */
@@ -120,12 +129,25 @@ static int parse_probe_opts(struct lttng
if (strlen(s_hex) == 0) {
ERR("Invalid probe offset %s", s_hex);
ret = -1;
- goto error;
+ goto end;
}
ev->attr.probe.offset = strtoul(s_hex, NULL, 0);
DBG("probe offset %" PRIu64, ev->attr.probe.offset);
ev->attr.probe.addr = 0;
- goto error;
+ goto end;
+ }
+
+ /* Check for symbol */
+ if (isalpha(name[0])) {
+ ret = sscanf(opt, "%s", name);
+ if (ret == 1) {
+ strncpy(ev->attr.probe.symbol_name, name, LTTNG_SYMBOL_NAME_LEN);
+ DBG("probe symbol %s", ev->attr.probe.symbol_name);
+ ev->attr.probe.offset = 0;
+ DBG("probe offset %" PRIu64, ev->attr.probe.offset);
+ ev->attr.probe.addr = 0;
+ goto end;
+ }
}
/* Check for address */
@@ -134,19 +156,19 @@ static int parse_probe_opts(struct lttng
if (strlen(s_hex) == 0) {
ERR("Invalid probe address %s", s_hex);
ret = -1;
- goto error;
+ goto end;
}
ev->attr.probe.addr = strtoul(s_hex, NULL, 0);
DBG("probe addr %" PRIu64, ev->attr.probe.addr);
ev->attr.probe.offset = 0;
memset(ev->attr.probe.symbol_name, 0, LTTNG_SYMBOL_NAME_LEN);
- goto error;
+ goto end;
}
/* No match */
ret = -1;
-error:
+end:
return ret;
}
@@ -217,7 +239,17 @@ static int enable_events(void)
}
break;
case LTTNG_EVENT_FUNCTION:
- strncpy(ev.attr.ftrace.symbol_name, opt_function_symbol, LTTNG_SYMBOL_NAME_LEN);
+ ret = parse_probe_opts(&ev, opt_function);
+ if (ret < 0) {
+ ERR("Unable to parse function probe options");
+ ret = 0;
+ goto error;
+ }
+ break;
+ case LTTNG_EVENT_FUNCTION_ENTRY:
+ strncpy(ev.attr.ftrace.symbol_name,
+ opt_function_entry_symbol,
+ LTTNG_SYMBOL_NAME_LEN);
break;
default:
ret = CMD_NOT_IMPLEMENTED;
@@ -291,7 +323,11 @@ int cmd_enable_events(int argc, const ch
break;
case OPT_FUNCTION:
opt_event_type = LTTNG_EVENT_FUNCTION;
- opt_function_symbol = poptGetOptArg(pc);
+ opt_function = poptGetOptArg(pc);
+ break;
+ case OPT_FUNCTION_ENTRY:
+ opt_event_type = LTTNG_EVENT_FUNCTION_ENTRY;
+ opt_function_entry_symbol = poptGetOptArg(pc);
break;
default:
usage(stderr);
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list