aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVaibhav Nagarnaik <vnagarnaik@google.com>2011-07-15 23:00:39 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-07-29 12:43:19 -0400
commitb33c8d01da95d1abdfb966eb7f91f2f0a58d8329 (patch)
tree38ca53105a867ef8ef280f535958ace77c0631d0
parentba911ea7fc1fdd13e3bce1b2001f5b432df8edae (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>
-rw-r--r--parse-events.c125
1 files changed, 83 insertions, 42 deletions
diff --git a/parse-events.c b/parse-events.c
index d8f322a..58ffe51 100644
--- a/parse-events.c
+++ b/parse-events.c
@@ -1901,90 +1901,120 @@ eval_type(unsigned long long val, struct print_arg *arg, int pointer)
1901 return eval_type_str(val, arg->typecast.type, pointer); 1901 return eval_type_str(val, arg->typecast.type, pointer);
1902} 1902}
1903 1903
1904static long long arg_num_eval(struct print_arg *arg) 1904static int arg_num_eval(struct print_arg *arg, long long *val)
1905{ 1905{
1906 long long left, right; 1906 long long left, right;
1907 long long val = 0; 1907 int ret = 1;
1908 1908
1909 switch (arg->type) { 1909 switch (arg->type) {
1910 case PRINT_ATOM: 1910 case PRINT_ATOM:
1911 val = strtoll(arg->atom.atom, NULL, 0); 1911 *val = strtoll(arg->atom.atom, NULL, 0);
1912 break; 1912 break;
1913 case PRINT_TYPE: 1913 case PRINT_TYPE:
1914 val = arg_num_eval(arg->typecast.item); 1914 ret = arg_num_eval(arg->typecast.item, val);
1915 val = eval_type(val, arg, 0); 1915 if (!ret)
1916 break;
1917 *val = eval_type(*val, arg, 0);
1916 break; 1918 break;
1917 case PRINT_OP: 1919 case PRINT_OP:
1918 switch (arg->op.op[0]) { 1920 switch (arg->op.op[0]) {
1919 case '|': 1921 case '|':
1920 left = arg_num_eval(arg->op.left); 1922 ret = arg_num_eval(arg->op.left, &left);
1921 right = arg_num_eval(arg->op.right); 1923 if (!ret)
1924 break;
1925 ret = arg_num_eval(arg->op.right, &right);
1926 if (!ret)
1927 break;
1922 if (arg->op.op[1]) 1928 if (arg->op.op[1])
1923 val = left || right; 1929 *val = left || right;
1924 else 1930 else
1925 val = left | right; 1931 *val = left | right;
1926 break; 1932 break;
1927 case '&': 1933 case '&':
1928 left = arg_num_eval(arg->op.left); 1934 ret = arg_num_eval(arg->op.left, &left);
1929 right = arg_num_eval(arg->op.right); 1935 if (!ret)
1936 break;
1937 ret = arg_num_eval(arg->op.right, &right);
1938 if (!ret)
1939 break;
1930 if (arg->op.op[1]) 1940 if (arg->op.op[1])
1931 val = left && right; 1941 *val = left && right;
1932 else 1942 else
1933 val = left & right; 1943 *val = left & right;
1934 break; 1944 break;
1935 case '<': 1945 case '<':
1936 left = arg_num_eval(arg->op.left); 1946 ret = arg_num_eval(arg->op.left, &left);
1937 right = arg_num_eval(arg->op.right); 1947 if (!ret)
1948 break;
1949 ret = arg_num_eval(arg->op.right, &right);
1950 if (!ret)
1951 break;
1938 switch (arg->op.op[1]) { 1952 switch (arg->op.op[1]) {
1939 case 0: 1953 case 0:
1940 val = left < right; 1954 *val = left < right;
1941 break; 1955 break;
1942 case '<': 1956 case '<':
1943 val = left << right; 1957 *val = left << right;
1944 break; 1958 break;
1945 case '=': 1959 case '=':
1946 val = left <= right; 1960 *val = left <= right;
1947 break; 1961 break;
1948 default: 1962 default:
1949 die("unknown op '%s'", arg->op.op); 1963 do_warning("unknown op '%s'", arg->op.op);
1964 ret = 0;
1950 } 1965 }
1951 break; 1966 break;
1952 case '>': 1967 case '>':
1953 left = arg_num_eval(arg->op.left); 1968 ret = arg_num_eval(arg->op.left, &left);
1954 right = arg_num_eval(arg->op.right); 1969 if (!ret)
1970 break;
1971 ret = arg_num_eval(arg->op.right, &right);
1972 if (!ret)
1973 break;
1955 switch (arg->op.op[1]) { 1974 switch (arg->op.op[1]) {
1956 case 0: 1975 case 0:
1957 val = left > right; 1976 *val = left > right;
1958 break; 1977 break;
1959 case '>': 1978 case '>':
1960 val = left >> right; 1979 *val = left >> right;
1961 break; 1980 break;
1962 case '=': 1981 case '=':
1963 val = left >= right; 1982 *val = left >= right;
1964 break; 1983 break;
1965 default: 1984 default:
1966 die("unknown op '%s'", arg->op.op); 1985 do_warning("unknown op '%s'", arg->op.op);
1986 ret = 0;
1967 } 1987 }
1968 break; 1988 break;
1969 case '=': 1989 case '=':
1970 left = arg_num_eval(arg->op.left); 1990 ret = arg_num_eval(arg->op.left, &left);
1971 right = arg_num_eval(arg->op.right); 1991 if (!ret)
1972 1992 break;
1973 if (arg->op.op[1] != '=') 1993 ret = arg_num_eval(arg->op.right, &right);
1974 die("unknown op '%s'", arg->op.op); 1994 if (!ret)
1995 break;
1975 1996
1976 val = left == right; 1997 if (arg->op.op[1] != '=') {
1998 do_warning("unknown op '%s'", arg->op.op);
1999 ret = 0;
2000 } else
2001 *val = left == right;
1977 break; 2002 break;
1978 case '!': 2003 case '!':
1979 left = arg_num_eval(arg->op.left); 2004 ret = arg_num_eval(arg->op.left, &left);
1980 right = arg_num_eval(arg->op.right); 2005 if (!ret)
2006 break;
2007 ret = arg_num_eval(arg->op.right, &right);
2008 if (!ret)
2009 break;
1981 2010
1982 switch (arg->op.op[1]) { 2011 switch (arg->op.op[1]) {
1983 case '=': 2012 case '=':
1984 val = left != right; 2013 *val = left != right;
1985 break; 2014 break;
1986 default: 2015 default:
1987 die("unknown op '%s'", arg->op.op); 2016 do_warning("unknown op '%s'", arg->op.op);
2017 ret = 0;
1988 } 2018 }
1989 break; 2019 break;
1990 case '-': 2020 case '-':
@@ -1992,12 +2022,17 @@ static long long arg_num_eval(struct print_arg *arg)
1992 if (arg->op.left->type == PRINT_NULL) 2022 if (arg->op.left->type == PRINT_NULL)
1993 left = 0; 2023 left = 0;
1994 else 2024 else
1995 left = arg_num_eval(arg->op.left); 2025 ret = arg_num_eval(arg->op.left, &left);
1996 right = arg_num_eval(arg->op.right); 2026 if (!ret)
1997 val = left - right; 2027 break;
2028 ret = arg_num_eval(arg->op.right, &right);
2029 if (!ret)
2030 break;
2031 *val = left - right;
1998 break; 2032 break;
1999 default: 2033 default:
2000 die("unknown op '%s'", arg->op.op); 2034 do_warning("unknown op '%s'", arg->op.op);
2035 ret = 0;
2001 } 2036 }
2002 break; 2037 break;
2003 2038
@@ -2006,10 +2041,11 @@ static long long arg_num_eval(struct print_arg *arg)
2006 case PRINT_STRING: 2041 case PRINT_STRING:
2007 case PRINT_BSTRING: 2042 case PRINT_BSTRING:
2008 default: 2043 default:
2009 die("invalid eval type %d", arg->type); 2044 do_warning("invalid eval type %d", arg->type);
2045 ret = 0;
2010 2046
2011 } 2047 }
2012 return val; 2048 return ret;
2013} 2049}
2014 2050
2015static char *arg_eval (struct print_arg *arg) 2051static char *arg_eval (struct print_arg *arg)
@@ -2023,7 +2059,8 @@ static char *arg_eval (struct print_arg *arg)
2023 case PRINT_TYPE: 2059 case PRINT_TYPE:
2024 return arg_eval(arg->typecast.item); 2060 return arg_eval(arg->typecast.item);
2025 case PRINT_OP: 2061 case PRINT_OP:
2026 val = arg_num_eval(arg); 2062 if (!arg_num_eval(arg, &val))
2063 break;
2027 sprintf(buf, "%lld", val); 2064 sprintf(buf, "%lld", val);
2028 return buf; 2065 return buf;
2029 2066
@@ -2065,6 +2102,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2065 memset(field, 0, sizeof(field)); 2102 memset(field, 0, sizeof(field));
2066 2103
2067 value = arg_eval(arg); 2104 value = arg_eval(arg);
2105 if (value == NULL)
2106 goto out_free;
2068 field->value = strdup(value); 2107 field->value = strdup(value);
2069 2108
2070 free_arg(arg); 2109 free_arg(arg);
@@ -2076,6 +2115,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2076 goto out_free; 2115 goto out_free;
2077 2116
2078 value = arg_eval(arg); 2117 value = arg_eval(arg);
2118 if (value == NULL)
2119 goto out_free;
2079 field->str = strdup(value); 2120 field->str = strdup(value);
2080 free_arg(arg); 2121 free_arg(arg);
2081 arg = NULL; 2122 arg = NULL;