diff --git a/src/ftracetool.c b/src/ftracetool.c index 7fbb332..5234979 100644 --- a/src/ftracetool.c +++ b/src/ftracetool.c @@ -17,6 +17,12 @@ #define CLEANUP(f) __attribute__((cleanup(f))) +enum Error_codes +{ + ER_COMMENT = 10000, + ER_PARSE_ERROR = 20000, +}; + static const char gs_ftracetool_scm[] = { #include "ftracetool_scm.h" }; @@ -312,7 +318,8 @@ static int parse_ftrace_entry(const char *str, char *pid_buf, char *timestamp_buf, char *probe_id_buf, - char *args_buf) + char **args, + size_t *args_num) { // skip whitespaces while (isspace(*str)) @@ -321,7 +328,11 @@ static int parse_ftrace_entry(const char *str, } if (!*str) { - return -1; + return ER_PARSE_ERROR + 1; + } + if (*str == '#') + { + return ER_COMMENT; } char *out = comm_buf; @@ -329,14 +340,14 @@ static int parse_ftrace_entry(const char *str, { if (!*str) { - return -2; + return ER_PARSE_ERROR + 2; } // TODO check out buf overflow *out++ = *str++; } if (!*str) { - return -3; + return ER_PARSE_ERROR + 3; } *out = 0; str++; // Skip '- @@ -346,7 +357,7 @@ static int parse_ftrace_entry(const char *str, { if (!*str) { - return -4; + return ER_PARSE_ERROR + 4; } // TODO check out buf overflow @@ -361,12 +372,12 @@ static int parse_ftrace_entry(const char *str, } if (!*str) { - return -5; + return ER_PARSE_ERROR + 5; } str++; if (!*str) { - return -6; + return ER_PARSE_ERROR + 6; } // skip whitespaces && flags @@ -376,7 +387,7 @@ static int parse_ftrace_entry(const char *str, } if (!*str) { - return -7; + return ER_PARSE_ERROR + 7; } out = timestamp_buf; @@ -384,7 +395,7 @@ static int parse_ftrace_entry(const char *str, { if (!*str) { - return -8; + return ER_PARSE_ERROR + 8; } // TODO check out buf overflow @@ -394,7 +405,7 @@ static int parse_ftrace_entry(const char *str, if (*str != ':') { - return -9; + return ER_PARSE_ERROR + 9; } str++; // skip whitespaces @@ -404,7 +415,7 @@ static int parse_ftrace_entry(const char *str, } if (!*str) { - return -10; + return ER_PARSE_ERROR + 10; } out = probe_id_buf; @@ -412,7 +423,7 @@ static int parse_ftrace_entry(const char *str, { if (!*str) { - return -11; + return ER_PARSE_ERROR + 11; } // TODO check out buf overflow *out++ = *str++; @@ -426,25 +437,44 @@ static int parse_ftrace_entry(const char *str, } if (!*str) { - return -12; + return ER_PARSE_ERROR + 12; } str++; if (!*str) { - return -13; + return ER_PARSE_ERROR + 13; } - out = args_buf; + size_t arg_num = 0; while (*str) { + const char *start = NULL; + while (*str && *str != '=') + { + str++; + } if (!*str) { - return -14; + break; } - // TODO check out buf overflow - *out++ = *str++; + start = str + 1; + while (*str && *str != ' ') + { + str++; + } + const char *end = str; + + const size_t string_length = end - start + 2; + args[arg_num] = calloc(1, string_length); + if (!args[arg_num]) + { + return ER_PARSE_ERROR + 15; + } + memcpy(args[arg_num], start, string_length - 1); + arg_num++; } - *out = 0; + + *args_num = arg_num; return 0; } @@ -452,7 +482,6 @@ static int parse_ftrace_entry(const char *str, static sexp sexp_parse_ftrace_entry_stub(sexp ctx, sexp self, sexp_sint_t n, sexp arg0) { - sexp res; int ret = 0; if (!sexp_stringp(arg0)) { @@ -462,15 +491,23 @@ sexp_parse_ftrace_entry_stub(sexp ctx, sexp self, sexp_sint_t n, sexp arg0) char pid_buf[32]; char timestamp_buf[64]; char probe_id_buf[64]; - char args[128]; + char *args[128]; + size_t args_num = 0; ret = parse_ftrace_entry(sexp_string_data(arg0), comm_buf, pid_buf, timestamp_buf, probe_id_buf, - args); + args, + &args_num); + if (ret == ER_COMMENT) + { + return SEXP_FALSE; + } if (ret) { + fprintf(stderr, "parse_ftrace_entry failed with %d\n", ret); + fprintf(stderr, "%s\n", sexp_string_data(arg0)); return SEXP_FALSE; } unsigned long pid = atoi(pid_buf); @@ -479,6 +516,14 @@ sexp_parse_ftrace_entry_stub(sexp ctx, sexp self, sexp_sint_t n, sexp arg0) char *frac = dot + 1; double timestamp = atol(timestamp_buf) + atol(frac) / 1000000.; + sexp prev = SEXP_NULL; + sexp head = SEXP_NULL; + for (ssize_t arg_num = args_num - 1; arg_num >= 0; arg_num--) + { + head = sexp_cons(ctx, sexp_c_string(ctx, args[arg_num], -1), prev); + prev = head; + } + return sexp_cons( ctx, sexp_c_string(ctx, comm_buf, -1), @@ -488,9 +533,7 @@ sexp_parse_ftrace_entry_stub(sexp ctx, sexp self, sexp_sint_t n, sexp arg0) sexp_make_flonum(ctx, timestamp), sexp_cons(ctx, sexp_c_string(ctx, probe_id_buf, -1), - sexp_cons(ctx, - sexp_c_string(ctx, args, -1), - SEXP_NULL))))); + sexp_cons(ctx, head, SEXP_NULL))))); } static int register_lookup_symbol_in_file(sexp ctx) diff --git a/src/ftracetool.scm b/src/ftracetool.scm index e2b8378..a5f0d12 100644 --- a/src/ftracetool.scm +++ b/src/ftracetool.scm @@ -243,8 +243,7 @@ (timestamp (list-ref match 2)) (probe-name (list-ref match 3)) (args (list-ref match 4)) - (parsed-args (parse-arguments args)) - (trace-event (make-trace-event timestamp probe-name pid (parse-arguments args)))) + (trace-event (make-trace-event timestamp probe-name pid args))) (loop (read-line p) (cons trace-event events) (+ 1 n))) (loop (read-line p) events n)))))))))))