property bool isUser { get { return (this == user || this == runToCursor); } };
};
enum DebuggerEvaluationError { none, symbolNotFound, memoryCantBeRead, unknown };
-enum DebuggerUserAction { none, start, resume, _break, stop, restart, selectThread, selectFrame, stepInto, stepOver, stepUntil, stepOut, runToCursor };
+enum DebuggerUserAction
+{
+ none, start, resume, _break, stop, restart, selectThread, selectFrame, stepInto, stepOver, stepUntil, stepOut, runToCursor;
+ property bool breaksOnInternalBreakpoint { get { return (this == stepInto || this == stepOver || this == stepUntil); } };
+};
enum GdbExecution
{
none, run, _continue, next, until, advance, step, finish;
bool sentKill;
bool sentBreakInsert;
bool ignoreBreakpoints;
- bool userBreakOnInternalBreakpoint;
- //bool runToCursorDebugStart;
bool signalOn;
bool needReset;
- //bool watchesInit;
bool usingValgrind;
int ideProcessId;
List<Breakpoint> sysBPs { };
Breakpoint bpRunToCursor;
+ Breakpoint intBpEntry;
+ Breakpoint intBpMain;
+ Breakpoint intBpWinMain;
OldList stackFrames;
}
else
_dpl2(_dpct, dplchan::debuggerProblem, 0, "Breakpoint bkptno(", stopItem.bkptno, ") invalid or not found!");
- if((bpUser && !ignoreBreakpoints) || (bpInternal && userBreakOnInternalBreakpoint))
+ if((bpUser && !ignoreBreakpoints) || (bpInternal && userAction.breaksOnInternalBreakpoint))
monitor = true;
hitThread = stopItem.threadid;
}
break;
case valgrindStartPause:
GdbExecContinue(true);
+ monitor = false;
break;
case exit:
HideDebuggerViews();
break;
}
- if(monitor || (bpUser && bpUser.type == runToCursor))
- GdbGetStack();
-
- if(monitor)
- {
- activeThread = stopItem.threadid;
- GdbCommand(false, "-thread-list-ids");
- if(activeFrameLevel > 0)
- GdbCommand(false, "-stack-select-frame %d", activeFrameLevel);
-
- WatchesCodeEditorLinkInit();
- EvaluateWatches();
- ide.AdjustDebugMenus();
- }
-
if(curEvent == signal)
{
char * s;
ide.callStackView.Show();
ide.callStackView.Activate();
}
-
- if(monitor && curEvent.canBeMonitored)
- {
- InternalSelectFrame(activeFrameLevel);
- GoToStackFrameLine(activeFrameLevel, true, false);
- ide.ShowCodeEditor();
- ideMainFrame.Activate(); // TOFIX: ide.Activate() is not reliable (app inactive)
- ide.Update(null);
- }
-
- if(curEvent == hit)
+ else if(curEvent == hit)
{
if(BreakpointHit(stopItem, bpInternal, bpUser))
{
delete breakString;
}
else
+ {
GdbExecContinue(false);
+ monitor = false;
+ }
}
}
+ if(monitor && curEvent.canBeMonitored)
+ {
+ GdbGetStack();
+ activeThread = stopItem.threadid;
+ GdbCommand(false, "-thread-list-ids");
+ InternalSelectFrame(activeFrameLevel);
+ GoToStackFrameLine(activeFrameLevel, true, false);
+ EvaluateWatches();
+ ide.ShowCodeEditor();
+ ide.AdjustDebugMenus();
+ ideMainFrame.Activate(); // TOFIX: ide.Activate() is not reliable (app inactive)
+ ide.Update(null);
+ }
+
if(stopItem)
{
stopItem.Free();
delete stopItem;
}
- if(userBreakOnInternalBreakpoint)
- userBreakOnInternalBreakpoint = false;
return false;
}
};
sentKill = false;
sentBreakInsert = false;
ignoreBreakpoints = false;
- userBreakOnInternalBreakpoint = false;
- //runToCursorDebugStart = false;
signalOn = false;
activeFrameLevel = 0;
delete currentCompiler;
prjConfig = null;
- codeEditor = null;
+
+ WatchesReleaseCodeEditor();
entryPoint = false;
projectsLibraryLoaded.Free();
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::constructor");
ideProcessId = Process_GetCurrentProcessId();
- sysBPs.Add(Breakpoint { type = internalEntry, enabled = false, level = -1 });
- sysBPs.Add(Breakpoint { type = internalMain, function = "main", enabled = true, level = -1 });
+ sysBPs.Add((intBpEntry = Breakpoint { type = internalEntry, enabled = false, level = -1 }));
+ sysBPs.Add((intBpMain = Breakpoint { type = internalMain, function = "main", enabled = true, level = -1 }));
#if defined(__WIN32__)
- sysBPs.Add(Breakpoint { type = internalWinMain, function = "WinMain", enabled = true, level = -1 });
+ sysBPs.Add((intBpWinMain = Breakpoint { type = internalWinMain, function = "WinMain", enabled = true, level = -1 }));
#endif
sysBPs.Add(Breakpoint { type = internalModulesLoaded, enabled = true, level = -1 });
sysBPs.Add(Breakpoint { type = internalModuleLoad, function = "InternalModuleLoadBreakpoint", enabled = true, level = -1 });
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::Restart");
_ChangeUserAction(restart);
- if(StartSession(compiler, config, bitDepth, useValgrind, true, false, false/*, false*/) == loaded)
+ if(StartSession(compiler, config, bitDepth, useValgrind, true, false) == loaded)
GdbExecRun();
}
GdbGetStack();
InternalSelectFrame(activeFrameLevel);
GoToStackFrameLine(activeFrameLevel, true, false);
- WatchesCodeEditorLinkRelease();
- WatchesCodeEditorLinkInit();
EvaluateWatches();
ide.Update(null);
}
{
//_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::SelectFrame(", frame, ")");
_ChangeUserAction(selectFrame);
- InternalSelectFrame(frame);
- }
-
- void InternalSelectFrame(int frame)
- {
- _dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::InternalSelectFrame(", frame, ")");
if(state == stopped)
{
- if(frame != activeFrameLevel || !codeEditor || !codeEditor.visible)
+ if(frame != activeFrameLevel)
{
- activeFrameLevel = frame; // there is no active frame number in the gdb reply
- GdbCommand(false, "-stack-select-frame %d", activeFrameLevel);
- for(activeFrame = stackFrames.first; activeFrame; activeFrame = activeFrame.next)
- if(activeFrame.level == activeFrameLevel)
- break;
-
- WatchesCodeEditorLinkRelease();
- WatchesCodeEditorLinkInit();
+ InternalSelectFrame(frame);
EvaluateWatches();
ide.Update(null);
}
}
}
+ void InternalSelectFrame(int frame)
+ {
+ //_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::InternalSelectFrame(", frame, ")");
+ activeFrameLevel = frame; // there is no active frame number in the gdb reply
+ GdbCommand(false, "-stack-select-frame %d", activeFrameLevel);
+ for(activeFrame = stackFrames.first; activeFrame; activeFrame = activeFrame.next)
+ if(activeFrame.level == activeFrameLevel)
+ break;
+ }
+
void HandleExit(char * reason, char * code)
{
bool returnedExitCode = false;
ide.Update(null);
}
- DebuggerState StartSession(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, bool restart, bool userBreakOnInternalBreakpoint, bool ignoreBreakpoints/*, bool runToCursorDebugStart*/)
+ DebuggerState StartSession(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, bool restart, bool ignoreBreakpoints)
{
DebuggerState result = none;
- _dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::StartSession(restart(", restart, "), userBreakOnInternalBreakpoint(", userBreakOnInternalBreakpoint, "), ignoreBreakpoints(", ignoreBreakpoints, ")"/*, runToCursorDebugStart(", runToCursorDebugStart, ")"*/);
+ _dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::StartSession(restart(", restart, "), ignoreBreakpoints(", ignoreBreakpoints, ")");
if(restart && state == running && targetProcessId)
{
breakType = DebuggerAction::restart;
bp.breaks = 0;
}
- //this.runToCursorDebugStart = runToCursorDebugStart;
-
if(GdbInit(compiler, config, bitDepth, useValgrind))
result = state;
else
result = error;
}
this.ignoreBreakpoints = ignoreBreakpoints;
- this.userBreakOnInternalBreakpoint = userBreakOnInternalBreakpoint;
}
return result;
}
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::Start()");
_ChangeUserAction(start);
- if(StartSession(compiler, config, bitDepth, useValgrind, true, false, false/*, false*/) == loaded)
+ if(StartSession(compiler, config, bitDepth, useValgrind, true, false) == loaded)
GdbExecRun();
}
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::StepInto()");
_ChangeUserAction(stepInto);
- switch(StartSession(compiler, config, bitDepth, useValgrind, false, true, false/*, false*/))
+ switch(StartSession(compiler, config, bitDepth, useValgrind, false, false))
{
case loaded: GdbExecRun(); break;
case stopped: GdbExecStep(); break;
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::StepOver()");
_ChangeUserAction(stepOver);
- switch(StartSession(compiler, config, bitDepth, useValgrind, false, true, ignoreBreakpoints/*, false*/))
+ switch(StartSession(compiler, config, bitDepth, useValgrind, false, ignoreBreakpoints))
{
case loaded: GdbExecRun(); break;
case stopped: GdbExecNext(); break;
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::StepUntil()");
_ChangeUserAction(stepUntil);
- switch(StartSession(compiler, config, bitDepth, useValgrind, false, true, ignoreBreakpoints/*, false*/))
+ switch(StartSession(compiler, config, bitDepth, useValgrind, false, ignoreBreakpoints))
{
case loaded: GdbExecRun(); break;
case stopped: GdbExecUntil(null, 0); break;
delete bpRunToCursor;
}
- StartSession(compiler, config, bitDepth, useValgrind, false, false, ignoreBreakpoints/*, true*/);
+ StartSession(compiler, config, bitDepth, useValgrind, false, ignoreBreakpoints);
#if 0
if(oldImplementation)
bp.inserted = (bp.bp && bp.bp.number && strcmp(bp.bp.number, "0"));
if(bp.inserted)
ValidateBreakpoint(bp);
- /*if(bp == bpRunToCursor)
- runToCursorDebugStart = false;*/
}
}
return !breakpointError;
event = none;
activeFrame = null;
stackFrames.Free(Frame::Free);
- WatchesCodeEditorLinkRelease();
ide.callStackView.Clear();
ide.threadsView.Clear();
ide.Update(null);
#endif
}
- void WatchesCodeEditorLinkInit()
+ bool WatchesLinkCodeEditor()
{
- //_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::WatchesCodeEditorLinkInit()");
- /*
- char tempPath[MAX_LOCATION];
- char path[MAX_LOCATION];
-
- //void MakeFilePathProjectRelative(char * path, char * relativePath)
- if(!ide.projectView.project.GetRelativePath(activeFrame.file, tempPath))
- strcpy(tempPath, activeFrame.file);
-
- strcpy(path, ide.workspace.projectDir);
- PathCat(path, tempPath);
- codeEditor = (CodeEditor)ide.OpenFile(path, Normal, false, null, no, normal, false);
- if(!codeEditor)
+ bool goodFrame = activeFrame && activeFrame.absoluteFile;
+ //_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::WatchesLinkCodeEditor()");
+ if(codeEditor && (!goodFrame || fstrcmp(codeEditor.fileName, activeFrame.absoluteFile)))
+ WatchesReleaseCodeEditor();
+
+ if(!codeEditor && goodFrame)
{
- for(srcDir : ide.workspace.sourceDirs)
+ codeEditor = (CodeEditor)ide.OpenFile(activeFrame.absoluteFile, normal, false, null, no, normal, false);
+ if(codeEditor)
{
- strcpy(path, srcDir);
- PathCat(path, tempPath);
- codeEditor = (CodeEditor)ide.OpenFile(path, Normal, false, null, no, normal, false);
- if(codeEditor) break;
+ codeEditor.inUseDebug = true;
+ incref codeEditor;
}
}
- */
-
- /*if(activeFrame && !activeFrame.absoluteFile && activeFrame.file)
- activeFrame.absoluteFile = ide.workspace.GetAbsolutePathFromRelative(activeFrame.file);*/
- if(!activeFrame || !activeFrame.absoluteFile)
- codeEditor = null;
- else
- codeEditor = (CodeEditor)ide.OpenFile(activeFrame.absoluteFile, normal, false, null, no, normal, false);
- if(codeEditor)
- {
- codeEditor.inUseDebug = true;
- incref codeEditor;
- }
- //watchesInit = true;
+ return codeEditor != null;
}
- void WatchesCodeEditorLinkRelease()
+ void WatchesReleaseCodeEditor()
{
- //_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::WatchesCodeEditorLinkRelease()");
- //if(watchesInit)
+ //_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::WatchesReleaseCodeEditor()");
+ if(codeEditor)
{
- if(codeEditor)
- {
- codeEditor.inUseDebug = false;
- if(!codeEditor.visible)
- codeEditor.Destroy(0);
- delete codeEditor;
- }
+ codeEditor.inUseDebug = false;
+ if(!codeEditor.visible)
+ codeEditor.Destroy(0);
+ delete codeEditor;
}
}
void EvaluateWatches()
{
_dpl2(_dpct, dplchan::debuggerWatches, 0, "Debugger::EvaluateWatches()");
- for(wh : ide.workspace.watches)
- ResolveWatch(wh);
+ WatchesLinkCodeEditor();
+ if(state == stopped)
+ {
+ for(wh : ide.workspace.watches)
+ ResolveWatch(wh);
+ }
}
char * ::GdbEvaluateExpression(char * expression)
"hitCursorBreakpoint(", bpUser && bpUser.type == runToCursor, ")");
delete s1; delete s2;
- if(bpUser && stopItem.frame.line && bpUser.line != stopItem.frame.line)
- {
- // updating user breakpoint on hit location difference
- // todo, print something?
- bpUser.line = stopItem.frame.line;
- ide.breakpointsView.UpdateBreakpoint(bpUser.row);
- ide.workspace.Save();
- }
- if(bpInternal)
- {
- bpInternal.hits++;
- if(bpInternal.type == internalModulesLoaded)
- modules = true;
- if(!bpUser && !userBreakOnInternalBreakpoint)
- {
- if(userAction == stepOut)//if(prevStopItem.reason == functionFinished)
- StepOut(ignoreBreakpoints);
- else
- result = false;
- }
- }
if(bpUser)
{
bool conditionMet = true;
- bool levelMatch = (bpUser.level == -1 || bpUser.level == frameCount-1);
if(bpUser.condition)
- conditionMet = ResolveWatch(bpUser.condition);
+ {
+ if(WatchesLinkCodeEditor())
+ conditionMet = ResolveWatch(bpUser.condition);
+ else
+ conditionMet = false;
+ }
bpUser.hits++;
- if(levelMatch && conditionMet)
+ if(conditionMet)
{
if(!bpUser.ignore)
bpUser.breaks++;
}
else
result = false;
- ide.breakpointsView.UpdateBreakpoint(bpUser.row);
+ if(stopItem.frame.line && bpUser.line != stopItem.frame.line)
+ {
+ // updating user breakpoint on hit location difference
+ // todo, print something?
+ bpUser.line = stopItem.frame.line;
+ ide.breakpointsView.UpdateBreakpoint(bpUser.row);
+ ide.workspace.Save();
+ }
+ else
+ ide.breakpointsView.UpdateBreakpoint(bpUser.row);
+ }
+ if(bpInternal)
+ {
+ bpInternal.hits++;
+ if(bpInternal.type == internalModulesLoaded)
+ modules = true;
+ if(userAction == stepOver)
+ {
+ if((bpInternal.type == internalEntry && ((intBpMain && intBpMain.inserted) || (intBpWinMain && intBpWinMain.inserted))) ||
+ (bpInternal.type == internalMain && intBpWinMain && intBpWinMain.inserted))
+ result = false;
+ }
+ if(!bpUser && !userAction.breaksOnInternalBreakpoint)
+ {
+ if(userAction == stepOut)
+ StepOut(ignoreBreakpoints);
+ else
+ result = false;
+ }
}
if(!bpUser && !bpInternal)