diff options
author | Steven Rostedt <srostedt@redhat.com> | 2011-11-15 18:47:48 -0500 |
---|---|---|
committer | Namhyung Kim <namhyung@kernel.org> | 2012-07-04 00:40:30 -0400 |
commit | c2e6dc2b268cca44d522b2ee86147f0d30d7e3e4 (patch) | |
tree | 5db2c6b780350b11ddb9a58280ef4f3f0e4182ad /tools/lib | |
parent | e84c282b40251f314c429f39b044785e323f2648 (diff) |
tools lib traceevent: Add support for "%.*s" in bprintk events
The arg notation of '*' in bprintks is not handled by the parser.
Implement it so that they show up properly in the output and do not
kill the tracer from reporting events.
Reported-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/n/tip-t0ctq7t1xz3ud6wv4v886jou@git.kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 83f0a8add17..0644c2a23ad 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -3370,7 +3370,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3370 | break; | 3370 | break; |
3371 | } | 3371 | } |
3372 | case PRINT_BSTRING: | 3372 | case PRINT_BSTRING: |
3373 | trace_seq_printf(s, format, arg->string.string); | 3373 | print_str_to_seq(s, format, len_arg, arg->string.string); |
3374 | break; | 3374 | break; |
3375 | case PRINT_OP: | 3375 | case PRINT_OP: |
3376 | /* | 3376 | /* |
@@ -3471,6 +3471,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3471 | unsigned long long ip, val; | 3471 | unsigned long long ip, val; |
3472 | char *ptr; | 3472 | char *ptr; |
3473 | void *bptr; | 3473 | void *bptr; |
3474 | int vsize; | ||
3474 | 3475 | ||
3475 | field = pevent->bprint_buf_field; | 3476 | field = pevent->bprint_buf_field; |
3476 | ip_field = pevent->bprint_ip_field; | 3477 | ip_field = pevent->bprint_ip_field; |
@@ -3519,6 +3520,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3519 | goto process_again; | 3520 | goto process_again; |
3520 | case '0' ... '9': | 3521 | case '0' ... '9': |
3521 | goto process_again; | 3522 | goto process_again; |
3523 | case '.': | ||
3524 | goto process_again; | ||
3522 | case 'p': | 3525 | case 'p': |
3523 | ls = 1; | 3526 | ls = 1; |
3524 | /* fall through */ | 3527 | /* fall through */ |
@@ -3526,23 +3529,29 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3526 | case 'u': | 3529 | case 'u': |
3527 | case 'x': | 3530 | case 'x': |
3528 | case 'i': | 3531 | case 'i': |
3529 | /* the pointers are always 4 bytes aligned */ | ||
3530 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
3531 | ~3); | ||
3532 | switch (ls) { | 3532 | switch (ls) { |
3533 | case 0: | 3533 | case 0: |
3534 | ls = 4; | 3534 | vsize = 4; |
3535 | break; | 3535 | break; |
3536 | case 1: | 3536 | case 1: |
3537 | ls = pevent->long_size; | 3537 | vsize = pevent->long_size; |
3538 | break; | 3538 | break; |
3539 | case 2: | 3539 | case 2: |
3540 | ls = 8; | 3540 | vsize = 8; |
3541 | default: | 3541 | default: |
3542 | vsize = ls; /* ? */ | ||
3542 | break; | 3543 | break; |
3543 | } | 3544 | } |
3544 | val = pevent_read_number(pevent, bptr, ls); | 3545 | /* fall through */ |
3545 | bptr += ls; | 3546 | case '*': |
3547 | if (*ptr == '*') | ||
3548 | vsize = 4; | ||
3549 | |||
3550 | /* the pointers are always 4 bytes aligned */ | ||
3551 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
3552 | ~3); | ||
3553 | val = pevent_read_number(pevent, bptr, vsize); | ||
3554 | bptr += vsize; | ||
3546 | arg = alloc_arg(); | 3555 | arg = alloc_arg(); |
3547 | arg->next = NULL; | 3556 | arg->next = NULL; |
3548 | arg->type = PRINT_ATOM; | 3557 | arg->type = PRINT_ATOM; |
@@ -3550,6 +3559,13 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3550 | sprintf(arg->atom.atom, "%lld", val); | 3559 | sprintf(arg->atom.atom, "%lld", val); |
3551 | *next = arg; | 3560 | *next = arg; |
3552 | next = &arg->next; | 3561 | next = &arg->next; |
3562 | /* | ||
3563 | * The '*' case means that an arg is used as the length. | ||
3564 | * We need to continue to figure out for what. | ||
3565 | */ | ||
3566 | if (*ptr == '*') | ||
3567 | goto process_again; | ||
3568 | |||
3553 | break; | 3569 | break; |
3554 | case 's': | 3570 | case 's': |
3555 | arg = alloc_arg(); | 3571 | arg = alloc_arg(); |