void DebugCLI::breakpoint(char *location) { Stringp filename = currentFile; char *colon = VMPI_strchr(location, ':'); if (colon) { *colon = 0; filename = core->internStringLatin1(location); location = colon+1; } if (abcCount() == 0) { core->console << "No abc file loaded\n"; return; } SourceFile* sourceFile = NULL; for (int i = 0, n = abcCount(); i < n; ++i) { AbcFile* abcFile = (AbcFile*)abcAt(i); sourceFile = abcFile->sourceNamed(filename); if (sourceFile) break; } if (sourceFile == NULL) { core->console << "No source available; can't set breakpoint.\n"; return; } int targetLine = VMPI_atoi(location); int breakpointId = ++breakpointCount; if (breakpointSet(sourceFile, targetLine)) { core->console << "Breakpoint " << breakpointId << ": file " << filename << ", " << (targetLine) << ".\n"; BreakAction *breakAction = new (core->GetGC()) BreakAction(sourceFile, breakpointId, filename, targetLine); breakAction->prev = lastBreakAction; if (lastBreakAction) { lastBreakAction->next = breakAction; } else { firstBreakAction = breakAction; } lastBreakAction = breakAction; } else { core->console << "Could not locate specified line.\n"; } }
/** * Identifies the source file and source line number * corresponding to this frame */ bool DebugStackFrame::sourceLocation(SourceInfo*& source, int& linenum) { // use the method info to locate the abcfile / source if (trace->info() && trace->filename() && debugger) { uintptr index = (uintptr)debugger->pool2abcIndex.get(Atom(trace->info()->pool())); AbcFile* abc = (AbcFile*)debugger->abcAt((int)index); source = abc->sourceNamed(trace->filename()); } linenum = trace->linenum(); // valid info? return (source != NULL && linenum > 0); }
void Debugger::debugLine(int linenum) { AvmAssert( core->callStack !=0 ); if (!core->callStack) return; AvmAssert(linenum > 0); int prev = core->callStack->linenum(); core->callStack->set_linenum(linenum); int line = linenum; // line number has changed bool changed = (prev == line) ? false : true; bool exited = (prev == -1) ? true : false; // are we being called as a result of function exit? if (!changed && !exited) return; // still on the same line in the same function? Profiler* profiler = core->profiler(); Sampler* s = core->get_sampler(); if (profiler && profiler->profilingDataWanted && profiler->profileSwitch && !(s && s->sampling())) { profiler->sendLineTimestamp(line); } // tracing information if (!exited) traceLine(line); // check if we should stop due to breakpoint or step bool stop = false; if (stepState.flag) { if (stepState.startingDepth != -1 && core->callStack->depth() < stepState.startingDepth) { // We stepped out of whatever function was executing when the // stepInto/stepOver/stepOut command was executed. We may be // in the middle of a line of code, but we still want to stop // immediately. See bug 126633. stop = true; } else if (!exited && (stepState.depth == -1 || core->callStack->depth() <= stepState.depth) ) { // We reached the beginning of a new line of code. stop = true; } } // we didn't decide to stop due to a step, but check if we hit a breakpoint if (!stop && !exited) { MethodInfo* f = core->callStack->info(); #ifdef VMCFG_AOT if (f && (f->hasMethodBody() || f->isCompiledMethod())) #else if (f && f->hasMethodBody()) #endif { AbcFile* abc = f->file(); if (abc) { SourceFile* source = abc->sourceNamed( core->callStack->filename() ); if (source && source->hasBreakpoint(line)) { stop = true; } } } } // we still haven't decided to stop; check our watchpoints if (!stop && !exited) { if (hitWatchpoint()) stop = true; } if (stop) { // Terminate whatever step operation may have been happening. But first, // save the state of the step, so that if someone calls stepContinue(), // then we can restore it. StepState oldOldStepState = oldStepState; // save oldStepState in case of reentrancy oldStepState = stepState; // save stepState so that stepContinue() can find it stepState.clear(); // turn off stepping enterDebugger(); oldStepState = oldOldStepState; // restore oldStepState } }