[ltt-dev] [lttng-tools PATCH] Add kretprobe support (new --function implementation)

David Goulet david.goulet at polymtl.ca
Fri Jul 29 11:25:17 EDT 2011


Merged! Thanks

FIN

David

On 11-07-28 06:45 PM, Mathieu Desnoyers wrote:
> 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);
> 




More information about the lttng-dev mailing list