Browse Source

C-based ftrace entry parser

master
Denis Tereshkin 6 months ago
parent
commit
8217e259b9
  1. 93
      src/ftracetool.c
  2. 3
      src/ftracetool.scm

93
src/ftracetool.c

@ -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++;
}
*out = 0;
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++;
}
*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)

3
src/ftracetool.scm

@ -243,8 +243,7 @@ @@ -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)))))))))))

Loading…
Cancel
Save