* Yannick Brosseau ([email protected]) wrote:
> Inspired by the k*probe support.
> 
> It add a new option to enable-event --uprobe which require a path name
> and an offset in the specified file.
> 
> (The file Documentation/trace/uprobetracer.txt in the kernel source provides
> and example on how to extract the offset for a symbol in a program)

Asking Masami and looking at perf might help us add support for lookup
by file/lineno (using dwarf info). I think in terms of usability this is
really important, and should appear in tools at the same time as the
basic feature based on file/offset (or at least appear in the same
LTTng release).

We should keep in mind that liblttng-ctl is LGPLv2.1, so we cannot use
perf code as-is without asking for the author's permission first.
Nothing prevents us from writing this support ourself if need be though.

Thanks,

Mathieu

> 
> Signed-off-by: Yannick Brosseau <[email protected]>
> ---
>  include/lttng/lttng.h                  |   15 +++++++++
>  src/bin/lttng-sessiond/cmd.c           |    5 +++
>  src/bin/lttng-sessiond/modprobe.c      |    1 +
>  src/bin/lttng-sessiond/trace-kernel.c  |    7 ++++
>  src/bin/lttng/commands/enable_events.c |   55 
> ++++++++++++++++++++++++++++++++
>  src/bin/lttng/commands/list.c          |    8 +++++
>  src/common/lttng-kernel.h              |    7 ++++
>  7 files changed, 98 insertions(+)
> 
> diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h
> index e21b479..c790e7b 100644
> --- a/include/lttng/lttng.h
> +++ b/include/lttng/lttng.h
> @@ -72,6 +72,7 @@ enum lttng_event_type {
>       LTTNG_EVENT_FUNCTION_ENTRY            = 3,
>       LTTNG_EVENT_NOOP                      = 4,
>       LTTNG_EVENT_SYSCALL                   = 5,
> +     LTTNG_EVENT_UPROBE                    = 6,
>  };
>  
>  /*
> @@ -219,6 +220,19 @@ struct lttng_event_function_attr {
>  };
>  
>  /*
> + * Event uprobe.
> + *
> + * The structures should be initialized to zero before use.
> + */
> +#define LTTNG_EVENT_UPROBE_PADDING1         24
> +struct lttng_event_uprobe_attr {
> +     char path[LTTNG_SYMBOL_NAME_LEN];
> +     uint64_t offset;
> +
> +     char padding[LTTNG_EVENT_UPROBE_PADDING1];
> +};
> +
> +/*
>   * Generic lttng event
>   *
>   * The structures should be initialized to zero before use.
> @@ -242,6 +256,7 @@ struct lttng_event {
>       union {
>               struct lttng_event_probe_attr probe;
>               struct lttng_event_function_attr ftrace;
> +             struct lttng_event_uprobe_attr uprobe;
>  
>               char padding[LTTNG_EVENT_PADDING2];
>       } attr;
> diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c
> index 491acde..d7fee70 100644
> --- a/src/bin/lttng-sessiond/cmd.c
> +++ b/src/bin/lttng-sessiond/cmd.c
> @@ -315,6 +315,11 @@ static int list_lttng_kernel_events(char *channel_name,
>                       memcpy(&((*events)[i].attr.ftrace), 
> &event->event->u.ftrace,
>                                       sizeof(struct lttng_kernel_function));
>                       break;
> +             case LTTNG_KERNEL_UPROBE:
> +                     (*events)[i].type = LTTNG_EVENT_UPROBE;
> +                     memcpy(&(*events)[i].attr.uprobe, 
> &event->event->u.uprobe,
> +                                     sizeof(struct lttng_kernel_uprobe));
> +                     break;
>               case LTTNG_KERNEL_NOOP:
>                       (*events)[i].type = LTTNG_EVENT_NOOP;
>                       break;
> diff --git a/src/bin/lttng-sessiond/modprobe.c 
> b/src/bin/lttng-sessiond/modprobe.c
> index 1a5a1b7..805e127 100644
> --- a/src/bin/lttng-sessiond/modprobe.c
> +++ b/src/bin/lttng-sessiond/modprobe.c
> @@ -35,6 +35,7 @@ const struct kern_modules_param kern_modules_list[] = {
>       { "lttng-ftrace", 0 },
>       { "lttng-kprobes", 0 },
>       { "lttng-kretprobes", 0 },
> +     { "lttng-uprobes", 0 },
>       { "lttng-lib-ring-buffer", 1 },
>       { "lttng-ring-buffer-client-discard", 1 },
>       { "lttng-ring-buffer-client-overwrite", 1 },
> diff --git a/src/bin/lttng-sessiond/trace-kernel.c 
> b/src/bin/lttng-sessiond/trace-kernel.c
> index f38cf3d..24f33f9 100644
> --- a/src/bin/lttng-sessiond/trace-kernel.c
> +++ b/src/bin/lttng-sessiond/trace-kernel.c
> @@ -207,6 +207,13 @@ struct ltt_kernel_event 
> *trace_kernel_create_event(struct lttng_event *ev)
>                               ev->attr.probe.symbol_name, 
> LTTNG_KERNEL_SYM_NAME_LEN);
>               attr->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = 
> '\0';
>               break;
> +     case LTTNG_EVENT_UPROBE:
> +             attr->instrumentation = LTTNG_KERNEL_UPROBE;
> +             attr->u.uprobe.offset = ev->attr.uprobe.offset;
> +             strncpy(attr->u.uprobe.path,
> +                             ev->attr.uprobe.path, 
> LTTNG_KERNEL_SYM_NAME_LEN);
> +             attr->u.uprobe.path[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
> +             break;
>       case LTTNG_EVENT_FUNCTION:
>               attr->instrumentation = LTTNG_KERNEL_KRETPROBE;
>               attr->u.kretprobe.addr = ev->attr.probe.addr;
> diff --git a/src/bin/lttng/commands/enable_events.c 
> b/src/bin/lttng/commands/enable_events.c
> index b6c18e1..61cb15b 100644
> --- a/src/bin/lttng/commands/enable_events.c
> +++ b/src/bin/lttng/commands/enable_events.c
> @@ -38,6 +38,7 @@ static char *opt_session_name;
>  static int opt_userspace;
>  static int opt_enable_all;
>  static char *opt_probe;
> +static char *opt_uprobe;
>  static char *opt_function;
>  static char *opt_function_entry_symbol;
>  static char *opt_channel_name;
> @@ -52,6 +53,7 @@ enum {
>       OPT_HELP = 1,
>       OPT_TRACEPOINT,
>       OPT_PROBE,
> +     OPT_UPROBE,
>       OPT_FUNCTION,
>       OPT_FUNCTION_ENTRY,
>       OPT_SYSCALL,
> @@ -74,6 +76,7 @@ static struct poptOption long_options[] = {
>       {"userspace",      'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
>       {"tracepoint",     0,   POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0},
>       {"probe",          0,   POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0},
> +     {"uprobe",          0,   POPT_ARG_STRING, &opt_uprobe, OPT_UPROBE, 0, 
> 0},
>       {"function",       0,   POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 
> 0, 0},
>  #if 0
>       /*
> @@ -117,6 +120,10 @@ static void usage(FILE *ofp)
>       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, "    --uprobe [path+offset]\n");
> +     fprintf(ofp, "                           Dynamic uprobe.\n");
> +     fprintf(ofp, "                           offset can be octal 
> (0NNN...),\n");
> +     fprintf(ofp, "                           decimal (NNN...) or 
> hexadecimal (0xNNN...)\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");
> @@ -245,6 +252,42 @@ static int parse_probe_opts(struct lttng_event *ev, char 
> *opt)
>  end:
>       return ret;
>  }
> +/*
> + * Parse uprobe options.
> + */
> +static int parse_uprobe_opts(struct lttng_event *ev, char *opt)
> +{
> +     int ret;
> +     char s_hex[19];
> +     char name[LTTNG_SYMBOL_NAME_LEN];
> +
> +     if (opt == NULL) {
> +             ret = -1;
> +             goto end;
> +     }
> +
> +     /* Check for path+offset */
> +     ret = sscanf(opt, "%[^'+']+%s", name, s_hex);
> +     if (ret == 2) {
> +             strncpy(ev->attr.uprobe.path, name, LTTNG_SYMBOL_NAME_LEN);
> +             ev->attr.uprobe.path[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
> +             DBG("probe path %s", ev->attr.uprobe.path);
> +             if (strlen(s_hex) == 0) {
> +                     ERR("Invalid uprobe offset %s", s_hex);
> +                     ret = -1;
> +                     goto end;
> +             }
> +             ev->attr.uprobe.offset = strtoul(s_hex, NULL, 0);
> +             DBG("uprobe offset %" PRIu64, ev->attr.uprobe.offset);
> +             goto end;
> +     }
> +
> +     /* No match */
> +     ret = -1;
> +
> +end:
> +     return ret;
> +}
>  
>  /*
>   * Maps loglevel from string to value
> @@ -471,6 +514,14 @@ static int enable_events(char *session_name)
>                                       goto error;
>                               }
>                               break;
> +                     case LTTNG_EVENT_UPROBE:
> +                             ret = parse_uprobe_opts(&ev, opt_uprobe);
> +                             if (ret < 0) {
> +                                     ERR("Unable to parse uprobe options");
> +                                     ret = 0;
> +                                     goto error;
> +                             }
> +                             break;
>                       case LTTNG_EVENT_FUNCTION:
>                               ret = parse_probe_opts(&ev, opt_function);
>                               if (ret < 0) {
> @@ -522,6 +573,7 @@ static int enable_events(char *session_name)
>                               ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
>                               break;
>                       case LTTNG_EVENT_PROBE:
> +                     case LTTNG_EVENT_UPROBE:
>                       case LTTNG_EVENT_FUNCTION:
>                       case LTTNG_EVENT_FUNCTION_ENTRY:
>                       case LTTNG_EVENT_SYSCALL:
> @@ -636,6 +688,9 @@ int cmd_enable_events(int argc, const char **argv)
>               case OPT_PROBE:
>                       opt_event_type = LTTNG_EVENT_PROBE;
>                       break;
> +             case OPT_UPROBE:
> +                     opt_event_type = LTTNG_EVENT_UPROBE;
> +                     break;
>               case OPT_FUNCTION:
>                       opt_event_type = LTTNG_EVENT_FUNCTION;
>                       break;
> diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c
> index a6ea6b8..ffae239 100644
> --- a/src/bin/lttng/commands/list.c
> +++ b/src/bin/lttng/commands/list.c
> @@ -231,6 +231,14 @@ static void print_events(struct lttng_event *event)
>                       MSG("%ssymbol: %s", indent8, 
> event->attr.probe.symbol_name);
>               }
>               break;
> +     case LTTNG_EVENT_UPROBE:
> +             MSG("%s%s (type: uprobe)%s%s", indent6,
> +                             event->name, enabled_string(event->enabled),
> +                             filter_string(event->filter));
> +
> +             MSG("%spath: %s", indent8, event->attr.uprobe.path);
> +             MSG("%soffset: 0x%" PRIx64, indent8, event->attr.uprobe.offset);
> +             break;
>       case LTTNG_EVENT_FUNCTION:
>       case LTTNG_EVENT_FUNCTION_ENTRY:
>               MSG("%s%s (type: function)%s%s", indent6,
> diff --git a/src/common/lttng-kernel.h b/src/common/lttng-kernel.h
> index fa8ba61..a43b956 100644
> --- a/src/common/lttng-kernel.h
> +++ b/src/common/lttng-kernel.h
> @@ -38,6 +38,7 @@ enum lttng_kernel_instrumentation {
>       LTTNG_KERNEL_KRETPROBE     = 3,
>       LTTNG_KERNEL_NOOP          = 4,    /* not hooked */
>       LTTNG_KERNEL_SYSCALL       = 5,
> +     LTTNG_KERNEL_UPROBE        = 6,
>  };
>  
>  enum lttng_kernel_context_type {
> @@ -96,6 +97,11 @@ struct lttng_kernel_function {
>       char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN];
>  }__attribute__((packed));
>  
> +struct lttng_kernel_uprobe {
> +     char path[LTTNG_KERNEL_SYM_NAME_LEN];
> +     uint64_t offset;
> +}__attribute__((packed));
> +
>  #define LTTNG_KERNEL_EVENT_PADDING1    16
>  #define LTTNG_KERNEL_EVENT_PADDING2    LTTNG_KERNEL_SYM_NAME_LEN + 32
>  struct lttng_kernel_event {
> @@ -108,6 +114,7 @@ struct lttng_kernel_event {
>               struct lttng_kernel_kretprobe kretprobe;
>               struct lttng_kernel_kprobe kprobe;
>               struct lttng_kernel_function ftrace;
> +             struct lttng_kernel_uprobe uprobe;
>               char padding[LTTNG_KERNEL_EVENT_PADDING2];
>       } u;
>  }__attribute__((packed));
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> lttng-dev mailing list
> [email protected]
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com

_______________________________________________
lttng-dev mailing list
[email protected]
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

Reply via email to