aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorVaibhav Nagarnaik <vnagarnaik@google.com>2012-04-05 18:48:00 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2012-04-25 07:35:28 -0400
commitd69afed55be1016c2bcfcb3e00cd5365d2f557f6 (patch)
tree1c5dcb6fd48531ea1ee278fbc2a54ec613637472 /tools
parent54a3625829c9de60f4acbd0efe3ec4201b174fd6 (diff)
parse-events: Handle invalid opcode parsing gracefully
If an invalid opcode is encountered, trace-cmd exits with an error. Instead it can be treated as a soft error where the event's print format is not parsed and its binary data is dumped out. This patch adds a return value to arg_num_eval() function to indicate if the parsing was successful. If not, then the error is considered soft and the parsing of the offending event fails. Cc: Michael Rubin <mrubin@google.com> Cc: David Sharp <dhsharp@google.com> Signed-off-by: Vaibhav Nagarnaik <vnagarnaik@google.com> Link: http://lkml.kernel.org/r/1310785241-3799-2-git-send-email-vnagarnaik@google.com Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@infradead.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Arun Sharma <asharma@fb.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/traceevent/event-parse.c125
1 files changed, 83 insertions, 42 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 16da20c552b..ef2c65f9167 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -1915,90 +1915,120 @@ eval_type(unsigned long long val, struct print_arg *arg, int pointer)
1915 return eval_type_str(val, arg->typecast.type, pointer); 1915 return eval_type_str(val, arg->typecast.type, pointer);
1916} 1916}
1917 1917
1918static long long arg_num_eval(struct print_arg *arg) 1918static int arg_num_eval(struct print_arg *arg, long long *val)
1919{ 1919{
1920 long long left, right; 1920 long long left, right;
1921 long long val = 0; 1921 int ret = 1;
1922 1922
1923 switch (arg->type) { 1923 switch (arg->type) {
1924 case PRINT_ATOM: 1924 case PRINT_ATOM:
1925 val = strtoll(arg->atom.atom, NULL, 0); 1925 *val = strtoll(arg->atom.atom, NULL, 0);
1926 break; 1926 break;
1927 case PRINT_TYPE: 1927 case PRINT_TYPE:
1928 val = arg_num_eval(arg->typecast.item); 1928 ret = arg_num_eval(arg->typecast.item, val);
1929 val = eval_type(val, arg, 0); 1929 if (!ret)
1930 break;
1931 *val = eval_type(*val, arg, 0);
1930 break; 1932 break;
1931 case PRINT_OP: 1933 case PRINT_OP:
1932 switch (arg->op.op[0]) { 1934 switch (arg->op.op[0]) {
1933 case '|': 1935 case '|':
1934 left = arg_num_eval(arg->op.left); 1936 ret = arg_num_eval(arg->op.left, &left);
1935 right = arg_num_eval(arg->op.right); 1937 if (!ret)
1938 break;
1939 ret = arg_num_eval(arg->op.right, &right);
1940 if (!ret)
1941 break;
1936 if (arg->op.op[1]) 1942 if (arg->op.op[1])
1937 val = left || right; 1943 *val = left || right;
1938 else 1944 else
1939 val = left | right; 1945 *val = left | right;
1940 break; 1946 break;
1941 case '&': 1947 case '&':
1942 left = arg_num_eval(arg->op.left); 1948 ret = arg_num_eval(arg->op.left, &left);
1943 right = arg_num_eval(arg->op.right); 1949 if (!ret)
1950 break;
1951 ret = arg_num_eval(arg->op.right, &right);
1952 if (!ret)
1953 break;
1944 if (arg->op.op[1]) 1954 if (arg->op.op[1])
1945 val = left && right; 1955 *val = left && right;
1946 else 1956 else
1947 val = left & right; 1957 *val = left & right;
1948 break; 1958 break;
1949 case '<': 1959 case '<':
1950 left = arg_num_eval(arg->op.left); 1960 ret = arg_num_eval(arg->op.left, &left);
1951 right = arg_num_eval(arg->op.right); 1961 if (!ret)
1962 break;
1963 ret = arg_num_eval(arg->op.right, &right);
1964 if (!ret)
1965 break;
1952 switch (arg->op.op[1]) { 1966 switch (arg->op.op[1]) {
1953 case 0: 1967 case 0:
1954 val = left < right; 1968 *val = left < right;
1955 break; 1969 break;
1956 case '<': 1970 case '<':
1957 val = left << right; 1971 *val = left << right;
1958 break; 1972 break;
1959 case '=': 1973 case '=':
1960 val = left <= right; 1974 *val = left <= right;
1961 break; 1975 break;
1962 default: 1976 default:
1963 die("unknown op '%s'", arg->op.op); 1977 do_warning("unknown op '%s'", arg->op.op);
1978 ret = 0;
1964 } 1979 }
1965 break; 1980 break;
1966 case '>': 1981 case '>':
1967 left = arg_num_eval(arg->op.left); 1982 ret = arg_num_eval(arg->op.left, &left);
1968 right = arg_num_eval(arg->op.right); 1983 if (!ret)
1984 break;
1985 ret = arg_num_eval(arg->op.right, &right);
1986 if (!ret)
1987 break;
1969 switch (arg->op.op[1]) { 1988 switch (arg->op.op[1]) {
1970 case 0: 1989 case 0:
1971 val = left > right; 1990 *val = left > right;
1972 break; 1991 break;
1973 case '>': 1992 case '>':
1974 val = left >> right; 1993 *val = left >> right;
1975 break; 1994 break;
1976 case '=': 1995 case '=':
1977 val = left >= right; 1996 *val = left >= right;
1978 break; 1997 break;
1979 default: 1998 default:
1980 die("unknown op '%s'", arg->op.op); 1999 do_warning("unknown op '%s'", arg->op.op);
2000 ret = 0;
1981 } 2001 }
1982 break; 2002 break;
1983 case '=': 2003 case '=':
1984 left = arg_num_eval(arg->op.left); 2004 ret = arg_num_eval(arg->op.left, &left);
1985 right = arg_num_eval(arg->op.right); 2005 if (!ret)
1986 2006 break;
1987 if (arg->op.op[1] != '=') 2007 ret = arg_num_eval(arg->op.right, &right);
1988 die("unknown op '%s'", arg->op.op); 2008 if (!ret)
2009 break;
1989 2010
1990 val = left == right; 2011 if (arg->op.op[1] != '=') {
2012 do_warning("unknown op '%s'", arg->op.op);
2013 ret = 0;
2014 } else
2015 *val = left == right;
1991 break; 2016 break;
1992 case '!': 2017 case '!':
1993 left = arg_num_eval(arg->op.left); 2018 ret = arg_num_eval(arg->op.left, &left);
1994 right = arg_num_eval(arg->op.right); 2019 if (!ret)
2020 break;
2021 ret = arg_num_eval(arg->op.right, &right);
2022 if (!ret)
2023 break;
1995 2024
1996 switch (arg->op.op[1]) { 2025 switch (arg->op.op[1]) {
1997 case '=': 2026 case '=':
1998 val = left != right; 2027 *val = left != right;
1999 break; 2028 break;
2000 default: 2029 default:
2001 die("unknown op '%s'", arg->op.op); 2030 do_warning("unknown op '%s'", arg->op.op);
2031 ret = 0;
2002 } 2032 }
2003 break; 2033 break;
2004 case '-': 2034 case '-':
@@ -2006,12 +2036,17 @@ static long long arg_num_eval(struct print_arg *arg)
2006 if (arg->op.left->type == PRINT_NULL) 2036 if (arg->op.left->type == PRINT_NULL)
2007 left = 0; 2037 left = 0;
2008 else 2038 else
2009 left = arg_num_eval(arg->op.left); 2039 ret = arg_num_eval(arg->op.left, &left);
2010 right = arg_num_eval(arg->op.right); 2040 if (!ret)
2011 val = left - right; 2041 break;
2042 ret = arg_num_eval(arg->op.right, &right);
2043 if (!ret)
2044 break;
2045 *val = left - right;
2012 break; 2046 break;
2013 default: 2047 default:
2014 die("unknown op '%s'", arg->op.op); 2048 do_warning("unknown op '%s'", arg->op.op);
2049 ret = 0;
2015 } 2050 }
2016 break; 2051 break;
2017 2052
@@ -2020,10 +2055,11 @@ static long long arg_num_eval(struct print_arg *arg)
2020 case PRINT_STRING: 2055 case PRINT_STRING:
2021 case PRINT_BSTRING: 2056 case PRINT_BSTRING:
2022 default: 2057 default:
2023 die("invalid eval type %d", arg->type); 2058 do_warning("invalid eval type %d", arg->type);
2059 ret = 0;
2024 2060
2025 } 2061 }
2026 return val; 2062 return ret;
2027} 2063}
2028 2064
2029static char *arg_eval (struct print_arg *arg) 2065static char *arg_eval (struct print_arg *arg)
@@ -2037,7 +2073,8 @@ static char *arg_eval (struct print_arg *arg)
2037 case PRINT_TYPE: 2073 case PRINT_TYPE:
2038 return arg_eval(arg->typecast.item); 2074 return arg_eval(arg->typecast.item);
2039 case PRINT_OP: 2075 case PRINT_OP:
2040 val = arg_num_eval(arg); 2076 if (!arg_num_eval(arg, &val))
2077 break;
2041 sprintf(buf, "%lld", val); 2078 sprintf(buf, "%lld", val);
2042 return buf; 2079 return buf;
2043 2080
@@ -2079,6 +2116,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2079 memset(field, 0, sizeof(*field)); 2116 memset(field, 0, sizeof(*field));
2080 2117
2081 value = arg_eval(arg); 2118 value = arg_eval(arg);
2119 if (value == NULL)
2120 goto out_free;
2082 field->value = strdup(value); 2121 field->value = strdup(value);
2083 2122
2084 free_arg(arg); 2123 free_arg(arg);
@@ -2090,6 +2129,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2090 goto out_free; 2129 goto out_free;
2091 2130
2092 value = arg_eval(arg); 2131 value = arg_eval(arg);
2132 if (value == NULL)
2133 goto out_free;
2093 field->str = strdup(value); 2134 field->str = strdup(value);
2094 free_arg(arg); 2135 free_arg(arg);
2095 arg = NULL; 2136 arg = NULL;