diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2011-11-15 18:47:48 -0500 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2011-11-15 18:47:48 -0500 |
| commit | 989d00fcdc4d67632509bdde3b42ee0973884ecd (patch) | |
| tree | 19900f3e747bf8e54c517334283afc345633e117 /parse-events.c | |
| parent | d012896cecf1fd498aa4af2f43c567af4795254d (diff) | |
parse-events: 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>
Diffstat (limited to 'parse-events.c')
| -rw-r--r-- | parse-events.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/parse-events.c b/parse-events.c index ca9fbb0..da1d0a6 100644 --- a/parse-events.c +++ b/parse-events.c | |||
| @@ -3270,7 +3270,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
| 3270 | break; | 3270 | break; |
| 3271 | } | 3271 | } |
| 3272 | case PRINT_BSTRING: | 3272 | case PRINT_BSTRING: |
| 3273 | trace_seq_printf(s, format, arg->string.string); | 3273 | print_str_to_seq(s, format, len_arg, arg->string.string); |
| 3274 | break; | 3274 | break; |
| 3275 | case PRINT_OP: | 3275 | case PRINT_OP: |
| 3276 | /* | 3276 | /* |
| @@ -3370,6 +3370,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3370 | unsigned long long ip, val; | 3370 | unsigned long long ip, val; |
| 3371 | char *ptr; | 3371 | char *ptr; |
| 3372 | void *bptr; | 3372 | void *bptr; |
| 3373 | int vsize; | ||
| 3373 | 3374 | ||
| 3374 | field = pevent->bprint_buf_field; | 3375 | field = pevent->bprint_buf_field; |
| 3375 | ip_field = pevent->bprint_ip_field; | 3376 | ip_field = pevent->bprint_ip_field; |
| @@ -3418,6 +3419,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3418 | goto process_again; | 3419 | goto process_again; |
| 3419 | case '0' ... '9': | 3420 | case '0' ... '9': |
| 3420 | goto process_again; | 3421 | goto process_again; |
| 3422 | case '.': | ||
| 3423 | goto process_again; | ||
| 3421 | case 'p': | 3424 | case 'p': |
| 3422 | ls = 1; | 3425 | ls = 1; |
| 3423 | /* fall through */ | 3426 | /* fall through */ |
| @@ -3425,23 +3428,29 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3425 | case 'u': | 3428 | case 'u': |
| 3426 | case 'x': | 3429 | case 'x': |
| 3427 | case 'i': | 3430 | case 'i': |
| 3428 | /* the pointers are always 4 bytes aligned */ | ||
| 3429 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
| 3430 | ~3); | ||
| 3431 | switch (ls) { | 3431 | switch (ls) { |
| 3432 | case 0: | 3432 | case 0: |
| 3433 | ls = 4; | 3433 | vsize = 4; |
| 3434 | break; | 3434 | break; |
| 3435 | case 1: | 3435 | case 1: |
| 3436 | ls = pevent->long_size; | 3436 | vsize = pevent->long_size; |
| 3437 | break; | 3437 | break; |
| 3438 | case 2: | 3438 | case 2: |
| 3439 | ls = 8; | 3439 | vsize = 8; |
| 3440 | default: | 3440 | default: |
| 3441 | vsize = ls; /* ? */ | ||
| 3441 | break; | 3442 | break; |
| 3442 | } | 3443 | } |
| 3443 | val = pevent_read_number(pevent, bptr, ls); | 3444 | /* fall through */ |
| 3444 | bptr += ls; | 3445 | case '*': |
| 3446 | if (*ptr == '*') | ||
| 3447 | vsize = 4; | ||
| 3448 | |||
| 3449 | /* the pointers are always 4 bytes aligned */ | ||
| 3450 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
| 3451 | ~3); | ||
| 3452 | val = pevent_read_number(pevent, bptr, vsize); | ||
| 3453 | bptr += vsize; | ||
| 3445 | arg = alloc_arg(); | 3454 | arg = alloc_arg(); |
| 3446 | arg->next = NULL; | 3455 | arg->next = NULL; |
| 3447 | arg->type = PRINT_ATOM; | 3456 | arg->type = PRINT_ATOM; |
| @@ -3449,6 +3458,13 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3449 | sprintf(arg->atom.atom, "%lld", val); | 3458 | sprintf(arg->atom.atom, "%lld", val); |
| 3450 | *next = arg; | 3459 | *next = arg; |
| 3451 | next = &arg->next; | 3460 | next = &arg->next; |
| 3461 | /* | ||
| 3462 | * The '*' case means that an arg is used as the length. | ||
| 3463 | * We need to continue to figure out for what. | ||
| 3464 | */ | ||
| 3465 | if (*ptr == '*') | ||
| 3466 | goto process_again; | ||
| 3467 | |||
| 3452 | break; | 3468 | break; |
| 3453 | case 's': | 3469 | case 's': |
| 3454 | arg = alloc_arg(); | 3470 | arg = alloc_arg(); |
