uint64_t time;
uint32_t addr;
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->addr = addr;
this->name = name;
+ this->isNative = isNative;
}
};
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,
- sym == NULL ? NULL: sym->name);
+ sym == NULL ? NULL: sym->name,
+ method_record.flags == kNativeEnter);
mStack->push(pframe);
} else {
pframe = mStack->pop();
void compareStacks(uint64_t time, int pid) {
CallStackType *eStack = eStacks[pid];
Stack *mStack = mStacks[pid];
+ frame **mFrames = mStack->frames;
frame *mframe;
int mTop = mStack->top;
int eTop = eStack->mTop;
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
int numMethods = 0;
for (int ii = 0; ii < eTop; ++ii) {
// 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
// native stack might be pushing a native function first.
- if (mTop != numMethods && mTop != numMethods + 1) {
- printf("\nDiff at time %llu pid %d: mtop %d numMethods %d\n",
- time, pid, mTop, numMethods);
+ if (numNonNativeMethods != numMethods && numNonNativeMethods != numMethods + 1) {
+ printf("\nDiff at time %llu pid %d: non-native %d numMethods %d\n",
+ time, pid, numNonNativeMethods, numMethods);
dumpStacks(pid);
numErrors += 1;
if (numErrors >= kMaxErrors)
continue;
uint32_t addr = eFrames[ii].function->addr;
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);
dumpStacks(pid);
exit(1);
printf("\nJava method stack\n");
for (int ii = 0; ii < mTop; ii++) {
mframe = mStack->frames[ii];
- printf(" %d: %llu 0x%x %s\n",
- ii, mframe->time, mframe->addr,
+ const char *native = mframe->isNative ? "n" : " ";
+ printf(" %s %d: %llu 0x%x %s\n",
+ native, ii, mframe->time, mframe->addr,
mframe->name == NULL ? "" : mframe->name);
}
printf("%5d %5d %10llu %6.2f %6.2f %5s %s",
pstate->pid, pstate->parent_pid, pstate->cpu_time,
per, sum_per, print_flags, pstate->name);
- for (int ii = 1; ii < pstate->argc; ++ii) {
- printf(" %s", pstate->argv[ii]);
+ for (int jj = 1; jj < pstate->argc; ++jj) {
+ printf(" %s", pstate->argv[jj]);
}
printf("\n");
}
+ delete trace;
return 0;
}
uint64_t time;
uint32_t addr;
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->addr = addr;
this->name = name;
+ this->isNative = isNative;
}
};
for (int ii = 0; ii < top; ii++) {
pframe = frames[ii];
- printf(" %d: %llu 0x%x %s\n",
- ii, pframe->time, pframe->addr,
+ const char *native = pframe->isNative ? "n" : " ";
+ printf(" %s %d: %llu 0x%x %s\n",
+ native, ii, pframe->time, pframe->addr,
pframe->name == NULL ? "" : pframe->name);
}
}
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,
- sym == NULL ? NULL: sym->name);
+ sym == NULL ? NULL: sym->name,
+ method_record.flags == kNativeEnter);
pStack->push(pframe);
} else {
pframe = pStack->pop();
public:
void push(int stackLevel, uint64_t time, CallStackBase *base);
void pop(int stackLevel, uint64_t time, CallStackBase *base);
+ void getFrameType(char *type);
};
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)
{
+ char type[5];
+
if (dumpTime > 0)
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)
printf(".");
printf(" 0x%08x %s\n", addr, function->name);
void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
{
+ char type[5];
+
if (dumpTime > 0)
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)
printf(".");
printf(" 0x%08x %s\n", addr, function->name);
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);
OptionsUsage();
}