* [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address
@ 2015-08-26 10:57 Wang Nan
2015-08-26 10:57 ` [PATCH v3 1/6] perf probe: Prevent segfault when reading probe point with " Wang Nan
` (6 more replies)
0 siblings, 7 replies; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
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 v2 can be found from [1].
Following Masami's suggestion, v3 splits bugfixs into their own
patches instead of merging with feature.
In this series, patch 1/6 to 4/6 are small bugfix. Patch 5/6 is the main
patch which support the new syntax. Patch 6/6 is a kernel side small bugfix.
Patch 1/6 and 6/6 have already been acked by Masami Hiramatsu.
[1] http://lkml.kernel.org/r/1440574825-221187-1-git-send-email-wangnan0@huawei.com
Wang Nan (6):
perf probe: Prevent segfault when reading probe point with absolute
address
perf probe: Fix list result when symbol can't be found
perf probe: Fix list result when address is zero
perf probe: Fix error reported when offset without function
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] 18+ messages in thread
* [PATCH v3 1/6] perf probe: Prevent segfault when reading probe point with absolute address
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
@ 2015-08-26 10:57 ` Wang Nan
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when neither dwarf nor map can't find symbol Wang Nan
` (5 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
'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 f07374b..6c7e538 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -515,7 +515,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;
@@ -1815,17 +1815,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] 18+ messages in thread
* [PATCH v3 2/6] perf probe: Fix list result when neither dwarf nor map can't find symbol
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
2015-08-26 10:57 ` [PATCH v3 1/6] perf probe: Prevent segfault when reading probe point with " Wang Nan
@ 2015-08-26 10:57 ` Wang Nan
2015-08-26 11:03 ` Wangnan (F)
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when symbol can't be found Wang Nan
` (4 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
'perf probe -l' reports error if it is unable find symbol through
address. Here is an example.
# 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
Also, this situation triggers a logical inconsistency in
convert_to_perf_probe_point() that, it returns ENOMEM but actually
it never try strdup().
This patch removes !tp->module && !is_kprobe condition, so it
always uses address to build function name if symbol not found.
Test result:
# perf probe -l
probe_libc:abs_5 (on 0x5 in /lib64/libc.so.6)
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 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6c7e538..f7bacbb 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1866,7 +1866,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] 18+ messages in thread
* [PATCH v3 2/6] perf probe: Fix list result when symbol can't be found
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
2015-08-26 10:57 ` [PATCH v3 1/6] perf probe: Prevent segfault when reading probe point with " Wang Nan
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when neither dwarf nor map can't find symbol Wang Nan
@ 2015-08-26 10:57 ` Wang Nan
2015-08-26 12:27 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:41 ` [tip:perf/core] perf probe: Fix list result when symbol can' t " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 3/6] perf probe: Fix list result when address is zero Wang Nan
` (3 subsequent siblings)
6 siblings, 2 replies; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
'perf probe -l' reports error if it is unable find symbol through
address. Here is an example.
# 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
Also, this situation triggers a logical inconsistency in
convert_to_perf_probe_point() that, it returns ENOMEM but actually
it never try strdup().
This patch removes !tp->module && !is_kprobe condition, so it
always uses address to build function name if symbol not found.
Test result:
# perf probe -l
probe_libc:abs_5 (on 0x5 in /lib64/libc.so.6)
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 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6c7e538..f7bacbb 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1866,7 +1866,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] 18+ messages in thread
* [PATCH v3 3/6] perf probe: Fix list result when address is zero
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
` (2 preceding siblings ...)
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when symbol can't be found Wang Nan
@ 2015-08-26 10:57 ` Wang Nan
2015-08-26 12:14 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 4/6] perf probe: Fix error reported when offset without function Wang Nan
` (2 subsequent siblings)
6 siblings, 2 replies; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
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 /path/to/lib.bin:0x (null) arg1=%ax
This patch supports the above kernel output.
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 | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f7bacbb..926bcec 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1519,9 +1519,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) {
--
1.8.3.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 4/6] perf probe: Fix error reported when offset without function
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
` (3 preceding siblings ...)
2015-08-26 10:57 ` [PATCH v3 3/6] perf probe: Fix list result when address is zero Wang Nan
@ 2015-08-26 10:57 ` Wang Nan
2015-08-26 12:21 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 5/6] perf probe: Support probing at absolute address Wang Nan
2015-08-26 10:57 ` [PATCH v3 6/6] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
6 siblings, 2 replies; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
This patch fixes a bug that, when offset is provided but function is
lost, parse_perf_probe_point() will give a "" string as function name,
so the checking code at the end of parse_perf_probe_point() become useless.
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.
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 | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 926bcec..eaacb58 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1194,9 +1194,13 @@ 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;
--
1.8.3.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 5/6] perf probe: Support probing at absolute address
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
` (4 preceding siblings ...)
2015-08-26 10:57 ` [PATCH v3 4/6] perf probe: Fix error reported when offset without function Wang Nan
@ 2015-08-26 10:57 ` Wang Nan
2015-08-26 12:16 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 6/6] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
6 siblings, 2 replies; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
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.
v1 -> v2:
Drop the leading '+' in cmdline;
Allow uprobing at offset 0x0;
Improve 'perf probe -l' result when uprobe at area without debuginfo.
v2 -> v3:
Split bugfix to a separated patch.
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 | 162 +++++++++++++++++++++++++++++++++++++++--
tools/perf/util/probe-event.h | 4 +
tools/perf/util/probe-finder.c | 21 +-----
3 files changed, 163 insertions(+), 24 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index eaacb58..eb5f18b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1204,9 +1204,27 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
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;
@@ -1804,14 +1822,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 ? ":" : "",
@@ -1874,8 +1907,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;
@@ -2331,7 +2364,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;
@@ -2598,6 +2633,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,
@@ -2614,6 +2741,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)
@@ -2784,3 +2915,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 83ee95e..6e7ec68 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -59,6 +59,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 */
@@ -156,4 +157,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 7b80f8c..29c43c068 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] 18+ messages in thread
* [PATCH v3 6/6] tracing/uprobes: Do not print '0x (null)' when offset is 0
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
` (5 preceding siblings ...)
2015-08-26 10:57 ` [PATCH v3 5/6] perf probe: Support probing at absolute address Wang Nan
@ 2015-08-26 10:57 ` Wang Nan
2015-08-28 6:43 ` [tip:perf/core] " tip-bot for Wang Nan
6 siblings, 1 reply; 18+ messages in thread
From: Wang Nan @ 2015-08-26 10:57 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel, Wang Nan
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>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.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] 18+ messages in thread
* Re: [PATCH v3 2/6] perf probe: Fix list result when neither dwarf nor map can't find symbol
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when neither dwarf nor map can't find symbol Wang Nan
@ 2015-08-26 11:03 ` Wangnan (F)
0 siblings, 0 replies; 18+ messages in thread
From: Wangnan (F) @ 2015-08-26 11:03 UTC (permalink / raw)
To: acme, masami.hiramatsu.pt, rostedt
Cc: mingo, namhyung, pi3orama, lizefan, linux-kernel
Please ignore this one, and use the identical one with shorter title.
Sorry for the noisy.
On 2015/8/26 18:57, Wang Nan wrote:
> 'perf probe -l' reports error if it is unable find symbol through
> address. Here is an example.
>
> # 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
>
> Also, this situation triggers a logical inconsistency in
> convert_to_perf_probe_point() that, it returns ENOMEM but actually
> it never try strdup().
>
> This patch removes !tp->module && !is_kprobe condition, so it
> always uses address to build function name if symbol not found.
>
> Test result:
>
> # perf probe -l
> probe_libc:abs_5 (on 0x5 in /lib64/libc.so.6)
>
> 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 | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 6c7e538..f7bacbb 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1866,7 +1866,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;
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH v3 3/6] perf probe: Fix list result when address is zero
2015-08-26 10:57 ` [PATCH v3 3/6] perf probe: Fix list result when address is zero Wang Nan
@ 2015-08-26 12:14 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26 12:14 UTC (permalink / raw)
To: 'Wang Nan', acme@kernel.org, rostedt@goodmis.org
Cc: mingo@redhat.com, namhyung@kernel.org, pi3orama@163.com,
lizefan@huawei.com, linux-kernel@vger.kernel.org, sysp-manager
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2631 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 /path/to/lib.bin:0x (null) arg1=%ax
>
> This patch supports the above kernel output.
OK, 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>
> ---
> tools/perf/util/probe-event.c | 28 +++++++++++++++++++++++++---
> 1 file changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index f7bacbb..926bcec 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1519,9 +1519,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) {
> --
> 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] 18+ messages in thread
* RE: [PATCH v3 5/6] perf probe: Support probing at absolute address
2015-08-26 10:57 ` [PATCH v3 5/6] perf probe: Support probing at absolute address Wang Nan
@ 2015-08-26 12:16 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26 12:16 UTC (permalink / raw)
To: 'Wang Nan', acme@kernel.org, rostedt@goodmis.org
Cc: mingo@redhat.com, namhyung@kernel.org, pi3orama@163.com,
lizefan@huawei.com, linux-kernel@vger.kernel.org, sysp-manager
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 11180 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, now looks good to me :D
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
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.
>
> v2 -> v3:
> Split bugfix to a separated patch.
>
> 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 | 162 +++++++++++++++++++++++++++++++++++++++--
> tools/perf/util/probe-event.h | 4 +
> tools/perf/util/probe-finder.c | 21 +-----
> 3 files changed, 163 insertions(+), 24 deletions(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index eaacb58..eb5f18b 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1204,9 +1204,27 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
>
> 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;
> @@ -1804,14 +1822,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 ? ":" : "",
> @@ -1874,8 +1907,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;
> @@ -2331,7 +2364,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;
> @@ -2598,6 +2633,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,
> @@ -2614,6 +2741,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)
> @@ -2784,3 +2915,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 83ee95e..6e7ec68 100644
> --- a/tools/perf/util/probe-event.h
> +++ b/tools/perf/util/probe-event.h
> @@ -59,6 +59,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 */
> @@ -156,4 +157,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 7b80f8c..29c43c068 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] 18+ messages in thread
* RE: [PATCH v3 4/6] perf probe: Fix error reported when offset without function
2015-08-26 10:57 ` [PATCH v3 4/6] perf probe: Fix error reported when offset without function Wang Nan
@ 2015-08-26 12:21 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26 12:21 UTC (permalink / raw)
To: 'Wang Nan', acme@kernel.org, rostedt@goodmis.org
Cc: mingo@redhat.com, namhyung@kernel.org, pi3orama@163.com,
lizefan@huawei.com, linux-kernel@vger.kernel.org, sysp-manager
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1726 bytes --]
> From: Wang Nan [mailto:wangnan0@huawei.com]
>
> This patch fixes a bug that, when offset is provided but function is
> lost, parse_perf_probe_point() will give a "" string as function name,
> so the checking code at the end of parse_perf_probe_point() become useless.
> 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.
OK, seems sane now :)
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>
> ---
> tools/perf/util/probe-event.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 926bcec..eaacb58 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1194,9 +1194,13 @@ 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;
> --
> 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] 18+ messages in thread
* RE: [PATCH v3 2/6] perf probe: Fix list result when symbol can't be found
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when symbol can't be found Wang Nan
@ 2015-08-26 12:27 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:41 ` [tip:perf/core] perf probe: Fix list result when symbol can' t " tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: 平松雅巳 / HIRAMATU,MASAMI @ 2015-08-26 12:27 UTC (permalink / raw)
To: 'Wang Nan', acme@kernel.org, rostedt@goodmis.org
Cc: mingo@redhat.com, namhyung@kernel.org, pi3orama@163.com,
lizefan@huawei.com, linux-kernel@vger.kernel.org, sysp-manager
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1974 bytes --]
> From: Wang Nan [mailto:wangnan0@huawei.com]
>
> 'perf probe -l' reports error if it is unable find symbol through
> address. Here is an example.
>
> # 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
>
> Also, this situation triggers a logical inconsistency in
> convert_to_perf_probe_point() that, it returns ENOMEM but actually
> it never try strdup().
>
> This patch removes !tp->module && !is_kprobe condition, so it
> always uses address to build function name if symbol not found.
>
> Test result:
>
> # perf probe -l
> probe_libc:abs_5 (on 0x5 in /lib64/libc.so.6)
>
Looks good!
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
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 | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 6c7e538..f7bacbb 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1866,7 +1866,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] 18+ messages in thread
* [tip:perf/core] perf probe: Fix list result when symbol can' t be found
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when symbol can't be found Wang Nan
2015-08-26 12:27 ` 平松雅巳 / HIRAMATU,MASAMI
@ 2015-08-28 6:41 ` tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: tip-bot for Wang Nan @ 2015-08-28 6:41 UTC (permalink / raw)
To: linux-tip-commits
Cc: lizefan, wangnan0, tglx, namhyung, linux-kernel, acme, mingo,
masami.hiramatsu.pt, rostedt, hpa
Commit-ID: 614e2fdbd79b47ddf63a1ccd3f2343e98c3077fb
Gitweb: http://git.kernel.org/tip/614e2fdbd79b47ddf63a1ccd3f2343e98c3077fb
Author: Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 26 Aug 2015 10:57:42 +0000
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 26 Aug 2015 10:36:04 -0300
perf probe: Fix list result when symbol can't be found
'perf probe -l' reports error if it is unable find symbol through
address. Here is an example.
# 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
Also, this situation triggers a logical inconsistency in
convert_to_perf_probe_point() that, it returns ENOMEM but actually it
never try strdup().
This patch removes !tp->module && !is_kprobe condition, so it always
uses address to build function name if symbol not found.
Test result:
# perf probe -l
probe_libc:abs_5 (on 0x5 in /lib64/libc.so.6)
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1440586666-235233-4-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/probe-event.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6c7e538..f7bacbb 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1866,7 +1866,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;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [tip:perf/core] perf probe: Fix list result when address is zero
2015-08-26 10:57 ` [PATCH v3 3/6] perf probe: Fix list result when address is zero Wang Nan
2015-08-26 12:14 ` 平松雅巳 / HIRAMATU,MASAMI
@ 2015-08-28 6:42 ` tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: tip-bot for Wang Nan @ 2015-08-28 6:42 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, namhyung, hpa, lizefan, tglx, masami.hiramatsu.pt,
acme, wangnan0, rostedt, mingo
Commit-ID: be07afe92a09638db9159d2c0794487d66a437a2
Gitweb: http://git.kernel.org/tip/be07afe92a09638db9159d2c0794487d66a437a2
Author: Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 26 Aug 2015 10:57:43 +0000
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 26 Aug 2015 10:39:20 -0300
perf probe: Fix list result when address is zero
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 /path/to/lib.bin:0x (null) arg1=%ax
This patch supports the above kernel output.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1440586666-235233-5-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/probe-event.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f7bacbb..926bcec 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1519,9 +1519,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) {
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [tip:perf/core] perf probe: Fix error reported when offset without function
2015-08-26 10:57 ` [PATCH v3 4/6] perf probe: Fix error reported when offset without function Wang Nan
2015-08-26 12:21 ` 平松雅巳 / HIRAMATU,MASAMI
@ 2015-08-28 6:42 ` tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: tip-bot for Wang Nan @ 2015-08-28 6:42 UTC (permalink / raw)
To: linux-tip-commits
Cc: rostedt, wangnan0, namhyung, hpa, linux-kernel, acme, mingo,
masami.hiramatsu.pt, tglx, lizefan
Commit-ID: 6c6e024f0a62a6a08c06002fd3caa2307cc54fd0
Gitweb: http://git.kernel.org/tip/6c6e024f0a62a6a08c06002fd3caa2307cc54fd0
Author: Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 26 Aug 2015 10:57:44 +0000
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 26 Aug 2015 10:40:34 -0300
perf probe: Fix error reported when offset without function
This patch fixes a bug that, when offset is provided but function is
lost, parse_perf_probe_point() will give a "" string as function name,
so the checking code at the end of parse_perf_probe_point() become
useless. 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.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1440586666-235233-6-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/probe-event.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 926bcec..eaacb58 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1194,9 +1194,13 @@ 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;
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [tip:perf/core] perf probe: Support probing at absolute address
2015-08-26 10:57 ` [PATCH v3 5/6] perf probe: Support probing at absolute address Wang Nan
2015-08-26 12:16 ` 平松雅巳 / HIRAMATU,MASAMI
@ 2015-08-28 6:42 ` tip-bot for Wang Nan
1 sibling, 0 replies; 18+ messages in thread
From: tip-bot for Wang Nan @ 2015-08-28 6:42 UTC (permalink / raw)
To: linux-tip-commits
Cc: wangnan0, lizefan, mingo, tglx, rostedt, linux-kernel, acme,
namhyung, hpa, masami.hiramatsu.pt
Commit-ID: da15bd9df4afd2f9f78cf29f85f013e3a38402b5
Gitweb: http://git.kernel.org/tip/da15bd9df4afd2f9f78cf29f85f013e3a38402b5
Author: Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 26 Aug 2015 10:57:45 +0000
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 26 Aug 2015 10:41:12 -0300
perf probe: Support probing at absolute address
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.
v1 -> v2:
Drop the leading '+' in cmdline;
Allow uprobing at offset 0x0;
Improve 'perf probe -l' result when uprobe at area without debuginfo.
v2 -> v3:
Split bugfix to a separated patch.
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>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1440586666-235233-7-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/probe-event.c | 162 +++++++++++++++++++++++++++++++++++++++--
tools/perf/util/probe-event.h | 4 +
tools/perf/util/probe-finder.c | 21 +-----
3 files changed, 163 insertions(+), 24 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index eaacb58..eb5f18b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1204,9 +1204,27 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
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;
@@ -1804,14 +1822,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 ? ":" : "",
@@ -1874,8 +1907,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;
@@ -2331,7 +2364,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;
@@ -2598,6 +2633,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,
@@ -2614,6 +2741,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)
@@ -2784,3 +2915,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 83ee95e..6e7ec68 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -59,6 +59,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 */
@@ -156,4 +157,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 7b80f8c..29c43c068 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);
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [tip:perf/core] tracing/uprobes: Do not print '0x (null)' when offset is 0
2015-08-26 10:57 ` [PATCH v3 6/6] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
@ 2015-08-28 6:43 ` tip-bot for Wang Nan
0 siblings, 0 replies; 18+ messages in thread
From: tip-bot for Wang Nan @ 2015-08-28 6:43 UTC (permalink / raw)
To: linux-tip-commits
Cc: rostedt, wangnan0, linux-kernel, namhyung, lizefan, mingo, tglx,
acme, hpa, masami.hiramatsu.pt
Commit-ID: a2fb3382edbea83c6f2bf6ac15e3673b2e254aad
Gitweb: http://git.kernel.org/tip/a2fb3382edbea83c6f2bf6ac15e3673b2e254aad
Author: Wang Nan <wangnan0@huawei.com>
AuthorDate: Wed, 26 Aug 2015 10:57:46 +0000
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 26 Aug 2015 10:43:01 -0300
tracing/uprobes: Do not print '0x (null)' when offset is 0
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>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1440586666-235233-8-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
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);
^ permalink raw reply related [flat|nested] 18+ messages in thread
end of thread, other threads:[~2015-08-28 6:43 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-26 10:57 [PATCH v3 0/6] perf probe, tracing/uprobes: Support probing at absolute address Wang Nan
2015-08-26 10:57 ` [PATCH v3 1/6] perf probe: Prevent segfault when reading probe point with " Wang Nan
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when neither dwarf nor map can't find symbol Wang Nan
2015-08-26 11:03 ` Wangnan (F)
2015-08-26 10:57 ` [PATCH v3 2/6] perf probe: Fix list result when symbol can't be found Wang Nan
2015-08-26 12:27 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:41 ` [tip:perf/core] perf probe: Fix list result when symbol can' t " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 3/6] perf probe: Fix list result when address is zero Wang Nan
2015-08-26 12:14 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 4/6] perf probe: Fix error reported when offset without function Wang Nan
2015-08-26 12:21 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 5/6] perf probe: Support probing at absolute address Wang Nan
2015-08-26 12:16 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-28 6:42 ` [tip:perf/core] " tip-bot for Wang Nan
2015-08-26 10:57 ` [PATCH v3 6/6] tracing/uprobes: Do not print '0x (null)' when offset is 0 Wang Nan
2015-08-28 6:43 ` [tip:perf/core] " tip-bot for Wang Nan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.