|
|
|
|
@ -17,6 +17,12 @@
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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)
@@ -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)
@@ -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)
@@ -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) |
|
|
|
|
|