• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2006 The Android Open Source Project
2 
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <inttypes.h>
7 #include <assert.h>
8 #include "trace_reader.h"
9 #include "bitvector.h"
10 #include "parse_options.h"
11 #include "armdis.h"
12 
13 typedef TraceReader<> TraceReaderType;
14 
15 #include "parse_options-inl.h"
16 #include "callstack.h"
17 
18 static uint64_t debugTime;
19 static uint64_t dumpTime = 0;
20 
21 class MyFrame : public StackFrame<symbol_type> {
22   public:
23     void    push(int stackLevel, uint64_t time, CallStackBase *base);
24     void    pop(int stackLevel, uint64_t time, CallStackBase *base);
25     void    getFrameType(char *type);
26 };
27 
28 typedef CallStack<MyFrame> CallStackType;
29 
getFrameType(char * type)30 void MyFrame::getFrameType(char *type)
31 {
32     strcpy(type, "----");
33     if (flags & kCausedException)
34         type[0] = 'e';
35     if (flags & kInterpreted)
36         type[1] = 'm';
37     if (function->region->flags & region_type::kIsKernelRegion)
38         type[2] = 'k';
39     if (function->flags & symbol_type::kIsVectorTable)
40         type[3] = 'v';
41 }
42 
push(int stackLevel,uint64_t time,CallStackBase * base)43 void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
44 {
45     char type[5];
46 
47     if (dumpTime > 0)
48         return;
49 
50     getFrameType(type);
51     printf("%llu en thr %d %s %3d", time, base->getId(), type, stackLevel);
52     for (int ii = 0; ii < stackLevel; ++ii)
53         printf(".");
54     printf(" 0x%08x %s\n", addr, function->name);
55 }
56 
pop(int stackLevel,uint64_t time,CallStackBase * base)57 void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
58 {
59     char type[5];
60 
61     if (dumpTime > 0)
62         return;
63 
64     getFrameType(type);
65     printf("%llu x  thr %d %s %3d", time, base->getId(), type, stackLevel);
66     for (int ii = 0; ii < stackLevel; ++ii)
67         printf(".");
68     printf(" 0x%08x %s\n", addr, function->name);
69 }
70 
71 static const int kNumStackFrames = 500;
72 static const int kMaxThreads = (32 * 1024);
73 CallStackType *stacks[kMaxThreads];
74 
Usage(const char * program)75 void Usage(const char *program)
76 {
77     fprintf(stderr, "Usage: %s [options] [-- -d dumpTime] trace_name elf_file\n",
78             program);
79     OptionsUsage();
80 }
81 
localParseOptions(int argc,char ** argv)82 bool localParseOptions(int argc, char **argv)
83 {
84     bool err = false;
85     while (!err) {
86         int opt = getopt(argc, argv, "+d:");
87         if (opt == -1)
88             break;
89         switch (opt) {
90         case 'd':
91             dumpTime = strtoull(optarg, NULL, 0);
92             break;
93         default:
94             err = true;
95             break;
96         }
97     }
98     return err;
99 }
100 
main(int argc,char ** argv)101 int main(int argc, char **argv)
102 {
103     ParseOptions(argc, argv);
104     localParseOptions(argc, argv);
105     if (argc - optind != 2) {
106         Usage(argv[0]);
107         exit(1);
108     }
109 
110     char *qemu_trace_file = argv[optind++];
111     char *elf_file = argv[optind++];
112     TraceReaderType *trace = new TraceReaderType;
113     trace->Open(qemu_trace_file);
114     trace->ReadKernelSymbols(elf_file);
115     trace->SetRoot(root);
116 
117     BBEvent event;
118     while (1) {
119         BBEvent ignored;
120         symbol_type *function;
121 
122         if (GetNextValidEvent(trace, &event, &ignored, &function))
123             break;
124         if (event.bb_num == 0)
125             break;
126 
127         // Get the stack for the current thread
128         CallStackType *pStack = stacks[event.pid];
129 
130         // If the stack does not exist, then allocate a new one.
131         if (pStack == NULL) {
132             pStack = new CallStackType(event.pid, kNumStackFrames, trace);
133             stacks[event.pid] = pStack;
134         }
135         if (debugTime != 0 && event.time >= debugTime)
136             printf("debug time: %lld\n", debugTime);
137 
138         // Update the stack
139         pStack->updateStack(&event, function);
140 
141         // If the user requested a stack dump at a certain time,
142         // and we are at that time, then dump the stack and exit.
143         if (dumpTime > 0 && event.time >= dumpTime) {
144             pStack->showStack(stdout);
145             break;
146         }
147     }
148 
149     for (int ii = 0; ii < kMaxThreads; ++ii) {
150         if (stacks[ii])
151             stacks[ii]->popAll(event.time);
152     }
153 
154     delete trace;
155     return 0;
156 }
157