aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-06-17 16:07:49 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-06-17 16:07:49 -0400
commit315ff6f8c9e9e899d655d75d5f5203c8b0047b0b (patch)
tree47158ca633c750382ad56eb69f1aba43783f5de4
parent11b828a7f5759ee6de214a102ee97d7b712bb47e (diff)
parse-events: Handle '*' in TP_printk format
When the "*" (next arg is length) is used in the TP_printk format, it is currently not handled. This will cause a shift in the arguments that are passed in causing all arguments after to be corrupted. Reported-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--parse-events.c66
1 files changed, 53 insertions, 13 deletions
diff --git a/parse-events.c b/parse-events.c
index 13c41aa..c0118aa 100644
--- a/parse-events.c
+++ b/parse-events.c
@@ -3042,12 +3042,14 @@ static unsigned long long eval_flag(const char *flag)
3042} 3042}
3043 3043
3044static void print_str_arg(struct trace_seq *s, void *data, int size, 3044static void print_str_arg(struct trace_seq *s, void *data, int size,
3045 struct event_format *event, struct print_arg *arg) 3045 struct event_format *event,
3046 int len_arg, struct print_arg *arg)
3046{ 3047{
3047 struct pevent *pevent = event->pevent; 3048 struct pevent *pevent = event->pevent;
3048 struct print_flag_sym *flag; 3049 struct print_flag_sym *flag;
3049 unsigned long long val, fval; 3050 unsigned long long val, fval;
3050 unsigned long addr; 3051 unsigned long addr;
3052 int len_as_arg = len_arg >= 0;
3051 char *str; 3053 char *str;
3052 int print; 3054 int print;
3053 int len; 3055 int len;
@@ -3082,7 +3084,10 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3082 str = malloc_or_die(len + 1); 3084 str = malloc_or_die(len + 1);
3083 memcpy(str, data + arg->field.field->offset, len); 3085 memcpy(str, data + arg->field.field->offset, len);
3084 str[len] = 0; 3086 str[len] = 0;
3085 trace_seq_puts(s, str); 3087 if (len_as_arg)
3088 trace_seq_printf(s, "%.*s", len_arg, str);
3089 else
3090 trace_seq_puts(s, str);
3086 free(str); 3091 free(str);
3087 break; 3092 break;
3088 case PRINT_FLAGS: 3093 case PRINT_FLAGS:
@@ -3091,13 +3096,19 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3091 for (flag = arg->flags.flags; flag; flag = flag->next) { 3096 for (flag = arg->flags.flags; flag; flag = flag->next) {
3092 fval = eval_flag(flag->value); 3097 fval = eval_flag(flag->value);
3093 if (!val && !fval) { 3098 if (!val && !fval) {
3094 trace_seq_puts(s, flag->str); 3099 if (len_as_arg)
3100 trace_seq_printf(s, "%.*s", len_arg, flag->str);
3101 else
3102 trace_seq_puts(s, flag->str);
3095 break; 3103 break;
3096 } 3104 }
3097 if (fval && (val & fval) == fval) { 3105 if (fval && (val & fval) == fval) {
3098 if (print && arg->flags.delim) 3106 if (print && arg->flags.delim)
3099 trace_seq_puts(s, arg->flags.delim); 3107 trace_seq_puts(s, arg->flags.delim);
3100 trace_seq_puts(s, flag->str); 3108 if (len_as_arg)
3109 trace_seq_printf(s, "%.*s", len_arg, flag->str);
3110 else
3111 trace_seq_puts(s, flag->str);
3101 print = 1; 3112 print = 1;
3102 val &= ~fval; 3113 val &= ~fval;
3103 } 3114 }
@@ -3108,7 +3119,10 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3108 for (flag = arg->symbol.symbols; flag; flag = flag->next) { 3119 for (flag = arg->symbol.symbols; flag; flag = flag->next) {
3109 fval = eval_flag(flag->value); 3120 fval = eval_flag(flag->value);
3110 if (val == fval) { 3121 if (val == fval) {
3111 trace_seq_puts(s, flag->str); 3122 if (len_as_arg)
3123 trace_seq_printf(s, "%.*s", len_arg, flag->str);
3124 else
3125 trace_seq_puts(s, flag->str);
3112 break; 3126 break;
3113 } 3127 }
3114 } 3128 }
@@ -3127,7 +3141,10 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3127 } 3141 }
3128 str_offset = data2host4(pevent, data + arg->string.offset); 3142 str_offset = data2host4(pevent, data + arg->string.offset);
3129 str_offset &= 0xffff; 3143 str_offset &= 0xffff;
3130 trace_seq_puts(s, ((char *)data) + str_offset); 3144 if (len_as_arg)
3145 trace_seq_printf(s, "%.*s", len_arg, ((char *)data) + str_offset);
3146 else
3147 trace_seq_puts(s, ((char *)data) + str_offset);
3131 break; 3148 break;
3132 } 3149 }
3133 case PRINT_OP: 3150 case PRINT_OP:
@@ -3138,9 +3155,9 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3138 return; 3155 return;
3139 val = eval_num_arg(data, size, event, arg->op.left); 3156 val = eval_num_arg(data, size, event, arg->op.left);
3140 if (val) 3157 if (val)
3141 print_str_arg(s, data, size, event, arg->op.right->op.left); 3158 print_str_arg(s, data, size, event, len_arg, arg->op.right->op.left);
3142 else 3159 else
3143 print_str_arg(s, data, size, event, arg->op.right->op.right); 3160 print_str_arg(s, data, size, event, len_arg, arg->op.right->op.right);
3144 break; 3161 break;
3145 case PRINT_FUNC: 3162 case PRINT_FUNC:
3146 process_defined_func(s, data, size, event, arg); 3163 process_defined_func(s, data, size, event, arg);
@@ -3185,7 +3202,7 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3185 break; 3202 break;
3186 case PEVENT_FUNC_ARG_STRING: 3203 case PEVENT_FUNC_ARG_STRING:
3187 trace_seq_init(&str); 3204 trace_seq_init(&str);
3188 print_str_arg(&str, data, size, event, farg); 3205 print_str_arg(&str, data, size, event, -1, farg);
3189 trace_seq_terminate(&str); 3206 trace_seq_terminate(&str);
3190 string = malloc_or_die(sizeof(*string)); 3207 string = malloc_or_die(sizeof(*string));
3191 string->next = strings; 3208 string->next = strings;
@@ -3494,6 +3511,8 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3494 char *bprint_fmt = NULL; 3511 char *bprint_fmt = NULL;
3495 char format[32]; 3512 char format[32];
3496 int show_func; 3513 int show_func;
3514 int len_as_arg;
3515 int len_arg;
3497 int len; 3516 int len;
3498 int ls; 3517 int ls;
3499 3518
@@ -3535,6 +3554,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3535 } else if (*ptr == '%') { 3554 } else if (*ptr == '%') {
3536 saveptr = ptr; 3555 saveptr = ptr;
3537 show_func = 0; 3556 show_func = 0;
3557 len_as_arg = 0;
3538 cont_process: 3558 cont_process:
3539 ptr++; 3559 ptr++;
3540 switch (*ptr) { 3560 switch (*ptr) {
@@ -3550,6 +3570,14 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3550 case 'L': 3570 case 'L':
3551 ls = 2; 3571 ls = 2;
3552 goto cont_process; 3572 goto cont_process;
3573 case '*':
3574 /* The argument is the length. */
3575 if (!arg)
3576 die("no argument match");
3577 len_arg = eval_num_arg(data, size, event, arg);
3578 len_as_arg = 1;
3579 arg = arg->next;
3580 goto cont_process;
3553 case '.': 3581 case '.':
3554 case 'z': 3582 case 'z':
3555 case 'Z': 3583 case 'Z':
@@ -3617,13 +3645,23 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3617 } 3645 }
3618 switch (ls) { 3646 switch (ls) {
3619 case 0: 3647 case 0:
3620 trace_seq_printf(s, format, (int)val); 3648 if (len_as_arg)
3649 trace_seq_printf(s, format, len_arg, (int)val);
3650 else
3651 trace_seq_printf(s, format, (int)val);
3621 break; 3652 break;
3622 case 1: 3653 case 1:
3623 trace_seq_printf(s, format, (long)val); 3654 if (len_as_arg)
3655 trace_seq_printf(s, format, len_arg, (long)val);
3656 else
3657 trace_seq_printf(s, format, (long)val);
3624 break; 3658 break;
3625 case 2: 3659 case 2:
3626 trace_seq_printf(s, format, (long long)val); 3660 if (len_as_arg)
3661 trace_seq_printf(s, format, len_arg,
3662 (long long)val);
3663 else
3664 trace_seq_printf(s, format, (long long)val);
3627 break; 3665 break;
3628 default: 3666 default:
3629 die("bad count (%d)", ls); 3667 die("bad count (%d)", ls);
@@ -3633,7 +3671,9 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3633 if (!arg) 3671 if (!arg)
3634 die("no matching argument"); 3672 die("no matching argument");
3635 3673
3636 print_str_arg(s, data, size, event, arg); 3674 if (!len_as_arg)
3675 len_arg = -1;
3676 print_str_arg(s, data, size, event, len_arg, arg);
3637 arg = arg->next; 3677 arg = arg->next;
3638 break; 3678 break;
3639 default: 3679 default: