aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Veenstra <veenstra@android.com>2009-05-09 11:54:37 -0700
committerJack Veenstra <veenstra@android.com>2009-05-11 17:18:08 -0700
commit921168fdb0cee8ae041df6308b49765b2a98ed74 (patch)
tree214167ca87ca777d931896c3c472eb9e1be36f94
parent14d7a99cffd1d494e52a8d31b4effd413ce21456 (diff)
downloadsdk-921168fdb0cee8ae041df6308b49765b2a98ed74.zip
sdk-921168fdb0cee8ae041df6308b49765b2a98ed74.tar.gz
sdk-921168fdb0cee8ae041df6308b49765b2a98ed74.tar.bz2
Better output for viewing the method trace.
This now keeps track of the names of the methods on the stack instead of just the addresses. This makes it easier to debug when something goes wrong.
-rw-r--r--emulator/qtools/parse_options-inl.h8
-rw-r--r--emulator/qtools/read_method.cpp82
2 files changed, 89 insertions, 1 deletions
diff --git a/emulator/qtools/parse_options-inl.h b/emulator/qtools/parse_options-inl.h
index f218cc1..beb9df4 100644
--- a/emulator/qtools/parse_options-inl.h
+++ b/emulator/qtools/parse_options-inl.h
@@ -42,6 +42,14 @@ inline bool IsValidEvent(BBEvent *event, symbol_type *sym)
return true;
}
+inline bool IsValidPid(int pid) {
+ if (include_some_pids && pid_include_vector.GetBit(pid) == 0)
+ return false;
+ if (exclude_some_pids && pid_exclude_vector.GetBit(pid))
+ return false;
+ return true;
+}
+
inline symbol_type *GetSymbol(TraceReaderType *trace, int pid, uint32_t addr,
uint64_t time)
{
diff --git a/emulator/qtools/read_method.cpp b/emulator/qtools/read_method.cpp
index e48edad..48be25a 100644
--- a/emulator/qtools/read_method.cpp
+++ b/emulator/qtools/read_method.cpp
@@ -9,6 +9,63 @@ typedef TraceReader<> TraceReaderType;
#include "parse_options-inl.h"
+struct frame {
+ uint64_t time;
+ uint32_t addr;
+ const char *name;
+
+ frame(uint64_t time, uint32_t addr, const char *name) {
+ this->time = time;
+ this->addr = addr;
+ this->name = name;
+ }
+};
+
+class Stack {
+ static const int kMaxFrames = 1000;
+ int top;
+ frame *frames[kMaxFrames];
+
+public:
+ Stack() {
+ top = 0;
+ }
+
+ void push(frame *pframe);
+ frame* pop();
+ void dump();
+};
+
+void Stack::push(frame *pframe) {
+ if (top == kMaxFrames) {
+ fprintf(stderr, "Error: stack overflow\n");
+ exit(1);
+ }
+ frames[top] = pframe;
+ top += 1;
+}
+
+frame *Stack::pop() {
+ if (top <= 0)
+ return NULL;
+ top -= 1;
+ return frames[top];
+}
+
+void Stack::dump() {
+ frame *pframe;
+
+ for (int ii = 0; ii < top; ii++) {
+ pframe = frames[ii];
+ printf(" %d: %llu 0x%x %s\n",
+ ii, pframe->time, pframe->addr,
+ pframe->name == NULL ? "" : pframe->name);
+ }
+}
+
+static const int kMaxThreads = (32 * 1024);
+Stack *stacks[kMaxThreads];
+
void Usage(const char *program)
{
fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
@@ -34,9 +91,14 @@ int main(int argc, char **argv) {
MethodRec method_record;
symbol_type *sym;
TraceReaderType::ProcessState *proc;
+ frame *pframe;
if (trace->ReadMethodSymbol(&method_record, &sym, &proc))
break;
+
+ if (!IsValidPid(proc->pid))
+ continue;
+
if (sym != NULL) {
printf("%lld p %d 0x%x %d %s\n",
method_record.time, proc->pid, method_record.addr,
@@ -46,7 +108,25 @@ int main(int argc, char **argv) {
method_record.time, proc->pid, method_record.addr,
method_record.flags);
}
- proc->DumpStack();
+
+ // Get the stack for the current thread
+ Stack *pStack = stacks[proc->pid];
+
+ // If the stack does not exist, then allocate a new one.
+ if (pStack == NULL) {
+ pStack = new Stack();
+ stacks[proc->pid] = pStack;
+ }
+
+ if (method_record.flags == 0) {
+ pframe = new frame(method_record.time, method_record.addr,
+ sym == NULL ? NULL: sym->name);
+ pStack->push(pframe);
+ } else {
+ pframe = pStack->pop();
+ delete pframe;
+ }
+ pStack->dump();
}
return 0;
}