Re: [RFC PATCH v2 09/15] perf probe: Support $params without debuginfo

From: Masami Hiramatsu
Date: Mon May 25 2015 - 08:23:05 EST


On 2015/05/25 17:33, He Kuang wrote:
> hi,
>
> On 2015/5/24 16:49, Masami Hiramatsu wrote:
>> On 2015/05/24 17:28, He Kuang wrote:
>>> When probing at function entry, fallback $params to calling regs if no
>>> debuginfo is provided.
>>>
>>> Before this path:
>>> $ perf probe -v --add='generic_perform_write $params'
>>> ...
>>> Added new event:
>>> Writing event: p:probe/generic_perform_write _stext+1246632 $params
>>> [86152.161204] Parse error at argument[0]. (-22)
>>> Failed to write event: Invalid argument
>>> Error: Failed to add events. Reason: Invalid argument (Code: -22)
>>>
>>> After this patch:
>>> $ perf probe -v --add='generic_perform_write $params'
>>> ...
>>> Could not open debuginfo. Try to use symbols.
>>> ...
>>> Added new event:
>>> Writing event: p:probe/generic_perform_write _stext+1246632 %di %si %dx %cx %r8 %r9
>>> probe:generic_perform_write (on generic_perform_write with $params)
>>>
>>> You can now use it in all perf tools, such as:
>>>
>>> perf record -e probe:generic_perform_write -aR sleep 1
>>>
>>> $ perf record -e probe:generic_perform_write dd if=/dev/zero of=/mnt/data/test bs=4k count=3
>>
>> NAK, this should not work on x86-32 and we don't know how many registers are used.
>> I think $params special handler should be used only with debuginfo, since $params
>> ensures user to save function parameters with its name. If we can't do that, we
>> should accept that.
>>
>> If you need to handle register arguments, you should introduce new $regparams instead
>
> Yes, $regparam is more appropriate.

thanks :)

>> of $params. (however, that still not work correctly on x86-32)
>>
>> Hmm, we also need $regs to record all registers.
>
> Right, I learnt regparm(3) is mandatory in x86_32, according to rules,
> the first three args will go to regparm(ax, dx, cx). But we should not
> refer arg1~3 to ax, dx, cx because of 64bit parameters (other reasons?).

Also, if the function is asmlinkage, its arguments are passed via stack.

> Consider this keyword is used for generating bpf prologue which fetches
> formal parameters when no debuginfo is provided, for this purpose, we can:
> 1) We just help fetch the $regs or $regparms(If the keyword is
> $regparms, ax/dx/cx is fetched, nothing related to args) to bpf arglists
> and leave the rest things to bpf prog writer.
>
> 2) Keep that on platforms like x86_64 and skip this feature on
> platforms like x86_32.

I like 1), since such arch-dependent behavior looks confusing.

>
> or any other suggestions?

Actually, I'm working on the perf-probe cache enhancement (and it will be perf-cache)
which allows you to cache the result of debuginfo analysis under buildid-cache.
So, if the build-id is same on remote machines, you can transfer the cache to the
remote machine and reuse it. This means you don't need debuginfo in the remote machine
unless you're using the same binary/bpf.

Thank you,

>
> Thanks
>
>>
>> Thank you,
>>
>>
>>>
>>> $ perf script
>>> dd 1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x0 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>> dd 1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x1000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>> dd 1149 [000] 18574.762652: probe:generic_perform_write: (ffffffff81130770) arg1=0xffff88007c37f600 arg2=0xffff88007ca87e70 arg3=0x2000 arg4=0x0 arg5=0x556062e3 arg6=0x12a8010
>>>
>>> Signed-off-by: He Kuang <hekuang@xxxxxxxxxx>
>>> ---
>>> tools/perf/util/probe-event.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 42 insertions(+)
>>>
>>> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
>>> index d05b77c..7f9f431 100644
>>> --- a/tools/perf/util/probe-event.c
>>> +++ b/tools/perf/util/probe-event.c
>>> @@ -46,6 +46,7 @@
>>> #include "probe-event.h"
>>> #include "probe-finder.h"
>>> #include "session.h"
>>> +#include <dwarf-regs.h>
>>>
>>> #define MAX_CMDLEN 256
>>> #define PERFPROBE_GROUP "probe"
>>> @@ -286,6 +287,14 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
>>> clear_probe_trace_event(tevs + i);
>>> }
>>>
>>> +static bool perf_probe_is_function_entry(struct perf_probe_event *pev)
>>> +{
>>> + if (pev->point.file || pev->point.line || pev->point.lazy_line)
>>> + return false;
>>> +
>>> + return true;
>>> +}
>>> +
>>> #ifdef HAVE_DWARF_SUPPORT
>>> /*
>>> * Some binaries like glibc have special symbols which are on the symbol
>>> @@ -1225,6 +1234,33 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
>>> return 0;
>>> }
>>>
>>> +static char *parse_perf_probe_param(void)
>>> +{
>>> + int i = 0;
>>> + struct strbuf sb;
>>> + bool first = true;
>>> + const char *reg_str;
>>> +
>>> + strbuf_init(&sb, 16);
>>> +
>>> + while (1) {
>>> + reg_str = get_arch_calling_reg_str(i++);
>>> + if (!reg_str)
>>> + break;
>>> +
>>> + if (first) {
>>> + strbuf_addf(&sb, "%s", reg_str);
>>> + first = false;
>>> + } else
>>> + strbuf_addf(&sb, " %s", reg_str);
>>> + }
>>> +
>>> + if (first)
>>> + strbuf_add(&sb, "", 1);
>>> +
>>> + return strbuf_detach(&sb, NULL);
>>> +}
>>> +
>>> /* Parse perf-probe event argument */
>>> static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
>>> {
>>> @@ -2543,6 +2579,12 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>>> goto nomem_out;
>>> }
>>> for (i = 0; i < tev->nargs; i++) {
>>> + if (perf_probe_is_function_entry(pev) &&
>>> + !strcmp(pev->args[i].var, "$params")) {
>>> + tev->args[i].value = parse_perf_probe_param();
>>> + continue;
>>> + }
>>> +
>>> if (pev->args[i].name)
>>> tev->args[i].name =
>>> strdup_or_goto(pev->args[i].name,
>>>
>>
>>
>
>


--
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@xxxxxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/