blob: 6aa0c1a7dab783689bb0d0f2d4106319b32b2179 [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;
Jack Veenstraa476e452009-05-19 16:47:04 -070016 bool isNative;
Jack Veenstra447a4e42009-05-09 11:54:37 -070017
Jack Veenstraa476e452009-05-19 16:47:04 -070018 frame(uint64_t time, uint32_t addr, const char *name, bool isNative) {
Jack Veenstra447a4e42009-05-09 11:54:37 -070019 this->time = time;
20 this->addr = addr;
21 this->name = name;
Jack Veenstraa476e452009-05-19 16:47:04 -070022 this->isNative = isNative;
Jack Veenstra447a4e42009-05-09 11:54:37 -070023 }
24};
25
26class Stack {
27 static const int kMaxFrames = 1000;
28 int top;
29 frame *frames[kMaxFrames];
30
31public:
32 Stack() {
33 top = 0;
34 }
35
36 void push(frame *pframe);
37 frame* pop();
38 void dump();
39};
40
41void Stack::push(frame *pframe) {
42 if (top == kMaxFrames) {
43 fprintf(stderr, "Error: stack overflow\n");
44 exit(1);
45 }
46 frames[top] = pframe;
47 top += 1;
48}
49
50frame *Stack::pop() {
51 if (top <= 0)
52 return NULL;
53 top -= 1;
54 return frames[top];
55}
56
57void Stack::dump() {
58 frame *pframe;
59
60 for (int ii = 0; ii < top; ii++) {
61 pframe = frames[ii];
Jack Veenstraa476e452009-05-19 16:47:04 -070062 const char *native = pframe->isNative ? "n" : " ";
63 printf(" %s %d: %llu 0x%x %s\n",
64 native, ii, pframe->time, pframe->addr,
Jack Veenstra447a4e42009-05-09 11:54:37 -070065 pframe->name == NULL ? "" : pframe->name);
66 }
67}
68
69static const int kMaxThreads = (32 * 1024);
70Stack *stacks[kMaxThreads];
71
The Android Open Source Project52d4c302009-03-03 19:29:09 -080072void Usage(const char *program)
73{
74 fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
75 program);
76 OptionsUsage();
77}
78
79int main(int argc, char **argv) {
80 ParseOptions(argc, argv);
81 if (argc - optind != 2) {
82 Usage(argv[0]);
83 exit(1);
84 }
85
86 char *qemu_trace_file = argv[optind++];
87 char *elf_file = argv[optind++];
88 TraceReaderType *trace = new TraceReaderType;
89 trace->Open(qemu_trace_file);
90 trace->ReadKernelSymbols(elf_file);
91 trace->SetRoot(root);
92
93 while (1) {
94 MethodRec method_record;
95 symbol_type *sym;
96 TraceReaderType::ProcessState *proc;
Jack Veenstra447a4e42009-05-09 11:54:37 -070097 frame *pframe;
The Android Open Source Project52d4c302009-03-03 19:29:09 -080098
99 if (trace->ReadMethodSymbol(&method_record, &sym, &proc))
100 break;
Jack Veenstra447a4e42009-05-09 11:54:37 -0700101
102 if (!IsValidPid(proc->pid))
103 continue;
104
The Android Open Source Project52d4c302009-03-03 19:29:09 -0800105 if (sym != NULL) {
106 printf("%lld p %d 0x%x %d %s\n",
107 method_record.time, proc->pid, method_record.addr,
108 method_record.flags, sym->name);
109 } else {
110 printf("%lld p %d 0x%x %d\n",
111 method_record.time, proc->pid, method_record.addr,
112 method_record.flags);
113 }
Jack Veenstra447a4e42009-05-09 11:54:37 -0700114
115 // Get the stack for the current thread
116 Stack *pStack = stacks[proc->pid];
117
118 // If the stack does not exist, then allocate a new one.
119 if (pStack == NULL) {
120 pStack = new Stack();
121 stacks[proc->pid] = pStack;
122 }
123
Jack Veenstraa476e452009-05-19 16:47:04 -0700124 int flags = method_record.flags;
125 if (flags == kMethodEnter || flags == kNativeEnter) {
Jack Veenstra447a4e42009-05-09 11:54:37 -0700126 pframe = new frame(method_record.time, method_record.addr,
Jack Veenstraa476e452009-05-19 16:47:04 -0700127 sym == NULL ? NULL: sym->name,
128 method_record.flags == kNativeEnter);
Jack Veenstra447a4e42009-05-09 11:54:37 -0700129 pStack->push(pframe);
130 } else {
131 pframe = pStack->pop();
132 delete pframe;
133 }
134 pStack->dump();
The Android Open Source Project52d4c302009-03-03 19:29:09 -0800135 }
136 return 0;
137}