blob: 48be25a9adb390d8c7302a392c3f85cd90ab6e97 [file] [log] [blame]
The Android Open Source Project52d4c302009-03-03 19:29:09 -08001#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <inttypes.h>
5#include "trace_reader.h"
6#include "parse_options.h"
7
8typedef TraceReader<> TraceReaderType;
9
10#include "parse_options-inl.h"
11
Jack Veenstra447a4e42009-05-09 11:54:37 -070012struct frame {
13 uint64_t time;
14 uint32_t addr;
15 const char *name;
16
17 frame(uint64_t time, uint32_t addr, const char *name) {
18 this->time = time;
19 this->addr = addr;
20 this->name = name;
21 }
22};
23
24class Stack {
25 static const int kMaxFrames = 1000;
26 int top;
27 frame *frames[kMaxFrames];
28
29public:
30 Stack() {
31 top = 0;
32 }
33
34 void push(frame *pframe);
35 frame* pop();
36 void dump();
37};
38
39void Stack::push(frame *pframe) {
40 if (top == kMaxFrames) {
41 fprintf(stderr, "Error: stack overflow\n");
42 exit(1);
43 }
44 frames[top] = pframe;
45 top += 1;
46}
47
48frame *Stack::pop() {
49 if (top <= 0)
50 return NULL;
51 top -= 1;
52 return frames[top];
53}
54
55void Stack::dump() {
56 frame *pframe;
57
58 for (int ii = 0; ii < top; ii++) {
59 pframe = frames[ii];
60 printf(" %d: %llu 0x%x %s\n",
61 ii, pframe->time, pframe->addr,
62 pframe->name == NULL ? "" : pframe->name);
63 }
64}
65
66static const int kMaxThreads = (32 * 1024);
67Stack *stacks[kMaxThreads];
68
The Android Open Source Project52d4c302009-03-03 19:29:09 -080069void Usage(const char *program)
70{
71 fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
72 program);
73 OptionsUsage();
74}
75
76int main(int argc, char **argv) {
77 ParseOptions(argc, argv);
78 if (argc - optind != 2) {
79 Usage(argv[0]);
80 exit(1);
81 }
82
83 char *qemu_trace_file = argv[optind++];
84 char *elf_file = argv[optind++];
85 TraceReaderType *trace = new TraceReaderType;
86 trace->Open(qemu_trace_file);
87 trace->ReadKernelSymbols(elf_file);
88 trace->SetRoot(root);
89
90 while (1) {
91 MethodRec method_record;
92 symbol_type *sym;
93 TraceReaderType::ProcessState *proc;
Jack Veenstra447a4e42009-05-09 11:54:37 -070094 frame *pframe;
The Android Open Source Project52d4c302009-03-03 19:29:09 -080095
96 if (trace->ReadMethodSymbol(&method_record, &sym, &proc))
97 break;
Jack Veenstra447a4e42009-05-09 11:54:37 -070098
99 if (!IsValidPid(proc->pid))
100 continue;
101
The Android Open Source Project52d4c302009-03-03 19:29:09 -0800102 if (sym != NULL) {
103 printf("%lld p %d 0x%x %d %s\n",
104 method_record.time, proc->pid, method_record.addr,
105 method_record.flags, sym->name);
106 } else {
107 printf("%lld p %d 0x%x %d\n",
108 method_record.time, proc->pid, method_record.addr,
109 method_record.flags);
110 }
Jack Veenstra447a4e42009-05-09 11:54:37 -0700111
112 // Get the stack for the current thread
113 Stack *pStack = stacks[proc->pid];
114
115 // If the stack does not exist, then allocate a new one.
116 if (pStack == NULL) {
117 pStack = new Stack();
118 stacks[proc->pid] = pStack;
119 }
120
121 if (method_record.flags == 0) {
122 pframe = new frame(method_record.time, method_record.addr,
123 sym == NULL ? NULL: sym->name);
124 pStack->push(pframe);
125 } else {
126 pframe = pStack->pop();
127 delete pframe;
128 }
129 pStack->dump();
The Android Open Source Project52d4c302009-03-03 19:29:09 -0800130 }
131 return 0;
132}