linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address
@ 2015-08-26  7:40 Wang Nan
  2015-08-26  7:40 ` [PATCH v2 1/4] perf probe: Prevent segfault when reading probe point with " Wang Nan
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Wang Nan @ 2015-08-26  7:40 UTC (permalink / raw)
  To: acme, masami.hiramatsu.pt, rostedt
  Cc: mingo, namhyung, pi3orama, linux-kernel

The goal of these 4 patches is to allow perf probing at absolute address
for uprobes and kprobes. During the development several small problem in
'perf probe -l' is found and fixed.

Patch 1 has already acked by Masami Hiramatsu.

Patch 2 fixes a problem about zero address in perf side.

Patch 3 is the main patch of these 4. It allows following command:

 # perf probe /lib/x86_64-linux-gnu/libc-2.19.so 0xeb860

 Different from v1, no extra '+' is required.

Patch 4 is a kernel side patch which fixes a small problem in uprobe_event
that, if address is 0, uprobe_events reports '0x  (null)'. It is independent
from the other patches.

Wang Nan (4):
  perf probe: Prevent segfault when reading probe point with absolute
    address
  perf probe: Fix list result when address is zero
  perf probe: Support probing at absolute address
  tracing/uprobes: Do not print '0x  (null)' when offset is 0

 kernel/trace/trace_uprobe.c    |  17 +++-
 tools/perf/util/probe-event.c  | 210 +++++++++++++++++++++++++++++++++++++----
 tools/perf/util/probe-event.h  |   4 +
 tools/perf/util/probe-finder.c |  21 +----
 4 files changed, 216 insertions(+), 36 deletions(-)

-- 
1.8.3.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/4] perf probe: Prevent segfault when reading probe point with absolute address
  2015-08-26  7:40 [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
@ 2015-08-26  7:40 ` Wang Nan
  2015-08-26  7:40 ` [PATCH v2 2/4] perf probe: Fix list result when address is zero Wang Nan
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Wang Nan @ 2015-08-26  7:40 UTC (permalink / raw)
  To: acme, masami.hiramatsu.pt, rostedt
  Cc: mingo, namhyung, pi3orama, linux-kernel

'perf probe -l' panic if there is a manually inserted probing point
with absolute address. For example:

 # echo 'p:probe/abs_ffffffff811e6615 0xffffffff811e6615' > /sys/kernel/debug/tracing/kprobe_events
 # perf probe -l
 Segmentation fault (core dumped)

This patch fixes this problem by considering the situation that
"tp->symbol == NULL" in find_perf_probe_point_from_dwarf() and
find_perf_probe_point_from_map().

After this patch:

 # perf probe -l
 probe:abs_ffffffff811e6615 (on SyS_write+5@fs/read_write.c)

And when debug info is missing:

 # rm -rf ~/.debug
 # mv /lib/modules/4.2.0-rc1+/build/vmlinux /lib/modules/4.2.0-rc1+/build/vmlinux.bak
 # perf probe -l
 probe:abs_ffffffff811e6615 (on sys_write+5)

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1440509256-193590-1-git-send-email-wangnan0@huawei.com
---
 tools/perf/util/probe-event.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f173372..ef325a2 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -517,7 +517,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
 		if (ret < 0)
 			goto error;
 		addr += stext;
-	} else {
+	} else if (tp->symbol) {
 		addr = kernel_get_symbol_address_by_name(tp->symbol, false);
 		if (addr == 0)
 			goto error;
@@ -1817,17 +1817,17 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
 {
 	struct symbol *sym = NULL;
 	struct map *map;
-	u64 addr;
+	u64 addr = tp->address;
 	int ret = -ENOENT;
 
 	if (!is_kprobe) {
 		map = dso__new_map(tp->module);
 		if (!map)
 			goto out;
-		addr = tp->address;
 		sym = map__find_symbol(map, addr, NULL);
 	} else {
-		addr = kernel_get_symbol_address_by_name(tp->symbol, true);
+		if (tp->symbol)
+			addr = kernel_get_symbol_address_by_name(tp->symbol, true);
 		if (addr) {
 			addr += tp->offset;
 			sym = __find_kernel_function(addr, &map);
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/4] perf probe: Fix list result when address is zero
  2015-08-26  7:40 [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
  2015-08-26  7:40 ` [PATCH v2 1/4] perf probe: Prevent segfault when reading probe point with " Wang Nan
@ 2015-08-26  7:40 ` Wang Nan
  2015-08-26  9:29   ` 平松雅巳 / HIRAMATU,MASAMI
  2015-08-26  7:40 ` [PATCH v2 3/4] perf probe: Support probing at absolute address Wang Nan
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Wang Nan @ 2015-08-26  7:40 UTC (permalink / raw)
  To: acme, masami.hiramatsu.pt, rostedt
  Cc: mingo, namhyung, pi3orama, linux-kernel

When manually added uprobe point with zero address, 'perf probe -l'
reports error. For example:

 # echo p:probe_libc/abs_0 /path/to/lib.bin:0x0 arg1=%ax > \
           /sys/kernel/debug/tracing/uprobe_events

 # perf probe -l
 Error: Failed to show event list.

Probing at 0x0 is possible and useful when lib.bin is not a normal
shared object but is manually mapped. However, in this case kernel
report:

 # cat /sys/kernel/debug/tracing/uprobe_events
 p:probe_libc/abs_0 /tmp/oxygen_root/lib64/libc-2.18.so:0x          (null) arg1=%ax

This patch supports the above kernel output.

In addition, this patch also fixes convert_to_perf_probe_point() that,
if failed to find probe point from both of dwarf and map, in all cases
pp->function should be filled with a strdup() result, or the following
ENOMEM error code is incorrect. Remove !tp->module && !is_kprobe
condition so always use address to build function name if symbol is not
found.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
 tools/perf/util/probe-event.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index ef325a2..3ce223d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1521,9 +1521,31 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
 	} else
 		p = argv[1];
 	fmt1_str = strtok_r(p, "+", &fmt);
-	if (fmt1_str[0] == '0')	/* only the address started with 0x */
-		tp->address = strtoul(fmt1_str, NULL, 0);
-	else {
+	/* only the address started with 0x */
+	if (fmt1_str[0] == '0')	{
+		/*
+		 * Fix a special case:
+		 * if address == 0, kernel reports something like:
+		 * p:probe_libc/abs_0 /lib/libc-2.18.so:0x          (null) arg1=%ax
+		 * Newer kernel may fix that, but we want to
+		 * support old kernel also.
+		 */
+		if (strcmp(fmt1_str, "0x") == 0) {
+			if (!argv[2] || strcmp(argv[2], "(null)")) {
+				ret = -EINVAL;
+				goto out;
+			}
+			tp->address = 0;
+
+			free(argv[2]);
+			for (i = 2; argv[i + 1] != NULL; i++)
+				argv[i] = argv[i + 1];
+
+			argv[i] = NULL;
+			argc -= 1;
+		} else
+			tp->address = strtoul(fmt1_str, NULL, 0);
+	} else {
 		/* Only the symbol-based probe has offset */
 		tp->symbol = strdup(fmt1_str);
 		if (tp->symbol == NULL) {
@@ -1868,7 +1890,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,
 	if (tp->symbol) {
 		pp->function = strdup(tp->symbol);
 		pp->offset = tp->offset;
-	} else if (!tp->module && !is_kprobe) {
+	} else {
 		ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
 		if (ret < 0)
 			return ret;
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/4] perf probe: Support probing at absolute address
  2015-08-26  7:40 [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
  2015-08-26  7:40 ` [PATCH v2 1/4] perf probe: Prevent segfault when reading probe point with " Wang Nan
  2015-08-26  7:40 ` [PATCH v2 2/4] perf probe: Fix list result when address is zero Wang Nan
@ 2015-08-26  7:40 ` Wang Nan
  2015-08-26  9:49   ` 平松雅巳 / HIRAMATU,MASAMI
  2015-08-26  7:40 ` [PATCH v2 4/4] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
  2015-08-26  9:12 ` [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address 平松雅巳 / HIRAMATU,MASAMI
  4 siblings, 1 reply; 11+ messages in thread
From: Wang Nan @ 2015-08-26  7:40 UTC (permalink / raw)
  To: acme, masami.hiramatsu.pt, rostedt
  Cc: mingo, namhyung, pi3orama, linux-kernel

It should be useful to allow 'perf probe' probe at absolute offset of
a target. For example, when (u)probing at a instruction of a shared
object in a embedded system where debuginfo is not avaliable but we
know the offset of that instruction by manually digging.

This patch enables following perf probe command syntax:

 # perf probe 0xffffffff811e6615

And

 # perf probe /lib/x86_64-linux-gnu/libc-2.19.so 0xeb860

In the above example, we don't need a anchor symbol, so it is possible
to compute absolute addresses using other methods and then use
'perf probe' to create the probing points.

This patch also fix a bug that, when offset is provided but function is
skipped, parse_perf_probe_point() will give function a "" string, so
the checking code at the end of this function is not used. For example:

 # perf probe +0x1234
 Failed to find symbol  in kernel
   Error: Failed to add events.

After this patch:

 # perf probe +0x1234
 Semantic error :Offset requires an entry function.
   Error: Command Parse Error.

v1 -> v2:
  Drop the leading '+' in cmdline;
  Allow uprobing at offset 0x0;
  Improve 'perf probe -l' result when uprobe at area without debuginfo.

Test result:

 # perf probe 0xffffffff8119d175 %ax
 # perf probe sys_write %ax
 # perf probe /lib64/libc-2.18.so 0x0 %ax
 # perf probe /lib64/libc-2.18.so 0x5 %ax
 # perf probe /lib64/libc-2.18.so 0xd8e40 %ax
 # perf probe /lib64/libc-2.18.so __write %ax
 # perf probe /lib64/libc-2.18.so 0xd8e49 %ax
 # cat /sys/kernel/debug/tracing/uprobe_events

 p:probe_libc/abs_0 /lib64/libc-2.18.so:0x          (null) arg1=%ax
 p:probe_libc/abs_5 /lib64/libc-2.18.so:0x0000000000000005 arg1=%ax
 p:probe_libc/abs_d8e40 /lib64/libc-2.18.so:0x00000000000d8e40 arg1=%ax
 p:probe_libc/__write /lib64/libc-2.18.so:0x00000000000d8e40 arg1=%ax
 p:probe_libc/abs_d8e49 /lib64/libc-2.18.so:0x00000000000d8e49 arg1=%ax

 # cat /sys/kernel/debug/tracing/kprobe_events

 p:probe/abs_ffffffff8119d175 0xffffffff8119d175 arg1=%ax
 p:probe/sys_write _text+1692016 arg1=%ax

 # perf probe -l

 Failed to find debug information for address 5
   probe:abs_ffffffff8119d175 (on sys_write+5 with arg1)
   probe:sys_write      (on sys_write with arg1)
   probe_libc:__write   (on @unix/syscall-template.S:81 in /lib64/libc-2.18.so with arg1)
   probe_libc:abs_0     (on 0x0 in /lib64/libc-2.18.so with arg1)
   probe_libc:abs_5     (on 0x5 in /lib64/libc-2.18.so with arg1)
   probe_libc:abs_d8e40 (on @unix/syscall-template.S:81 in /lib64/libc-2.18.so with arg1)
   probe_libc:abs_d8e49 (on __GI___libc_write+9 in /lib64/libc-2.18.so with arg1)

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
 tools/perf/util/probe-event.c  | 172 ++++++++++++++++++++++++++++++++++++++---
 tools/perf/util/probe-event.h  |   4 +
 tools/perf/util/probe-finder.c |  21 +----
 3 files changed, 170 insertions(+), 27 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3ce223d..b94a8d7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1196,15 +1196,37 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 		*ptr++ = '\0';
 	}
 
-	tmp = strdup(arg);
-	if (tmp == NULL)
-		return -ENOMEM;
+	if (arg[0] == '\0')
+		tmp = NULL;
+	else {
+		tmp = strdup(arg);
+		if (tmp == NULL)
+			return -ENOMEM;
+	}
 
 	if (file_spec)
 		pp->file = tmp;
-	else
+	else {
 		pp->function = tmp;
 
+		/*
+		 * Keep pp->function even if this is absolute address,
+		 * so it can mark whether abs_address is valid.
+		 * Which make 'perf probe lib.bin 0x0' possible.
+		 *
+		 * Note that checking length of tmp is not needed
+		 * because when we access tmp[1] we know tmp[0] is '0',
+		 * so tmp[1] should always valid (but could be '\0').
+		 */
+		if (tmp && !strncmp(tmp, "0x", 2)) {
+			pp->abs_address = strtoul(pp->function, &tmp, 0);
+			if (*tmp != '\0') {
+				semantic_error("Invalid absolute address.\n");
+				return -EINVAL;
+			}
+		}
+	}
+
 	/* Parse other options */
 	while (ptr) {
 		arg = ptr;
@@ -1802,14 +1824,29 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
 	if (len <= 0)
 		goto error;
 
-	/* Uprobes must have tp->address and tp->module */
-	if (tev->uprobes && (!tp->address || !tp->module))
+	/* Uprobes must have tp->module */
+	if (tev->uprobes && !tp->module)
 		goto error;
+	/*
+	 * If tp->address == 0, then this point must be a
+	 * absolute address uprobe.
+	 * try_to_find_absolute_address() should have made
+	 * tp->symbol to "0x0".
+	 */
+	if (tev->uprobes && !tp->address) {
+		if (!tp->symbol || strcmp(tp->symbol, "0x0"))
+			goto error;
+	}
 
 	/* Use the tp->address for uprobes */
 	if (tev->uprobes)
 		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx",
 				 tp->module, tp->address);
+	else if (!strncmp(tp->symbol, "0x", 2))
+		/* Absolute address. See try_to_find_absolute_address() */
+		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s0x%lx",
+				 tp->module ?: "", tp->module ? ":" : "",
+				 tp->address);
 	else
 		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu",
 				 tp->module ?: "", tp->module ? ":" : "",
@@ -1872,8 +1909,8 @@ out:
 }
 
 static int convert_to_perf_probe_point(struct probe_trace_point *tp,
-					struct perf_probe_point *pp,
-					bool is_kprobe)
+				       struct perf_probe_point *pp,
+				       bool is_kprobe)
 {
 	char buf[128];
 	int ret;
@@ -2334,7 +2371,9 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
 	if (pev->event)
 		event = pev->event;
 	else
-		if (pev->point.function && !strisglob(pev->point.function))
+		if (pev->point.function &&
+			(strncmp(pev->point.function, "0x", 2) != 0) &&
+			!strisglob(pev->point.function))
 			event = pev->point.function;
 		else
 			event = tev->point.realname;
@@ -2604,6 +2643,98 @@ err_out:
 	goto out;
 }
 
+static int try_to_find_absolute_address(struct perf_probe_event *pev,
+					struct probe_trace_event **tevs)
+{
+	struct perf_probe_point *pp = &pev->point;
+	struct probe_trace_event *tev;
+	struct probe_trace_point *tp;
+	int i, err;
+
+	if (!(pev->point.function && !strncmp(pev->point.function, "0x", 2)))
+		return -EINVAL;
+	if (perf_probe_event_need_dwarf(pev))
+		return -EINVAL;
+
+	/*
+	 * This is 'perf probe /lib/libc.so 0xabcd'. Try to probe at
+	 * absolute address.
+	 *
+	 * Only one tev can be generated by this.
+	 */
+	*tevs = zalloc(sizeof(*tev));
+	if (!*tevs)
+		return -ENOMEM;
+
+	tev = *tevs;
+	tp = &tev->point;
+
+	/*
+	 * Don't use tp->offset, use address directly, because
+	 * in synthesize_probe_trace_command() address cannot be
+	 * zero.
+	 */
+	tp->address = pev->point.abs_address;
+	tp->retprobe = pp->retprobe;
+	tev->uprobes = pev->uprobes;
+
+	err = -ENOMEM;
+	/*
+	 * Give it a '0x' leading symbol name.
+	 * In __add_probe_trace_events, a NULL symbol is interpreted as
+	 * invalud.
+	 */
+	if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
+		goto errout;
+
+	/* For kprobe, check range */
+	if ((!tev->uprobes) &&
+	    (kprobe_warn_out_range(tev->point.symbol,
+				   tev->point.address))) {
+		err = -EACCES;
+		goto errout;
+	}
+
+	if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
+		goto errout;
+
+	if (pev->target) {
+		tp->module = strdup(pev->target);
+		if (!tp->module)
+			goto errout;
+	}
+
+	if (tev->group) {
+		tev->group = strdup(pev->group);
+		if (!tev->group)
+			goto errout;
+	}
+
+	if (pev->event) {
+		tev->event = strdup(pev->event);
+		if (!tev->event)
+			goto errout;
+	}
+
+	tev->nargs = pev->nargs;
+	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
+	if (!tev->args) {
+		err = -ENOMEM;
+		goto errout;
+	}
+	for (i = 0; i < tev->nargs; i++)
+		copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
+
+	return 1;
+
+errout:
+	if (*tevs) {
+		clear_probe_trace_events(*tevs, 1);
+		*tevs = NULL;
+	}
+	return err;
+}
+
 bool __weak arch__prefers_symtab(void) { return false; }
 
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
@@ -2620,6 +2751,10 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 		}
 	}
 
+	ret = try_to_find_absolute_address(pev, tevs);
+	if (ret > 0)
+		return ret;
+
 	if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
 		ret = find_probe_trace_events_from_map(pev, tevs);
 		if (ret > 0)
@@ -2787,3 +2922,22 @@ end:
 	return ret;
 }
 
+int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
+			    struct perf_probe_arg *pvar)
+{
+	tvar->value = strdup(pvar->var);
+	if (tvar->value == NULL)
+		return -ENOMEM;
+	if (pvar->type) {
+		tvar->type = strdup(pvar->type);
+		if (tvar->type == NULL)
+			return -ENOMEM;
+	}
+	if (pvar->name) {
+		tvar->name = strdup(pvar->name);
+		if (tvar->name == NULL)
+			return -ENOMEM;
+	} else
+		tvar->name = NULL;
+	return 0;
+}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 9c7b99e..de0dd13 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -61,6 +61,7 @@ struct perf_probe_point {
 	bool		retprobe;	/* Return probe flag */
 	char		*lazy_line;	/* Lazy matching pattern */
 	unsigned long	offset;		/* Offset from function entry */
+	unsigned long	abs_address;	/* Absolute address of the point */
 };
 
 /* Perf probe probing argument field chain */
@@ -162,4 +163,7 @@ int e_snprintf(char *str, size_t size, const char *format, ...)
 /* Maximum index number of event-name postfix */
 #define MAX_EVENT_INDEX	1024
 
+int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
+			    struct perf_probe_arg *pvar);
+
 #endif /*_PROBE_EVENT_H */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 4b1e074..5ab9cd6 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -553,24 +553,9 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
 	char buf[32], *ptr;
 	int ret = 0;
 
-	if (!is_c_varname(pf->pvar->var)) {
-		/* Copy raw parameters */
-		pf->tvar->value = strdup(pf->pvar->var);
-		if (pf->tvar->value == NULL)
-			return -ENOMEM;
-		if (pf->pvar->type) {
-			pf->tvar->type = strdup(pf->pvar->type);
-			if (pf->tvar->type == NULL)
-				return -ENOMEM;
-		}
-		if (pf->pvar->name) {
-			pf->tvar->name = strdup(pf->pvar->name);
-			if (pf->tvar->name == NULL)
-				return -ENOMEM;
-		} else
-			pf->tvar->name = NULL;
-		return 0;
-	}
+	/* Copy raw parameters */
+	if (!is_c_varname(pf->pvar->var))
+		return copy_to_probe_trace_arg(pf->tvar, pf->pvar);
 
 	if (pf->pvar->name)
 		pf->tvar->name = strdup(pf->pvar->name);
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/4] tracing/uprobes: Do not print '0x  (null)' when offset is 0
  2015-08-26  7:40 [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
                   ` (2 preceding siblings ...)
  2015-08-26  7:40 ` [PATCH v2 3/4] perf probe: Support probing at absolute address Wang Nan
@ 2015-08-26  7:40 ` Wang Nan
  2015-08-26 10:00   ` 平松雅巳 / HIRAMATU,MASAMI
  2015-08-26  9:12 ` [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address 平松雅巳 / HIRAMATU,MASAMI
  4 siblings, 1 reply; 11+ messages in thread
From: Wang Nan @ 2015-08-26  7:40 UTC (permalink / raw)
  To: acme, masami.hiramatsu.pt, rostedt
  Cc: mingo, namhyung, pi3orama, linux-kernel

When manually added uprobe point with zero address, 'uprobe_events' output
'(null)' instead of 0x00000000:

 # echo p:probe_libc/abs_0 /path/to/lib.bin:0x0 arg1=%ax > \
            /sys/kernel/debug/tracing/uprobe_events

 # cat /sys/kernel/debug/tracing/uprobe_events
   p:probe_libc/abs_0 /path/to/lib.bin:0x          (null) arg1=%ax

This patch fixes this behavior:

 # cat /sys/kernel/debug/tracing/uprobe_events
 p:probe_libc/abs_0 /path/to/lib.bin:0x0000000000000000

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/trace_uprobe.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index f97479f..d2f6d0b 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -601,7 +601,22 @@ static int probes_seq_show(struct seq_file *m, void *v)
 
 	seq_printf(m, "%c:%s/%s", c, tu->tp.call.class->system,
 			trace_event_name(&tu->tp.call));
-	seq_printf(m, " %s:0x%p", tu->filename, (void *)tu->offset);
+	seq_printf(m, " %s:", tu->filename);
+
+	/* Don't print "0x  (null)" when offset is 0 */
+	if (tu->offset) {
+		seq_printf(m, "0x%p", (void *)tu->offset);
+	} else {
+		switch (sizeof(void *)) {
+		case 4:
+			seq_printf(m, "0x00000000");
+			break;
+		case 8:
+		default:
+			seq_printf(m, "0x0000000000000000");
+			break;
+		}
+	}
 
 	for (i = 0; i < tu->tp.nr_args; i++)
 		seq_printf(m, " %s=%s", tu->tp.args[i].name, tu->tp.args[i].comm);
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* RE: [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address
  2015-08-26  7:40 [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
                   ` (3 preceding siblings ...)
  2015-08-26  7:40 ` [PATCH v2 4/4] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
@ 2015-08-26  9:12 ` 平松雅巳 / HIRAMATU,MASAMI
  4 siblings, 0 replies; 11+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26  9:12 UTC (permalink / raw)
  To: 'Wang Nan', acme, rostedt; +Cc: mingo, namhyung, linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1613 bytes --]

> From: Wang Nan [mailto:wangnan0@huawei.com]
> 
> The goal of these 4 patches is to allow perf probing at absolute address
> for uprobes and kprobes. During the development several small problem in
> 'perf probe -l' is found and fixed.
> 
> Patch 1 has already acked by Masami Hiramatsu.
> 
> Patch 2 fixes a problem about zero address in perf side.
> 
> Patch 3 is the main patch of these 4. It allows following command:
> 
>  # perf probe /lib/x86_64-linux-gnu/libc-2.19.so 0xeb860
> 
>  Different from v1, no extra '+' is required.

Yeah, this seems better for me. Since '+' has double meanings "positive value" and
"add something", I think it's not good for this context.

> 
> Patch 4 is a kernel side patch which fixes a small problem in uprobe_event
> that, if address is 0, uprobe_events reports '0x  (null)'. It is independent
> from the other patches.

Oops, right.

Thanks!

> 
> Wang Nan (4):
>   perf probe: Prevent segfault when reading probe point with absolute
>     address
>   perf probe: Fix list result when address is zero
>   perf probe: Support probing at absolute address
>   tracing/uprobes: Do not print '0x  (null)' when offset is 0
> 
>  kernel/trace/trace_uprobe.c    |  17 +++-
>  tools/perf/util/probe-event.c  | 210 +++++++++++++++++++++++++++++++++++++----
>  tools/perf/util/probe-event.h  |   4 +
>  tools/perf/util/probe-finder.c |  21 +----
>  4 files changed, 216 insertions(+), 36 deletions(-)
> 
> --
> 1.8.3.4

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH v2 2/4] perf probe: Fix list result when address is zero
  2015-08-26  7:40 ` [PATCH v2 2/4] perf probe: Fix list result when address is zero Wang Nan
@ 2015-08-26  9:29   ` 平松雅巳 / HIRAMATU,MASAMI
  2015-08-26  9:43     ` Wangnan (F)
  0 siblings, 1 reply; 11+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26  9:29 UTC (permalink / raw)
  To: 'Wang Nan', acme, rostedt
  Cc: mingo, namhyung, linux-kernel, pi3orama, sysp-manager

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3426 bytes --]

> From: Wang Nan [mailto:wangnan0@huawei.com]
> 
> When manually added uprobe point with zero address, 'perf probe -l'
> reports error. For example:
> 
>  # echo p:probe_libc/abs_0 /path/to/lib.bin:0x0 arg1=%ax > \
>            /sys/kernel/debug/tracing/uprobe_events
> 
>  # perf probe -l
>  Error: Failed to show event list.
> 
> Probing at 0x0 is possible and useful when lib.bin is not a normal
> shared object but is manually mapped. However, in this case kernel
> report:
> 
>  # cat /sys/kernel/debug/tracing/uprobe_events
>  p:probe_libc/abs_0 /tmp/oxygen_root/lib64/libc-2.18.so:0x          (null) arg1=%ax
> 
> This patch supports the above kernel output.

Former part is OK to me.

> 
> In addition, this patch also fixes convert_to_perf_probe_point() that,
> if failed to find probe point from both of dwarf and map, in all cases
> pp->function should be filled with a strdup() result, or the following
> ENOMEM error code is incorrect. Remove !tp->module && !is_kprobe
> condition so always use address to build function name if symbol is not
> found.

No, I think this should be included in 3/4, since until that perf probe
doesn't support absolute address on kernel.

Thank you,

> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> ---
>  tools/perf/util/probe-event.c | 30 ++++++++++++++++++++++++++----
>  1 file changed, 26 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index ef325a2..3ce223d 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1521,9 +1521,31 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
>  	} else
>  		p = argv[1];
>  	fmt1_str = strtok_r(p, "+", &fmt);
> -	if (fmt1_str[0] == '0')	/* only the address started with 0x */
> -		tp->address = strtoul(fmt1_str, NULL, 0);
> -	else {
> +	/* only the address started with 0x */
> +	if (fmt1_str[0] == '0')	{
> +		/*
> +		 * Fix a special case:
> +		 * if address == 0, kernel reports something like:
> +		 * p:probe_libc/abs_0 /lib/libc-2.18.so:0x          (null) arg1=%ax
> +		 * Newer kernel may fix that, but we want to
> +		 * support old kernel also.
> +		 */
> +		if (strcmp(fmt1_str, "0x") == 0) {
> +			if (!argv[2] || strcmp(argv[2], "(null)")) {
> +				ret = -EINVAL;
> +				goto out;
> +			}
> +			tp->address = 0;
> +
> +			free(argv[2]);
> +			for (i = 2; argv[i + 1] != NULL; i++)
> +				argv[i] = argv[i + 1];
> +
> +			argv[i] = NULL;
> +			argc -= 1;
> +		} else
> +			tp->address = strtoul(fmt1_str, NULL, 0);
> +	} else {
>  		/* Only the symbol-based probe has offset */
>  		tp->symbol = strdup(fmt1_str);
>  		if (tp->symbol == NULL) {
> @@ -1868,7 +1890,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,
>  	if (tp->symbol) {
>  		pp->function = strdup(tp->symbol);
>  		pp->offset = tp->offset;
> -	} else if (!tp->module && !is_kprobe) {
> +	} else {
>  		ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
>  		if (ret < 0)
>  			return ret;
> --
> 1.8.3.4

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 2/4] perf probe: Fix list result when address is zero
  2015-08-26  9:29   ` 平松雅巳 / HIRAMATU,MASAMI
@ 2015-08-26  9:43     ` Wangnan (F)
  2015-08-26 10:48       ` 平松雅巳 / HIRAMATU,MASAMI
  0 siblings, 1 reply; 11+ messages in thread
From: Wangnan (F) @ 2015-08-26  9:43 UTC (permalink / raw)
  To: 平松雅巳 / HIRAMATU,MASAMI, acme, rostedt
  Cc: mingo, namhyung, linux-kernel, pi3orama, sysp-manager



On 2015/8/26 17:29, 平松雅巳 / HIRAMATU,MASAMI wrote:
>> From: Wang Nan [mailto:wangnan0@huawei.com]
>>
>> When manually added uprobe point with zero address, 'perf probe -l'
>> reports error. For example:
>>
>>   # echo p:probe_libc/abs_0 /path/to/lib.bin:0x0 arg1=%ax > \
>>             /sys/kernel/debug/tracing/uprobe_events
>>
>>   # perf probe -l
>>   Error: Failed to show event list.
>>
>> Probing at 0x0 is possible and useful when lib.bin is not a normal
>> shared object but is manually mapped. However, in this case kernel
>> report:
>>
>>   # cat /sys/kernel/debug/tracing/uprobe_events
>>   p:probe_libc/abs_0 /tmp/oxygen_root/lib64/libc-2.18.so:0x          (null) arg1=%ax
>>
>> This patch supports the above kernel output.
> Former part is OK to me.
>
>> In addition, this patch also fixes convert_to_perf_probe_point() that,
>> if failed to find probe point from both of dwarf and map, in all cases
>> pp->function should be filled with a strdup() result, or the following
>> ENOMEM error code is incorrect. Remove !tp->module && !is_kprobe
>> condition so always use address to build function name if symbol is not
>> found.
> No, I think this should be included in 3/4, since until that perf probe
> doesn't support absolute address on kernel.

This is for manually introduced probing points.

convert_to_perf_probe_point is called by:

perf probe -l -> show_perf_probe_events -> __show_perf_probe_events --> convert_to_perf_probe_event

If there is a manually inserted probing point there, 'perf probe -l' reports an error.

Here is the result if I remove the second part:

$ git log --oneline  # I'm in 2/4
aae2c2c perf probe: Fix list result when address is zero
931dff5 perf probe: Prevent segfault when reading probe point with 
absolute address
...

$ git diff    # remove the second part
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 926bcec..de2c27e 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1888,7 +1888,7 @@ static int convert_to_perf_probe_point(struct 
probe_trace_point *tp,
         if (tp->symbol) {
                 pp->function = strdup(tp->symbol);
                 pp->offset = tp->offset;
-       } else {
+       } else if (!tp->module && !is_kprobe) {
                 ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
                 if (ret < 0)
                         return ret;


...
# echo 'p:probe_libc/abs_5 /lib64/libc.so.6:0x5' > 
/sys/kernel/debug/tracing/uprobe_events
# cat /sys/kernel/debug/tracing/uprobe_events
  p:probe_libc/abs_5 /lib64/libc.so.6:0x0000000000000005
# perf probe -l
   Error: Failed to show event list

Then add it back:

$ git reset --hard HEAD
...
# perf probe -l
  probe_libc:abs_5     (on 0x5 in /lib64/libc.so.6)

Thank you.

> Thank you,
>
>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
>> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
>> Cc: Ingo Molnar <mingo@redhat.com>
>> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
>> Cc: Namhyung Kim <namhyung@kernel.org>
>> Cc: Steven Rostedt <rostedt@goodmis.org>
>> ---
>>   tools/perf/util/probe-event.c | 30 ++++++++++++++++++++++++++----
>>   1 file changed, 26 insertions(+), 4 deletions(-)
>>
>> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
>> index ef325a2..3ce223d 100644
>> --- a/tools/perf/util/probe-event.c
>> +++ b/tools/perf/util/probe-event.c
>> @@ -1521,9 +1521,31 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
>>   	} else
>>   		p = argv[1];
>>   	fmt1_str = strtok_r(p, "+", &fmt);
>> -	if (fmt1_str[0] == '0')	/* only the address started with 0x */
>> -		tp->address = strtoul(fmt1_str, NULL, 0);
>> -	else {
>> +	/* only the address started with 0x */
>> +	if (fmt1_str[0] == '0')	{
>> +		/*
>> +		 * Fix a special case:
>> +		 * if address == 0, kernel reports something like:
>> +		 * p:probe_libc/abs_0 /lib/libc-2.18.so:0x          (null) arg1=%ax
>> +		 * Newer kernel may fix that, but we want to
>> +		 * support old kernel also.
>> +		 */
>> +		if (strcmp(fmt1_str, "0x") == 0) {
>> +			if (!argv[2] || strcmp(argv[2], "(null)")) {
>> +				ret = -EINVAL;
>> +				goto out;
>> +			}
>> +			tp->address = 0;
>> +
>> +			free(argv[2]);
>> +			for (i = 2; argv[i + 1] != NULL; i++)
>> +				argv[i] = argv[i + 1];
>> +
>> +			argv[i] = NULL;
>> +			argc -= 1;
>> +		} else
>> +			tp->address = strtoul(fmt1_str, NULL, 0);
>> +	} else {
>>   		/* Only the symbol-based probe has offset */
>>   		tp->symbol = strdup(fmt1_str);
>>   		if (tp->symbol == NULL) {
>> @@ -1868,7 +1890,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,
>>   	if (tp->symbol) {
>>   		pp->function = strdup(tp->symbol);
>>   		pp->offset = tp->offset;
>> -	} else if (!tp->module && !is_kprobe) {
>> +	} else {
>>   		ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
>>   		if (ret < 0)
>>   			return ret;
>> --
>> 1.8.3.4



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* RE: [PATCH v2 3/4] perf probe: Support probing at absolute address
  2015-08-26  7:40 ` [PATCH v2 3/4] perf probe: Support probing at absolute address Wang Nan
@ 2015-08-26  9:49   ` 平松雅巳 / HIRAMATU,MASAMI
  0 siblings, 0 replies; 11+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26  9:49 UTC (permalink / raw)
  To: 'Wang Nan', acme, rostedt
  Cc: mingo, namhyung, pi3orama, linux-kernel, sysp-manager

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 11803 bytes --]

> From: Wang Nan [mailto:wangnan0@huawei.com]
> 
> It should be useful to allow 'perf probe' probe at absolute offset of
> a target. For example, when (u)probing at a instruction of a shared
> object in a embedded system where debuginfo is not avaliable but we
> know the offset of that instruction by manually digging.
> 
> This patch enables following perf probe command syntax:
> 
>  # perf probe 0xffffffff811e6615
> 
> And
> 
>  # perf probe /lib/x86_64-linux-gnu/libc-2.19.so 0xeb860
> 
> In the above example, we don't need a anchor symbol, so it is possible
> to compute absolute addresses using other methods and then use
> 'perf probe' to create the probing points.

OK, this looks good :)

> 
> This patch also fix a bug that, when offset is provided but function is
> skipped, parse_perf_probe_point() will give function a "" string, so
> the checking code at the end of this function is not used. For example:
> 
>  # perf probe +0x1234
>  Failed to find symbol  in kernel
>    Error: Failed to add events.
> 
> After this patch:
> 
>  # perf probe +0x1234
>  Semantic error :Offset requires an entry function.
>    Error: Command Parse Error.

Hmm, could you please split the bugfix from feature addition patch?

Thank you,

> 
> v1 -> v2:
>   Drop the leading '+' in cmdline;
>   Allow uprobing at offset 0x0;
>   Improve 'perf probe -l' result when uprobe at area without debuginfo.
> 
> Test result:
> 
>  # perf probe 0xffffffff8119d175 %ax
>  # perf probe sys_write %ax
>  # perf probe /lib64/libc-2.18.so 0x0 %ax
>  # perf probe /lib64/libc-2.18.so 0x5 %ax
>  # perf probe /lib64/libc-2.18.so 0xd8e40 %ax
>  # perf probe /lib64/libc-2.18.so __write %ax
>  # perf probe /lib64/libc-2.18.so 0xd8e49 %ax
>  # cat /sys/kernel/debug/tracing/uprobe_events
> 
>  p:probe_libc/abs_0 /lib64/libc-2.18.so:0x          (null) arg1=%ax
>  p:probe_libc/abs_5 /lib64/libc-2.18.so:0x0000000000000005 arg1=%ax
>  p:probe_libc/abs_d8e40 /lib64/libc-2.18.so:0x00000000000d8e40 arg1=%ax
>  p:probe_libc/__write /lib64/libc-2.18.so:0x00000000000d8e40 arg1=%ax
>  p:probe_libc/abs_d8e49 /lib64/libc-2.18.so:0x00000000000d8e49 arg1=%ax
> 
>  # cat /sys/kernel/debug/tracing/kprobe_events
> 
>  p:probe/abs_ffffffff8119d175 0xffffffff8119d175 arg1=%ax
>  p:probe/sys_write _text+1692016 arg1=%ax
> 
>  # perf probe -l
> 
>  Failed to find debug information for address 5
>    probe:abs_ffffffff8119d175 (on sys_write+5 with arg1)
>    probe:sys_write      (on sys_write with arg1)
>    probe_libc:__write   (on @unix/syscall-template.S:81 in /lib64/libc-2.18.so with arg1)
>    probe_libc:abs_0     (on 0x0 in /lib64/libc-2.18.so with arg1)
>    probe_libc:abs_5     (on 0x5 in /lib64/libc-2.18.so with arg1)
>    probe_libc:abs_d8e40 (on @unix/syscall-template.S:81 in /lib64/libc-2.18.so with arg1)
>    probe_libc:abs_d8e49 (on __GI___libc_write+9 in /lib64/libc-2.18.so with arg1)
> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> ---
>  tools/perf/util/probe-event.c  | 172 ++++++++++++++++++++++++++++++++++++++---
>  tools/perf/util/probe-event.h  |   4 +
>  tools/perf/util/probe-finder.c |  21 +----
>  3 files changed, 170 insertions(+), 27 deletions(-)
> 
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 3ce223d..b94a8d7 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1196,15 +1196,37 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
>  		*ptr++ = '\0';
>  	}
> 
> -	tmp = strdup(arg);
> -	if (tmp == NULL)
> -		return -ENOMEM;
> +	if (arg[0] == '\0')
> +		tmp = NULL;
> +	else {
> +		tmp = strdup(arg);
> +		if (tmp == NULL)
> +			return -ENOMEM;
> +	}
> 
>  	if (file_spec)
>  		pp->file = tmp;
> -	else
> +	else {
>  		pp->function = tmp;
> 
> +		/*
> +		 * Keep pp->function even if this is absolute address,
> +		 * so it can mark whether abs_address is valid.
> +		 * Which make 'perf probe lib.bin 0x0' possible.
> +		 *
> +		 * Note that checking length of tmp is not needed
> +		 * because when we access tmp[1] we know tmp[0] is '0',
> +		 * so tmp[1] should always valid (but could be '\0').
> +		 */
> +		if (tmp && !strncmp(tmp, "0x", 2)) {
> +			pp->abs_address = strtoul(pp->function, &tmp, 0);
> +			if (*tmp != '\0') {
> +				semantic_error("Invalid absolute address.\n");
> +				return -EINVAL;
> +			}
> +		}
> +	}
> +
>  	/* Parse other options */
>  	while (ptr) {
>  		arg = ptr;
> @@ -1802,14 +1824,29 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
>  	if (len <= 0)
>  		goto error;
> 
> -	/* Uprobes must have tp->address and tp->module */
> -	if (tev->uprobes && (!tp->address || !tp->module))
> +	/* Uprobes must have tp->module */
> +	if (tev->uprobes && !tp->module)
>  		goto error;
> +	/*
> +	 * If tp->address == 0, then this point must be a
> +	 * absolute address uprobe.
> +	 * try_to_find_absolute_address() should have made
> +	 * tp->symbol to "0x0".
> +	 */
> +	if (tev->uprobes && !tp->address) {
> +		if (!tp->symbol || strcmp(tp->symbol, "0x0"))
> +			goto error;
> +	}
> 
>  	/* Use the tp->address for uprobes */
>  	if (tev->uprobes)
>  		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx",
>  				 tp->module, tp->address);
> +	else if (!strncmp(tp->symbol, "0x", 2))
> +		/* Absolute address. See try_to_find_absolute_address() */
> +		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s0x%lx",
> +				 tp->module ?: "", tp->module ? ":" : "",
> +				 tp->address);
>  	else
>  		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu",
>  				 tp->module ?: "", tp->module ? ":" : "",
> @@ -1872,8 +1909,8 @@ out:
>  }
> 
>  static int convert_to_perf_probe_point(struct probe_trace_point *tp,
> -					struct perf_probe_point *pp,
> -					bool is_kprobe)
> +				       struct perf_probe_point *pp,
> +				       bool is_kprobe)
>  {
>  	char buf[128];
>  	int ret;
> @@ -2334,7 +2371,9 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
>  	if (pev->event)
>  		event = pev->event;
>  	else
> -		if (pev->point.function && !strisglob(pev->point.function))
> +		if (pev->point.function &&
> +			(strncmp(pev->point.function, "0x", 2) != 0) &&
> +			!strisglob(pev->point.function))
>  			event = pev->point.function;
>  		else
>  			event = tev->point.realname;
> @@ -2604,6 +2643,98 @@ err_out:
>  	goto out;
>  }
> 
> +static int try_to_find_absolute_address(struct perf_probe_event *pev,
> +					struct probe_trace_event **tevs)
> +{
> +	struct perf_probe_point *pp = &pev->point;
> +	struct probe_trace_event *tev;
> +	struct probe_trace_point *tp;
> +	int i, err;
> +
> +	if (!(pev->point.function && !strncmp(pev->point.function, "0x", 2)))
> +		return -EINVAL;
> +	if (perf_probe_event_need_dwarf(pev))
> +		return -EINVAL;
> +
> +	/*
> +	 * This is 'perf probe /lib/libc.so 0xabcd'. Try to probe at
> +	 * absolute address.
> +	 *
> +	 * Only one tev can be generated by this.
> +	 */
> +	*tevs = zalloc(sizeof(*tev));
> +	if (!*tevs)
> +		return -ENOMEM;
> +
> +	tev = *tevs;
> +	tp = &tev->point;
> +
> +	/*
> +	 * Don't use tp->offset, use address directly, because
> +	 * in synthesize_probe_trace_command() address cannot be
> +	 * zero.
> +	 */
> +	tp->address = pev->point.abs_address;
> +	tp->retprobe = pp->retprobe;
> +	tev->uprobes = pev->uprobes;
> +
> +	err = -ENOMEM;
> +	/*
> +	 * Give it a '0x' leading symbol name.
> +	 * In __add_probe_trace_events, a NULL symbol is interpreted as
> +	 * invalud.
> +	 */
> +	if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
> +		goto errout;
> +
> +	/* For kprobe, check range */
> +	if ((!tev->uprobes) &&
> +	    (kprobe_warn_out_range(tev->point.symbol,
> +				   tev->point.address))) {
> +		err = -EACCES;
> +		goto errout;
> +	}
> +
> +	if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
> +		goto errout;
> +
> +	if (pev->target) {
> +		tp->module = strdup(pev->target);
> +		if (!tp->module)
> +			goto errout;
> +	}
> +
> +	if (tev->group) {
> +		tev->group = strdup(pev->group);
> +		if (!tev->group)
> +			goto errout;
> +	}
> +
> +	if (pev->event) {
> +		tev->event = strdup(pev->event);
> +		if (!tev->event)
> +			goto errout;
> +	}
> +
> +	tev->nargs = pev->nargs;
> +	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
> +	if (!tev->args) {
> +		err = -ENOMEM;
> +		goto errout;
> +	}
> +	for (i = 0; i < tev->nargs; i++)
> +		copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
> +
> +	return 1;
> +
> +errout:
> +	if (*tevs) {
> +		clear_probe_trace_events(*tevs, 1);
> +		*tevs = NULL;
> +	}
> +	return err;
> +}
> +
>  bool __weak arch__prefers_symtab(void) { return false; }
> 
>  static int convert_to_probe_trace_events(struct perf_probe_event *pev,
> @@ -2620,6 +2751,10 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
>  		}
>  	}
> 
> +	ret = try_to_find_absolute_address(pev, tevs);
> +	if (ret > 0)
> +		return ret;
> +
>  	if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
>  		ret = find_probe_trace_events_from_map(pev, tevs);
>  		if (ret > 0)
> @@ -2787,3 +2922,22 @@ end:
>  	return ret;
>  }
> 
> +int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
> +			    struct perf_probe_arg *pvar)
> +{
> +	tvar->value = strdup(pvar->var);
> +	if (tvar->value == NULL)
> +		return -ENOMEM;
> +	if (pvar->type) {
> +		tvar->type = strdup(pvar->type);
> +		if (tvar->type == NULL)
> +			return -ENOMEM;
> +	}
> +	if (pvar->name) {
> +		tvar->name = strdup(pvar->name);
> +		if (tvar->name == NULL)
> +			return -ENOMEM;
> +	} else
> +		tvar->name = NULL;
> +	return 0;
> +}
> diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> index 9c7b99e..de0dd13 100644
> --- a/tools/perf/util/probe-event.h
> +++ b/tools/perf/util/probe-event.h
> @@ -61,6 +61,7 @@ struct perf_probe_point {
>  	bool		retprobe;	/* Return probe flag */
>  	char		*lazy_line;	/* Lazy matching pattern */
>  	unsigned long	offset;		/* Offset from function entry */
> +	unsigned long	abs_address;	/* Absolute address of the point */
>  };
> 
>  /* Perf probe probing argument field chain */
> @@ -162,4 +163,7 @@ int e_snprintf(char *str, size_t size, const char *format, ...)
>  /* Maximum index number of event-name postfix */
>  #define MAX_EVENT_INDEX	1024
> 
> +int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
> +			    struct perf_probe_arg *pvar);
> +
>  #endif /*_PROBE_EVENT_H */
> diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> index 4b1e074..5ab9cd6 100644
> --- a/tools/perf/util/probe-finder.c
> +++ b/tools/perf/util/probe-finder.c
> @@ -553,24 +553,9 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
>  	char buf[32], *ptr;
>  	int ret = 0;
> 
> -	if (!is_c_varname(pf->pvar->var)) {
> -		/* Copy raw parameters */
> -		pf->tvar->value = strdup(pf->pvar->var);
> -		if (pf->tvar->value == NULL)
> -			return -ENOMEM;
> -		if (pf->pvar->type) {
> -			pf->tvar->type = strdup(pf->pvar->type);
> -			if (pf->tvar->type == NULL)
> -				return -ENOMEM;
> -		}
> -		if (pf->pvar->name) {
> -			pf->tvar->name = strdup(pf->pvar->name);
> -			if (pf->tvar->name == NULL)
> -				return -ENOMEM;
> -		} else
> -			pf->tvar->name = NULL;
> -		return 0;
> -	}
> +	/* Copy raw parameters */
> +	if (!is_c_varname(pf->pvar->var))
> +		return copy_to_probe_trace_arg(pf->tvar, pf->pvar);
> 
>  	if (pf->pvar->name)
>  		pf->tvar->name = strdup(pf->pvar->name);
> --
> 1.8.3.4

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH v2 4/4] tracing/uprobes: Do not print '0x  (null)' when offset is 0
  2015-08-26  7:40 ` [PATCH v2 4/4] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
@ 2015-08-26 10:00   ` 平松雅巳 / HIRAMATU,MASAMI
  0 siblings, 0 replies; 11+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26 10:00 UTC (permalink / raw)
  To: 'Wang Nan', acme, rostedt
  Cc: mingo, namhyung, pi3orama, linux-kernel, sysp-manager

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2117 bytes --]

> From: Wang Nan [mailto:wangnan0@huawei.com]
> 
> When manually added uprobe point with zero address, 'uprobe_events' output
> '(null)' instead of 0x00000000:
> 
>  # echo p:probe_libc/abs_0 /path/to/lib.bin:0x0 arg1=%ax > \
>             /sys/kernel/debug/tracing/uprobe_events
> 
>  # cat /sys/kernel/debug/tracing/uprobe_events
>    p:probe_libc/abs_0 /path/to/lib.bin:0x          (null) arg1=%ax
> 
> This patch fixes this behavior:
> 
>  # cat /sys/kernel/debug/tracing/uprobe_events
>  p:probe_libc/abs_0 /path/to/lib.bin:0x0000000000000000


Looks Good to me :)

Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

Thanks!

> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> ---
>  kernel/trace/trace_uprobe.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
> index f97479f..d2f6d0b 100644
> --- a/kernel/trace/trace_uprobe.c
> +++ b/kernel/trace/trace_uprobe.c
> @@ -601,7 +601,22 @@ static int probes_seq_show(struct seq_file *m, void *v)
> 
>  	seq_printf(m, "%c:%s/%s", c, tu->tp.call.class->system,
>  			trace_event_name(&tu->tp.call));
> -	seq_printf(m, " %s:0x%p", tu->filename, (void *)tu->offset);
> +	seq_printf(m, " %s:", tu->filename);
> +
> +	/* Don't print "0x  (null)" when offset is 0 */
> +	if (tu->offset) {
> +		seq_printf(m, "0x%p", (void *)tu->offset);
> +	} else {
> +		switch (sizeof(void *)) {
> +		case 4:
> +			seq_printf(m, "0x00000000");
> +			break;
> +		case 8:
> +		default:
> +			seq_printf(m, "0x0000000000000000");
> +			break;
> +		}
> +	}
> 
>  	for (i = 0; i < tu->tp.nr_args; i++)
>  		seq_printf(m, " %s=%s", tu->tp.args[i].name, tu->tp.args[i].comm);
> --
> 1.8.3.4

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH v2 2/4] perf probe: Fix list result when address is zero
  2015-08-26  9:43     ` Wangnan (F)
@ 2015-08-26 10:48       ` 平松雅巳 / HIRAMATU,MASAMI
  0 siblings, 0 replies; 11+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26 10:48 UTC (permalink / raw)
  To: 'Wangnan (F)', acme, rostedt
  Cc: mingo, namhyung, linux-kernel, pi3orama, sysp-manager

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3249 bytes --]

> From: Wangnan (F) [mailto:wangnan0@huawei.com]
> >>
> >> When manually added uprobe point with zero address, 'perf probe -l'
> >> reports error. For example:
> >>
> >>   # echo p:probe_libc/abs_0 /path/to/lib.bin:0x0 arg1=%ax > \
> >>             /sys/kernel/debug/tracing/uprobe_events
> >>
> >>   # perf probe -l
> >>   Error: Failed to show event list.
> >>
> >> Probing at 0x0 is possible and useful when lib.bin is not a normal
> >> shared object but is manually mapped. However, in this case kernel
> >> report:
> >>
> >>   # cat /sys/kernel/debug/tracing/uprobe_events
> >>   p:probe_libc/abs_0 /tmp/oxygen_root/lib64/libc-2.18.so:0x          (null) arg1=%ax
> >>
> >> This patch supports the above kernel output.
> > Former part is OK to me.
> >
> >> In addition, this patch also fixes convert_to_perf_probe_point() that,
> >> if failed to find probe point from both of dwarf and map, in all cases
> >> pp->function should be filled with a strdup() result, or the following
> >> ENOMEM error code is incorrect. Remove !tp->module && !is_kprobe
> >> condition so always use address to build function name if symbol is not
> >> found.
> > No, I think this should be included in 3/4, since until that perf probe
> > doesn't support absolute address on kernel.
> 
> This is for manually introduced probing points.
> 
> convert_to_perf_probe_point is called by:
> 
> perf probe -l -> show_perf_probe_events -> __show_perf_probe_events --> convert_to_perf_probe_event
> 
> If there is a manually inserted probing point there, 'perf probe -l' reports an error.
> 
> Here is the result if I remove the second part:
> 
> $ git log --oneline  # I'm in 2/4
> aae2c2c perf probe: Fix list result when address is zero
> 931dff5 perf probe: Prevent segfault when reading probe point with
> absolute address
> ...
> 
> $ git diff    # remove the second part
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 926bcec..de2c27e 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1888,7 +1888,7 @@ static int convert_to_perf_probe_point(struct
> probe_trace_point *tp,
>          if (tp->symbol) {
>                  pp->function = strdup(tp->symbol);
>                  pp->offset = tp->offset;
> -       } else {
> +       } else if (!tp->module && !is_kprobe) {
>                  ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
>                  if (ret < 0)
>                          return ret;
> 
> 
> ...
> # echo 'p:probe_libc/abs_5 /lib64/libc.so.6:0x5' >
> /sys/kernel/debug/tracing/uprobe_events
> # cat /sys/kernel/debug/tracing/uprobe_events
>   p:probe_libc/abs_5 /lib64/libc.so.6:0x0000000000000005
> # perf probe -l
>    Error: Failed to show event list
> 
> Then add it back:
> 
> $ git reset --hard HEAD
> ...
> # perf probe -l
>   probe_libc:abs_5     (on 0x5 in /lib64/libc.so.6)

Hmm, OK, then this should be in the 1/4 or splitted as an independent patch,
because this part it is not "when address is zero", just support showing
absolute address probes on user applications.

Thank you,

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-08-26 10:48 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-26  7:40 [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
2015-08-26  7:40 ` [PATCH v2 1/4] perf probe: Prevent segfault when reading probe point with " Wang Nan
2015-08-26  7:40 ` [PATCH v2 2/4] perf probe: Fix list result when address is zero Wang Nan
2015-08-26  9:29   ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-26  9:43     ` Wangnan (F)
2015-08-26 10:48       ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-26  7:40 ` [PATCH v2 3/4] perf probe: Support probing at absolute address Wang Nan
2015-08-26  9:49   ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-26  7:40 ` [PATCH v2 4/4] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
2015-08-26 10:00   ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-26  9:12 ` [PATCH v2 0/4] perf probe, tracing/uprobes: Support probing at absolute address 平松雅巳 / HIRAMATU,MASAMI

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).