Add support for native (JNI) calls to the trace tools.

Also fix a bug in profile_pid.cpp and add better output to
stack_dump.cpp.
This commit is contained in:
Jack Veenstra
2009-05-19 16:47:04 -07:00
parent 2bb9bb4546
commit a476e45d1d
4 changed files with 67 additions and 19 deletions

View File

@@ -32,11 +32,13 @@ struct frame {
uint64_t time; uint64_t time;
uint32_t addr; uint32_t addr;
const char *name; const char *name;
bool isNative;
frame(uint64_t time, uint32_t addr, const char *name) { frame(uint64_t time, uint32_t addr, const char *name, bool isNative) {
this->time = time; this->time = time;
this->addr = addr; this->addr = addr;
this->name = name; this->name = name;
this->isNative = isNative;
} }
}; };
@@ -125,9 +127,11 @@ int main(int argc, char **argv)
mStacks[proc->pid] = mStack; mStacks[proc->pid] = mStack;
} }
if (method_record.flags == 0) { int flags = method_record.flags;
if (flags == kMethodEnter || flags == kNativeEnter) {
pframe = new frame(method_record.time, method_record.addr, pframe = new frame(method_record.time, method_record.addr,
sym == NULL ? NULL: sym->name); sym == NULL ? NULL: sym->name,
method_record.flags == kNativeEnter);
mStack->push(pframe); mStack->push(pframe);
} else { } else {
pframe = mStack->pop(); pframe = mStack->pop();
@@ -171,12 +175,22 @@ int main(int argc, char **argv)
void compareStacks(uint64_t time, int pid) { void compareStacks(uint64_t time, int pid) {
CallStackType *eStack = eStacks[pid]; CallStackType *eStack = eStacks[pid];
Stack *mStack = mStacks[pid]; Stack *mStack = mStacks[pid];
frame **mFrames = mStack->frames;
frame *mframe; frame *mframe;
int mTop = mStack->top; int mTop = mStack->top;
int eTop = eStack->mTop; int eTop = eStack->mTop;
CallStackType::frame_type *eFrames = eStack->mFrames; CallStackType::frame_type *eFrames = eStack->mFrames;
// Count the number of non-native methods (ie, Java methods) on the
// Java method stack
int numNonNativeMethods = 0;
for (int ii = 0; ii < mTop; ++ii) {
if (!mFrames[ii]->isNative) {
numNonNativeMethods += 1;
}
}
// Count the number of Java methods on the native stack // Count the number of Java methods on the native stack
int numMethods = 0; int numMethods = 0;
for (int ii = 0; ii < eTop; ++ii) { for (int ii = 0; ii < eTop; ++ii) {
@@ -188,9 +202,9 @@ void compareStacks(uint64_t time, int pid) {
// Verify that the number of Java methods on both stacks are the same. // Verify that the number of Java methods on both stacks are the same.
// Allow the native stack to have one less Java method because the // Allow the native stack to have one less Java method because the
// native stack might be pushing a native function first. // native stack might be pushing a native function first.
if (mTop != numMethods && mTop != numMethods + 1) { if (numNonNativeMethods != numMethods && numNonNativeMethods != numMethods + 1) {
printf("\nDiff at time %llu pid %d: mtop %d numMethods %d\n", printf("\nDiff at time %llu pid %d: non-native %d numMethods %d\n",
time, pid, mTop, numMethods); time, pid, numNonNativeMethods, numMethods);
dumpStacks(pid); dumpStacks(pid);
numErrors += 1; numErrors += 1;
if (numErrors >= kMaxErrors) if (numErrors >= kMaxErrors)
@@ -206,7 +220,12 @@ void compareStacks(uint64_t time, int pid) {
continue; continue;
uint32_t addr = eFrames[ii].function->addr; uint32_t addr = eFrames[ii].function->addr;
addr += eFrames[ii].function->region->vstart; addr += eFrames[ii].function->region->vstart;
if (addr != mStack->frames[mIndex]->addr) { while (mIndex < mTop && mFrames[mIndex]->isNative) {
mIndex += 1;
}
if (mIndex >= mTop)
break;
if (addr != mFrames[mIndex]->addr) {
printf("\nDiff at time %llu pid %d: frame %d\n", time, pid, ii); printf("\nDiff at time %llu pid %d: frame %d\n", time, pid, ii);
dumpStacks(pid); dumpStacks(pid);
exit(1); exit(1);
@@ -224,8 +243,9 @@ void dumpStacks(int pid) {
printf("\nJava method stack\n"); printf("\nJava method stack\n");
for (int ii = 0; ii < mTop; ii++) { for (int ii = 0; ii < mTop; ii++) {
mframe = mStack->frames[ii]; mframe = mStack->frames[ii];
printf(" %d: %llu 0x%x %s\n", const char *native = mframe->isNative ? "n" : " ";
ii, mframe->time, mframe->addr, printf(" %s %d: %llu 0x%x %s\n",
native, ii, mframe->time, mframe->addr,
mframe->name == NULL ? "" : mframe->name); mframe->name == NULL ? "" : mframe->name);
} }

View File

@@ -84,10 +84,11 @@ int main(int argc, char **argv) {
printf("%5d %5d %10llu %6.2f %6.2f %5s %s", printf("%5d %5d %10llu %6.2f %6.2f %5s %s",
pstate->pid, pstate->parent_pid, pstate->cpu_time, pstate->pid, pstate->parent_pid, pstate->cpu_time,
per, sum_per, print_flags, pstate->name); per, sum_per, print_flags, pstate->name);
for (int ii = 1; ii < pstate->argc; ++ii) { for (int jj = 1; jj < pstate->argc; ++jj) {
printf(" %s", pstate->argv[ii]); printf(" %s", pstate->argv[jj]);
} }
printf("\n"); printf("\n");
} }
delete trace;
return 0; return 0;
} }

View File

@@ -13,11 +13,13 @@ struct frame {
uint64_t time; uint64_t time;
uint32_t addr; uint32_t addr;
const char *name; const char *name;
bool isNative;
frame(uint64_t time, uint32_t addr, const char *name) { frame(uint64_t time, uint32_t addr, const char *name, bool isNative) {
this->time = time; this->time = time;
this->addr = addr; this->addr = addr;
this->name = name; this->name = name;
this->isNative = isNative;
} }
}; };
@@ -57,8 +59,9 @@ void Stack::dump() {
for (int ii = 0; ii < top; ii++) { for (int ii = 0; ii < top; ii++) {
pframe = frames[ii]; pframe = frames[ii];
printf(" %d: %llu 0x%x %s\n", const char *native = pframe->isNative ? "n" : " ";
ii, pframe->time, pframe->addr, printf(" %s %d: %llu 0x%x %s\n",
native, ii, pframe->time, pframe->addr,
pframe->name == NULL ? "" : pframe->name); pframe->name == NULL ? "" : pframe->name);
} }
} }
@@ -118,9 +121,11 @@ int main(int argc, char **argv) {
stacks[proc->pid] = pStack; stacks[proc->pid] = pStack;
} }
if (method_record.flags == 0) { int flags = method_record.flags;
if (flags == kMethodEnter || flags == kNativeEnter) {
pframe = new frame(method_record.time, method_record.addr, pframe = new frame(method_record.time, method_record.addr,
sym == NULL ? NULL: sym->name); sym == NULL ? NULL: sym->name,
method_record.flags == kNativeEnter);
pStack->push(pframe); pStack->push(pframe);
} else { } else {
pframe = pStack->pop(); pframe = pStack->pop();

View File

@@ -22,15 +22,33 @@ class MyFrame : public StackFrame<symbol_type> {
public: public:
void push(int stackLevel, uint64_t time, CallStackBase *base); void push(int stackLevel, uint64_t time, CallStackBase *base);
void pop(int stackLevel, uint64_t time, CallStackBase *base); void pop(int stackLevel, uint64_t time, CallStackBase *base);
void getFrameType(char *type);
}; };
typedef CallStack<MyFrame> CallStackType; typedef CallStack<MyFrame> CallStackType;
void MyFrame::getFrameType(char *type)
{
strcpy(type, "----");
if (flags & kCausedException)
type[0] = 'e';
if (flags & kInterpreted)
type[1] = 'm';
if (function->region->flags & region_type::kIsKernelRegion)
type[2] = 'k';
if (function->flags & symbol_type::kIsVectorTable)
type[3] = 'v';
}
void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base) void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
{ {
char type[5];
if (dumpTime > 0) if (dumpTime > 0)
return; return;
printf("%llu en thr %d %3d", time, base->getId(), stackLevel);
getFrameType(type);
printf("%llu en thr %d %s %3d", time, base->getId(), type, stackLevel);
for (int ii = 0; ii < stackLevel; ++ii) for (int ii = 0; ii < stackLevel; ++ii)
printf("."); printf(".");
printf(" 0x%08x %s\n", addr, function->name); printf(" 0x%08x %s\n", addr, function->name);
@@ -38,9 +56,13 @@ void MyFrame::push(int stackLevel, uint64_t time, CallStackBase *base)
void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base) void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
{ {
char type[5];
if (dumpTime > 0) if (dumpTime > 0)
return; return;
printf("%llu x thr %d %3d", time, base->getId(), stackLevel);
getFrameType(type);
printf("%llu x thr %d %s %3d", time, base->getId(), type, stackLevel);
for (int ii = 0; ii < stackLevel; ++ii) for (int ii = 0; ii < stackLevel; ++ii)
printf("."); printf(".");
printf(" 0x%08x %s\n", addr, function->name); printf(" 0x%08x %s\n", addr, function->name);
@@ -52,7 +74,7 @@ CallStackType *stacks[kMaxThreads];
void Usage(const char *program) void Usage(const char *program)
{ {
fprintf(stderr, "Usage: %s [options] trace_name elf_file\n", fprintf(stderr, "Usage: %s [options] [-- -d dumpTime] trace_name elf_file\n",
program); program);
OptionsUsage(); OptionsUsage();
} }