aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}