| Index: dump.c
|
| diff --git a/dump.c b/dump.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b298a55d9d697786a7979c4789fafdad06865331
|
| --- /dev/null
|
| +++ b/dump.c
|
| @@ -0,0 +1,160 @@
|
| +/*
|
| + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
| + * Distributed under the terms of the GNU General Public License v2
|
| + */
|
| +
|
| +#include <stdio.h>
|
| +#include <unistd.h>
|
| +
|
| +#include "collector.h"
|
| +#include "ktop.h"
|
| +#include "syscall.h"
|
| +
|
| +void pr_buf(int cpu, int sz, u8 buf[sz])
|
| +{
|
| + int i;
|
| + int j;
|
| +
|
| + printf("%d. trace=%d bytes\n", cpu, sz);
|
| + for (i = 0; i < sz; i++) {
|
| + for (j = 0; j < 32; j++, i++) {
|
| + if (i == sz) goto done;
|
| + printf(" %2x", buf[i]);
|
| + }
|
| + printf("\n");
|
| + }
|
| +done:
|
| + printf("\n");
|
| +}
|
| +
|
| +static void pr_event(event_s *event)
|
| +{
|
| + printf(" type=%2u flags=%2x cnt=%2d pid=%5d lock=%2d",
|
| + event->type, event->flags, event->preempt_count, event->pid,
|
| + event->lock_depth);
|
| +}
|
| +
|
| +static void pr_sys_enter(void *event)
|
| +{
|
| + sys_enter_s *sy = event;
|
| + int i;
|
| +
|
| + printf(" %-20s", Syscall[sy->id]);
|
| + for (i = 0; i < 6; i++) {
|
| + printf(" %ld", sy->arg[i]);
|
| + }
|
| + printf("\n");
|
| +}
|
| +
|
| +static void pr_sys_exit(void *event)
|
| +{
|
| + sys_exit_s *sy = event;
|
| +
|
| + printf(" %-20s ret=%ld\n", Syscall[sy->id], sy->ret);
|
| +}
|
| +
|
| +static void pr_ring_header(ring_header_s *rh)
|
| +{
|
| + printf("%lld %lld %ld\n",
|
| + rh->time_stamp / A_BILLION, rh->time_stamp % A_BILLION,
|
| + rh->commit);
|
| +}
|
| +
|
| +static void dump_event(void *buf)
|
| +{
|
| + event_s *event = buf;
|
| +
|
| + pr_event(event);
|
| + switch (event->type) {
|
| + case 21:
|
| + pr_sys_exit(event);
|
| + break;
|
| + case 22:
|
| + pr_sys_enter(event);
|
| + break;
|
| + default:
|
| + printf(" no processing\n");
|
| + break;
|
| + }
|
| +}
|
| +
|
| +static void dump_buf(u8 *buf)
|
| +{
|
| + ring_header_s *rh = (ring_header_s *)buf;
|
| + ring_event_s *r;
|
| + unint length;
|
| + unint size;
|
| + u64 time;
|
| + u8 *end;
|
| +
|
| + pr_ring_header(rh);
|
| + time = rh->time_stamp;
|
| + buf += sizeof(*rh);
|
| + end = &buf[rh->commit];
|
| + for (; buf < end; buf += size) {
|
| + r = (ring_event_s *)buf;
|
| + printf("type_len=%2u time=%9d", r->type_len, r->time_delta);
|
| + if (r->type_len == 0) {
|
| + length = r->array[0];
|
| + size = 4 + length * 4;
|
| + time += r->time_delta;
|
| + } else if (r->type_len <= 28) {
|
| + length = r->type_len;
|
| + size = 4 + length * 4;
|
| + time += r->time_delta;
|
| + dump_event(buf+4);
|
| + } else if (r->type_len == 29) {
|
| + printf("\n");
|
| + if (r->time_delta == 0) {
|
| + return;
|
| + } else {
|
| + length = r->array[0];
|
| + size = 4 + length * 4;
|
| + }
|
| + } else if (r->type_len == 30) {
|
| + /* Extended time delta */
|
| + printf("\n");
|
| + size = 8;
|
| + time += (((u64)r->array[0]) << 28) | r->time_delta;
|
| + } else if (r->type_len == 31) {
|
| + /* Sync time with external clock (NOT IMMPLEMENTED) */
|
| + //tv_nsec = r->array[0];
|
| + //tv_sec = *(u64 *)&(r->array[1]);
|
| + } else {
|
| + printf(" Unknown event %d\n", r->type_len);
|
| + /* Unknown - ignore */
|
| + size = 4;
|
| + }
|
| + }
|
| +}
|
| +
|
| +static void dump_raw(int cpu, int sz, u8 buf[sz])
|
| +{
|
| + dump_buf(buf); // Need to do something with sz
|
| +}
|
| +
|
| +void *dump_collector(void *args)
|
| +{
|
| + Collector_args_s *a = args;
|
| + u8 buf[BUF_SIZE];
|
| + int cpu = a->cpu_id;
|
| + int trace_pipe;
|
| + int rc;
|
| + int i;
|
| +
|
| + ignore_pid(gettid());
|
| + trace_pipe = open_raw(cpu);
|
| + for (i = 0;; i++) {
|
| + rc = read(trace_pipe, buf, sizeof(buf));
|
| + printf("i=%d rc=%d\n", i, rc);
|
| + if (rc == -1) {
|
| + close(trace_pipe);
|
| + cleanup(0);
|
| + }
|
| + dump_raw(cpu, rc, buf);
|
| + if (rc < SMALL_READ) {
|
| + sleep(1); // Wait for input to accumulate
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
|
|