diff options
-rw-r--r-- | emulator/qtools/parse_options-inl.h | 8 | ||||
-rw-r--r-- | emulator/qtools/read_method.cpp | 82 |
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; } |