Browse Source

max-lines, fix parser

master
Denis Tereshkin 6 months ago
parent
commit
31d0f9d934
  1. 53
      src/ftracetool.c
  2. 77
      src/ftracetool.scm

53
src/ftracetool.c

@ -34,6 +34,8 @@ struct ftt_mapping
struct ftt_mapping *next; struct ftt_mapping *next;
}; };
static int g_max_lines = 0;
static struct ftt_mapping *gs_mappings; static struct ftt_mapping *gs_mappings;
static struct ftt_mapping *parse_mapping(const char *const raw_str) static struct ftt_mapping *parse_mapping(const char *const raw_str)
@ -92,6 +94,16 @@ static int embed_mappings(sexp ctx)
sexp_gc_release2(ctx); sexp_gc_release2(ctx);
} }
static int embed_options(sexp ctx)
{
sexp_gc_var2(option_name, option_value);
sexp_gc_preserve2(ctx, option_name, option_value);
option_name = sexp_intern(ctx, "*max-lines*", -1);
option_value = sexp_make_fixnum(g_max_lines);
sexp_env_define(ctx, sexp_context_env(ctx), option_name, option_value);
sexp_gc_release2(ctx);
}
static void show_version() static void show_version()
{ {
printf("ftracetool v%s\n", VERSION_STRING); printf("ftracetool v%s\n", VERSION_STRING);
@ -321,22 +333,13 @@ static int parse_ftrace_entry(const char *str,
char **args, char **args,
size_t *args_num) size_t *args_num)
{ {
// skip whitespaces
while (isspace(*str))
{
str++;
}
if (!*str)
{
return ER_PARSE_ERROR + 1;
}
if (*str == '#') if (*str == '#')
{ {
return ER_COMMENT; return ER_COMMENT;
} }
char *out = comm_buf; char *out = comm_buf;
while (*str != '-') for (size_t i = 0; i < 16; i++)
{ {
if (!*str) if (!*str)
{ {
@ -381,7 +384,7 @@ static int parse_ftrace_entry(const char *str,
} }
// skip whitespaces && flags // skip whitespaces && flags
while (isspace(*str) || isalpha(*str)) while (isspace(*str) || isalpha(*str) || *str == '.')
{ {
str++; str++;
} }
@ -512,25 +515,23 @@ sexp_parse_ftrace_entry_stub(sexp ctx, sexp self, sexp_sint_t n, sexp arg0)
char *frac = dot + 1; char *frac = dot + 1;
double timestamp = atol(timestamp_buf) + atol(frac) / 1000000.; double timestamp = atol(timestamp_buf) + atol(frac) / 1000000.;
sexp prev = SEXP_NULL; sexp_gc_var5(prev, head, res, tmp, data);
sexp head = SEXP_NULL; sexp_gc_preserve5(ctx, prev, head, res, tmp, data);
for (ssize_t arg_num = args_num - 1; arg_num >= 0; arg_num--) 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); head = sexp_cons(ctx, sexp_c_string(ctx, args[arg_num], -1), prev);
prev = head; prev = head;
free(args[arg_num]); free(args[arg_num]);
} }
tmp = sexp_cons(ctx, head, SEXP_NULL);
tmp = sexp_cons(ctx, data = sexp_c_string(ctx, probe_id_buf, -1), tmp);
tmp = sexp_cons(ctx, data = sexp_make_flonum(ctx, timestamp), tmp);
tmp = sexp_cons(ctx, data = sexp_make_fixnum(pid), tmp);
tmp = sexp_cons(ctx, data = sexp_c_string(ctx, comm_buf, -1), tmp);
return sexp_cons( res = tmp;
ctx, sexp_gc_release5(ctx);
sexp_c_string(ctx, comm_buf, -1), return res;
sexp_cons(ctx,
sexp_make_fixnum(pid),
sexp_cons(ctx,
sexp_make_flonum(ctx, timestamp),
sexp_cons(ctx,
sexp_c_string(ctx, probe_id_buf, -1),
sexp_cons(ctx, head, SEXP_NULL)))));
} }
static int register_lookup_symbol_in_file(sexp ctx) static int register_lookup_symbol_in_file(sexp ctx)
@ -680,6 +681,7 @@ static int do_execute_script(const char *const filename)
sexp_load_standard_env(ctx, NULL, SEXP_SEVEN); sexp_load_standard_env(ctx, NULL, SEXP_SEVEN);
sexp_load_standard_ports(ctx, NULL, stdin, stdout, stderr, 1); sexp_load_standard_ports(ctx, NULL, stdin, stdout, stderr, 1);
embed_mappings(ctx); embed_mappings(ctx);
embed_options(ctx);
sexp_gc_var1(filename_obj); sexp_gc_var1(filename_obj);
@ -743,6 +745,11 @@ int main(int argc, char **argv)
show_symbols_in_file = true; show_symbols_in_file = true;
break; break;
} }
case 'l':
{
g_max_lines = atoi(optarg);
break;
}
case 'm': case 'm':
{ {
struct ftt_mapping *const mapping = parse_mapping(optarg); struct ftt_mapping *const mapping = parse_mapping(optarg);

77
src/ftracetool.scm

@ -9,12 +9,13 @@
(let ((pair (assoc key *ftt-mappings*))) (let ((pair (assoc key *ftt-mappings*)))
(if pair (if pair
(cdr pair) (cdr pair)
(raise (string-append "No mapping: " key))))) #f)))
(define (mapping-int key) (define (mapping-int key)
(let ((value (mapping-str key))) (let ((value (mapping-str key)))
(when value (if value
(string->number value)))) (string->number value)
#f)))
(define (with-append-to-file file thunk) (define (with-append-to-file file thunk)
(let ((old-out (current-output-port)) (let ((old-out (current-output-port))
@ -204,64 +205,44 @@
(string-cursor-next x (string-index x #\=)) (string-cursor-next x (string-index x #\=))
(string-cursor-end x))) raw-args))) (string-cursor-end x))) raw-args)))
(define (read-trace-events-from-file filename) (define (read-trace-events-from-file filename max-lines)
(let ((rx (regexp '(: (reverse
(+ whitespace) (call-with-input-file filename
($ alnum (+ (~ "-"))) (lambda (p)
"-" (let loop ((line (read-line p))
($ word) (events '())
(+ whitespace) (n 0))
"[" (if (or (eof-object? line)
(+ num) (if max-lines (> n max-lines) #f))
"]" events
(+ whitespace) (begin
(+ (~ whitespace)) (let ((match (parse-ftrace-entry line)))
(+ whitespace) (if match
($ (+ (or num "."))) (begin
":" (let* ((comm (list-ref match 0))
(+ whitespace) (pid (list-ref match 1))
($ (+ (or alnum "_"))) (timestamp (list-ref match 2))
": (" (probe-name (list-ref match 3))
(+ (~ ")")) (args (list-ref match 4))
")" (trace-event (make-trace-event timestamp probe-name pid args)))
($ (+ any)) (loop (read-line p) (cons trace-event events) (+ 1 n))))
)))) (loop (read-line p) events n))))))))))
(reverse
(call-with-input-file filename
(lambda (p)
(let loop ((line (read-line p))
(events '())
(n 0))
(if (or (eof-object? line)
(> n 1000))
events
(begin
(let ((match (parse-ftrace-entry line)))
(if match
(let* ((comm (list-ref match 0))
(pid (list-ref match 1))
(timestamp (list-ref match 2))
(probe-name (list-ref match 3))
(args (list-ref match 4))
(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)))))))))))
(define (find-subprobe probe-name subprobes) (define (find-subprobe probe-name subprobes)
(find (lambda (x) (equal? probe-name (ftrace-probe-name x))) subprobes)) (find (lambda (x) (equal? probe-name (ftrace-probe-name x))) subprobes))
(define (ftrace-process subprobes) (define (ftrace-process subprobes)
(let ((max-lines (if (> *max-lines* 0) *max-lines* #f)))
(with-output-to-file "/sys/kernel/tracing/events/uprobes/enable" (with-output-to-file "/sys/kernel/tracing/events/uprobes/enable"
(lambda () (lambda ()
(display "0") (display "0")
(newline))) (newline)))
(let ((events (read-trace-events-from-file "/sys/kernel/tracing/trace"))) (let ((events (read-trace-events-from-file "/sys/kernel/tracing/trace" max-lines)))
(for-each (for-each
(lambda (event) (lambda (event)
(let ((probe (find-subprobe (trace-event-probe-id event) subprobes))) (let ((probe (find-subprobe (trace-event-probe-id event) subprobes)))
(when probe (when probe
((ftrace-probe-process-entry-handler probe) event))) ((ftrace-probe-process-entry-handler probe) event)))) events))))
) events)))
(define (tracing-probe ctx install remove process) (define (tracing-probe ctx install remove process)
(make-probe (lambda () (install ctx)) (make-probe (lambda () (install ctx))

Loading…
Cancel
Save