FileDialog debuggerFileDialog { type = selectDir };
+static DualPipe vgTargetHandle;
+static File vgLogFile;
+static char vgLogPath[MAX_LOCATION];
static DualPipe gdbHandle;
static DebugEvaluationData eval { };
bool userBreakOnInternBreak;
bool signalOn;
//bool watchesInit;
+ bool usingValgrind;
int ideProcessId;
int gdbProcessId;
CodeEditor codeEditor;
+ ValgrindLogThread vgLogThread { debugger = this };
+ ValgrindTargetThread vgTargetThread { debugger = this };
GdbThread gdbThread { debugger = this };
Timer gdbTimer
{
{
case restart:
breakType = none;
- Restart(currentCompiler, prjConfig, bitDepth);
+ Restart(currentCompiler, prjConfig, bitDepth, usingValgrind);
break;
case stop:
breakType = none;
}
}
- void Restart(CompilerConfig compiler, ProjectConfig config, int bitDepth)
+ void Restart(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind)
{
switch(state)
{
GdbAbortExec();
case none:
case terminated:
- if(!GdbInit(compiler, config, bitDepth))
+ if(!GdbInit(compiler, config, bitDepth, useValgrind))
break;
case loaded:
GdbExecRun();
}
#if defined(__unix__)
- progThread.terminate = true;
- if(fifoFile)
+ if(!usingValgrind)
{
- fifoFile.CloseInput();
- app.Unlock();
- progThread.Wait();
- app.Lock();
- delete fifoFile;
- }
+ progThread.terminate = true;
+ if(fifoFile)
+ {
+ fifoFile.CloseInput();
+ app.Unlock();
+ progThread.Wait();
+ app.Lock();
+ delete fifoFile;
+ }
+ }
#endif
{
ide.Update(null);
}
- void Start(CompilerConfig compiler, ProjectConfig config, int bitDepth)
+ void Start(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind)
{
ide.outputView.debugBox.Clear();
switch(state)
{
case none:
case terminated:
- if(!GdbInit(compiler, config, bitDepth))
+ if(!GdbInit(compiler, config, bitDepth, useValgrind))
break;
case loaded:
GdbExecRun();
}
}
- void StepInto(CompilerConfig compiler, ProjectConfig config, int bitDepth)
+ void StepInto(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind)
{
switch(state)
{
case none:
case terminated:
- if(!GdbInit(compiler, config, bitDepth))
+ if(!GdbInit(compiler, config, bitDepth, useValgrind))
break;
case loaded:
ide.outputView.ShowClearSelectTab(debug);
}
}
- void StepOver(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool ignoreBkpts)
+ void StepOver(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, bool ignoreBkpts)
{
switch(state)
{
case none:
case terminated:
- if(!GdbInit(compiler, config, bitDepth))
+ if(!GdbInit(compiler, config, bitDepth, useValgrind))
break;
case loaded:
ide.outputView.ShowClearSelectTab(debug);
}
}
- void RunToCursor(CompilerConfig compiler, ProjectConfig config, int bitDepth, char * absoluteFilePath, int lineNumber, bool ignoreBkpts, bool atSameLevel)
+ void RunToCursor(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, char * absoluteFilePath, int lineNumber, bool ignoreBkpts, bool atSameLevel)
{
char relativeFilePath[MAX_LOCATION];
DebuggerState oldState = state;
{
case none:
case terminated:
- Start(compiler, config, bitDepth);
+ Start(compiler, config, bitDepth, useValgrind);
case stopped:
case loaded:
if(symbols)
if(!symbols)
return true;
+ if(usingValgrind)
+ {
+ const char *vgdbCommand = "/usr/bin/vgdb"; // TODO: vgdb command config option
+ //GdbCommand(false, "-target-select remote | %s --pid=%d", "vgdb", targetProcessId);
+ printf("target remote | %s --pid=%d\n", vgdbCommand, targetProcessId);
+ GdbCommand(false, "target remote | %s --pid=%d", vgdbCommand, targetProcessId); // TODO: vgdb command config option
+ }
+
for(prj : ide.workspace.projects)
{
if(prj == ide.workspace.projects.firstIterator.data)
continue;
GdbCommand(false, "-environment-directory \"%s\"", prj.topNode.path);
}
-
for(dir : ide.workspace.sourceDirs)
{
GdbCommand(false, "-environment-directory \"%s\"", dir);
}
+
GdbInsertInternalBreakpoints();
targeted = true;
}
GdbTargetSet();
GdbExecCommon();
ShowDebuggerViews();
- GdbCommand(true, "-exec-run");
+ if(usingValgrind)
+ GdbCommand(true, "-exec-continue");
+ else
+ GdbCommand(true, "-exec-run");
}
void GdbExecContinue(bool focus)
return true;
}
- bool GdbInit(CompilerConfig compiler, ProjectConfig config, int bitDepth)
+ bool GdbInit(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind)
{
bool result = true;
char oldDirectory[MAX_LOCATION];
char tempPath[MAX_LOCATION];
- char command[MAX_LOCATION];
+ char command[MAX_F_STRING*4];
+ bool vgFullLeakCheck = ide.workspace.vgFullLeakCheck;
Project project = ide.project;
DirExpression targetDirExp = project.GetTargetDir(compiler, config, bitDepth);
PathBackup pathBackup { };
}
prjConfig = config;
this.bitDepth = bitDepth;
+ usingValgrind = useValgrind;
ChangeState(loaded);
sentKill = false;
SetEnvironment(e.name, e.string);
}
- strcpy(command,
- (compiler.targetPlatform == win32 && bitDepth == 64) ? "x86_64-w64-mingw32-gdb" :
- (compiler.targetPlatform == win32 && bitDepth == 32) ? "i686-w64-mingw32-gdb" :
- "gdb");
- strcat(command, " -n -silent --interpreter=mi2"); //-async //\"%s\"
- gdbTimer.Start();
- gdbHandle = DualPipeOpen(PipeOpenMode { output = 1, error = 2, input = 1 }, command);
- if(!gdbHandle)
+ if(usingValgrind)
{
- ide.outputView.debugBox.Logf($"Debugger Fatal Error: Couldn't start GDB\n");
- result = false;
+ char * clArgs = ide.workspace.commandLineArgs;
+ const char *valgrindCommand = "valgrind"; // TODO: valgrind command config option //TODO: valgrind options
+ vgLogFile = CreateTemporaryFile(vgLogPath, "ecereidevglog");
+ if(vgLogFile)
+ {
+ incref vgLogFile;
+ vgLogThread.Create();
+ }
+ else
+ {
+ ide.outputView.debugBox.Logf($"Debugger Fatal Error: Couldn't open temporary log file for Valgrind output\n");
+ result = false;
+ }
+ if(result)
+ {
+ sprintf(command, "%s --vgdb=yes --vgdb-error=0 --log-file=%s%s %s%s%s",
+ valgrindCommand, vgLogPath, vgFullLeakCheck ? " --leak-check=full" : "", targetFile, clArgs ? " " : "", clArgs ? clArgs : "");
+ vgTargetHandle = DualPipeOpen(PipeOpenMode { output = 1, error = 2, input = 1 }, command);
+ if(!vgTargetHandle)
+ {
+ ide.outputView.debugBox.Logf($"Debugger Fatal Error: Couldn't start Valgrind\n");
+ result = false;
+ }
+ }
+ if(result)
+ {
+ incref vgTargetHandle;
+ vgTargetThread.Create();
+
+ targetProcessId = vgTargetHandle.GetProcessID();
+ waitingForPID = false;
+ if(!targetProcessId)
+ {
+ ide.outputView.debugBox.Logf($"Debugger Fatal Error: Couldn't get Valgrind process ID\n");
+ result = false;
+ }
+ }
+ if(result)
+ {
+ app.Unlock();
+ serialSemaphore.Wait();
+ app.Lock();
+ }
+ }
+
+ if(result)
+ {
+ strcpy(command,
+ (compiler.targetPlatform == win32 && bitDepth == 64) ? "x86_64-w64-mingw32-gdb" :
+ (compiler.targetPlatform == win32 && bitDepth == 32) ? "i686-w64-mingw32-gdb" :
+ "gdb");
+ strcat(command, " -n -silent --interpreter=mi2"); //-async //\"%s\"
+ gdbTimer.Start();
+ gdbHandle = DualPipeOpen(PipeOpenMode { output = 1, error = 2, input = 1 }, command);
+ if(!gdbHandle)
+ {
+ ide.outputView.debugBox.Logf($"Debugger Fatal Error: Couldn't start GDB\n");
+ result = false;
+ }
}
if(result)
{
ide.outputView.debugBox.Logf($"Debugger Fatal Error: Couldn't get GDB process ID\n");
result = false;
}
- if(result)
- {
- app.Unlock();
- serialSemaphore.Wait();
- app.Lock();
+ }
+ if(result)
+ {
+ app.Unlock();
+ serialSemaphore.Wait();
+ app.Lock();
- if(!GdbTargetSet())
+ if(!GdbTargetSet())
+ {
+ //ChangeState(terminated);
+ result = false;
+ }
+ }
+ if(result)
+ {
+#if defined(__unix__)
+ {
+ CreateTemporaryDir(progFifoDir, "ecereide");
+ strcpy(progFifoPath, progFifoDir);
+ PathCat(progFifoPath, "ideprogfifo");
+ if(!mkfifo(progFifoPath, 0600))
{
- //ChangeState(terminated);
- result = false;
+ //fileCreated = true;
}
-
- if(result)
+ else
{
-#if defined(__unix__)
- {
- CreateTemporaryDir(progFifoDir, "ecereide");
- strcpy(progFifoPath, progFifoDir);
- PathCat(progFifoPath, "ideprogfifo");
- if(!mkfifo(progFifoPath, 0600))
- {
- //fileCreated = true;
- }
- else
- {
- //app.Lock();
- ide.outputView.debugBox.Logf(createFIFOMsg, progFifoPath);
- //app.Unlock();
- }
- }
+ //app.Lock();
+ ide.outputView.debugBox.Logf(createFIFOMsg, progFifoPath);
+ //app.Unlock();
+ }
+ }
- progThread.terminate = false;
- progThread.Create();
+ if(!usingValgrind)
+ {
+ progThread.terminate = false;
+ progThread.Create();
+ }
#endif
-
+
#if defined(__WIN32__)
- GdbCommand(false, "-gdb-set new-console on");
+ GdbCommand(false, "-gdb-set new-console on");
#endif
-
- GdbCommand(false, "-gdb-set verbose off");
- //GdbCommand(false, "-gdb-set exec-done-display on");
- GdbCommand(false, "-gdb-set step-mode off");
- GdbCommand(false, "-gdb-set unwindonsignal on");
- //GdbCommand(false, "-gdb-set shell on");
- GdbCommand(false, "set print elements 992");
- GdbCommand(false, "-gdb-set backtrace limit 100000");
+
+ GdbCommand(false, "-gdb-set verbose off");
+ //GdbCommand(false, "-gdb-set exec-done-display on");
+ GdbCommand(false, "-gdb-set step-mode off");
+ GdbCommand(false, "-gdb-set unwindonsignal on");
+ //GdbCommand(false, "-gdb-set shell on");
+ GdbCommand(false, "set print elements 992");
+ GdbCommand(false, "-gdb-set backtrace limit 100000");
#if defined(__unix__)
- GdbCommand(false, "-inferior-tty-set %s", progFifoPath);
+ if(!usingValgrind)
+ GdbCommand(false, "-inferior-tty-set %s", progFifoPath);
#endif
- GdbCommand(false, "-gdb-set args %s", ide.workspace.commandLineArgs ? ide.workspace.commandLineArgs : "");
- /*
- for(e : ide.workspace.environmentVars)
- {
- GdbCommand(false, "set environment %s=%s", e.name, e.string);
- }
- */
- }
+ if(!usingValgrind)
+ GdbCommand(false, "-gdb-set args %s", ide.workspace.commandLineArgs ? ide.workspace.commandLineArgs : "");
+ /*
+ for(e : ide.workspace.environmentVars)
+ {
+ GdbCommand(false, "set environment %s=%s", e.name, e.string);
}
+ */
}
ChangeWorkingDir(oldDirectory);
ide.Update(null);
#if defined(__unix__)
- if(FileExists(progFifoPath)) //fileCreated)
+ if(!usingValgrind && FileExists(progFifoPath)) //fileCreated)
{
progThread.terminate = true;
if(fifoFile)
}
}
+ void ValgrindTargetThreadExit()
+ {
+ ide.outputView.debugBox.Logf($"ValgrindTargetThreadExit\n");
+ if(vgTargetHandle)
+ {
+ vgTargetHandle.Wait();
+ delete vgTargetHandle;
+ }
+ HandleExit(null, null);
+ }
+
void GdbThreadExit()
{
if(state != terminated)
targetProcessId = 0;
ClearBreakDisplay();
+ if(vgLogFile)
+ delete vgLogFile;
if(gdbHandle)
{
serialSemaphore.Release();
else
DebuggerProtocolUnknown("Unknown reason", reason);
}
+ else
+ {
+ PrintLn(output);
+ }
}
}
app.SignalEvent();
int oldProcessID = targetProcessId;
GetLastDirectory(targetFile, exeFile);
- while(true)
+ while(!targetProcessId/*true*/)
{
targetProcessId = Process_GetChildExeProcessId(gdbProcessId, exeFile);
if(targetProcessId || gdbHandle.Peek()) break;
ClearBreakDisplay();
#if defined(__unix__)
- if(FileExists(progFifoPath)) //fileCreated)
+ if(!usingValgrind && FileExists(progFifoPath)) //fileCreated)
{
progThread.terminate = true;
if(fifoFile)
}
}
+class ValgrindLogThread : Thread
+{
+ Debugger debugger;
+
+ unsigned int Main()
+ {
+ static char output[4096];
+ Array<char> dynamicBuffer { minAllocSize = 4096 };
+ File oldValgrindHandle = vgLogFile;
+ incref oldValgrindHandle;
+
+ app.Lock();
+ while(debugger.state != terminated && vgLogFile)
+ {
+ int result;
+ app.Unlock();
+ result = vgLogFile.Read(output, 1, sizeof(output));
+ app.Lock();
+ if(debugger.state == terminated || !vgLogFile/* || vgLogFile.Eof()*/)
+ break;
+ if(result)
+ {
+ int c;
+ int start = 0;
+
+ for(c = 0; c<result; c++)
+ {
+ if(output[c] == '\n')
+ {
+ int pos = dynamicBuffer.size;
+ dynamicBuffer.size += c - start;
+ memcpy(&dynamicBuffer[pos], output + start, c - start);
+ if(dynamicBuffer.count && dynamicBuffer[dynamicBuffer.count - 1] != '\r')
+ // COMMENTED OUT DUE TO ISSUE #135, FIXED
+ //if(dynamicBuffer.array[dynamicBuffer.count - 1] != '\r')
+ dynamicBuffer.size++;
+ dynamicBuffer[dynamicBuffer.count - 1] = '\0';
+#ifdef _DEBUG
+ // printf("%s\n", dynamicBuffer.array);
+#endif
+ if(strstr(&dynamicBuffer[0], "vgdb me"))
+ debugger.serialSemaphore.Release();
+ ide.outputView.debugBox.Logf("%s\n", &dynamicBuffer[0]);
+ dynamicBuffer.size = 0;
+ start = c + 1;
+ }
+ }
+ if(c == result)
+ {
+ int pos = dynamicBuffer.size;
+ dynamicBuffer.size += c - start;
+ memcpy(&dynamicBuffer[pos], output + start, c - start);
+ }
+ }
+ else if(debugger.state == stopped)
+ {
+/*#ifdef _DEBUG
+ printf("Got end of file from GDB!\n");
+#endif*/
+ app.Unlock();
+ Sleep(0.2);
+ app.Lock();
+ }
+ }
+ delete dynamicBuffer;
+ ide.outputView.debugBox.Logf($"ValgrindLogThreadExit\n");
+ //if(oldValgrindHandle == vgLogFile)
+ debugger.GdbThreadExit/*ValgrindLogThreadExit*/();
+ delete oldValgrindHandle;
+ app.Unlock();
+ return 0;
+ }
+}
+
+class ValgrindTargetThread : Thread
+{
+ Debugger debugger;
+
+ unsigned int Main()
+ {
+ static char output[4096];
+ Array<char> dynamicBuffer { minAllocSize = 4096 };
+ DualPipe oldValgrindHandle = vgTargetHandle;
+ incref oldValgrindHandle;
+
+ app.Lock();
+ while(debugger.state != terminated && vgTargetHandle && !vgTargetHandle.Eof())
+ {
+ int result;
+ app.Unlock();
+ result = vgTargetHandle.Read(output, 1, sizeof(output));
+ app.Lock();
+ if(debugger.state == terminated || !vgTargetHandle || vgTargetHandle.Eof())
+ break;
+ if(result)
+ {
+ int c;
+ int start = 0;
+
+ for(c = 0; c<result; c++)
+ {
+ if(output[c] == '\n')
+ {
+ int pos = dynamicBuffer.size;
+ dynamicBuffer.size += c - start;
+ memcpy(&dynamicBuffer[pos], output + start, c - start);
+ if(dynamicBuffer.count && dynamicBuffer[dynamicBuffer.count - 1] != '\r')
+ // COMMENTED OUT DUE TO ISSUE #135, FIXED
+ //if(dynamicBuffer.array[dynamicBuffer.count - 1] != '\r')
+ dynamicBuffer.size++;
+ dynamicBuffer[dynamicBuffer.count - 1] = '\0';
+#ifdef _DEBUG
+ // printf("%s\n", dynamicBuffer.array);
+#endif
+ ide.outputView.debugBox.Logf("%s\n", &dynamicBuffer[0]);
+
+ dynamicBuffer.size = 0;
+ start = c + 1;
+ }
+ }
+ if(c == result)
+ {
+ int pos = dynamicBuffer.size;
+ dynamicBuffer.size += c - start;
+ memcpy(&dynamicBuffer[pos], output + start, c - start);
+ }
+ }
+ else
+ {
+#ifdef _DEBUG
+ printf("Got end of file from GDB!\n");
+#endif
+ }
+ }
+ delete dynamicBuffer;
+ //if(oldValgrindHandle == vgTargetHandle)
+ debugger.ValgrindTargetThreadExit();
+ delete oldValgrindHandle;
+ app.Unlock();
+ return 0;
+ }
+}
+
class GdbThread : Thread
{
Debugger debugger;
hasMinimize = true;
hasClose = true;
stayOnTop = true;
- size = { 424, 294 };
+ size = { 800, 600 };
autoCreate = false;
Command lastCommand;
OldList commands;
- Label commandLabel { this, position = { 8, 12 }, labeledWindow = command };
+ Stacker bg
+ {
+ this, direction = horizontal, gap = 0;
+ isActiveClient = true;
+ background = darkGray;//formColor
+ anchor = { left = 0, top = 0, right = 0, bottom = 0 };
+ flipSpring = true;
+ flipper = rightCol;
+ };
+
+ Stacker leftCol
+ {
+ bg, this, gap = 4, margin = 4 ;
+ isActiveClient = true;
+ background = darkGray;
+ size = { 200, 100 };
+ anchor = { top = 0, bottom = 0 };
+ flipSpring = true;
+ flipper = history;
+ };
+
+ PaneSplitter splitter
+ {
+ this, leftPane = leftCol, rightPane = rightCol, split = 200;
+ };
+
+ Stacker rightCol
+ {
+ bg, this, gap = 4, margin = 4;
+ isActiveClient = true;
+ background = darkGray;
+ size = { 800, 600 };
+ anchor = { top = 0, bottom = 0 };
+ flipSpring = true;
+ flipper = tree;
+ };
+
+ Label lhistory { leftCol, this, position = { 4, 4 }, labeledWindow = history };
+ ListBox history
+ {
+ leftCol, this, borderStyle = deep, hasVertScroll = true, hasHorzScroll = true;
+ // selectionColor = unfocusedSelectorColor;
+ fullRowSelect = true, alwaysHighLight = true;
+
+ size = { 180 };
+ anchor = { left = leftCol.margin, right = leftCol.margin };
+ text = $"Command History";
+
+ bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
+ {
+ if(row)
+ {
+ lastCommand = (Command)row.tag;
+ command.contents = lastCommand.command;
+ UpdateOutput();
+ }
+ return true;
+ }
+ };
+
+ Label commandLabel { rightCol, this, position = { 4, 4 }, labeledWindow = command };
EditBox command
{
- this, text = $"Command:", size = { 328, 19 }, anchor = { left = 80, top = 8, right = 8 };
+ rightCol, this, text = $"Command:", size = { 328, 19 }, anchor = { left = rightCol.margin, right = rightCol.margin };
bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
{
}
};
- TagButton infoLibs { this, text = "libs", tag = "info shared", anchor = { left = 80, top = 35 }, NotifyClicked = QuickCommandNotifyClicked; };
- TagButton infoPaths { this, text = "paths", tag = "-environment-path", anchor = { left = 120, top = 35 }, NotifyClicked = QuickCommandNotifyClicked; };
- TagButton infoWorkDir { this, text = "wd", tag = "-environment-pwd", anchor = { left = 170, top = 35 }, NotifyClicked = QuickCommandNotifyClicked; };
- TagButton infoDirs { this, text = "pths", tag = "-environment-directory", anchor = { left = 200, top = 35 }, NotifyClicked = QuickCommandNotifyClicked; };
- TagButton infoTemp { this, text = "pths", tag = "-environment-temp", anchor = { left = 200, top = 35 }, NotifyClicked = QuickCommandNotifyClicked; };
+ Stacker toolBar
+ {
+ rightCol, this, direction = horizontal, gap = 4;
+ isActiveClient = true;
+ background = darkGray;
+ size = { 200, 30 };
+ anchor = { left = rightCol.margin, right = rightCol.margin };
+ };
+
+ TagButton infoLibs { toolBar, this, text = "libs", tag = "info shared", NotifyClicked = QuickCommandNotifyClicked; };
+ TagButton infoPaths { toolBar, this, text = "paths", tag = "-environment-path", NotifyClicked = QuickCommandNotifyClicked; };
+ TagButton infoWorkDir { toolBar, this, text = "wd", tag = "-environment-pwd", NotifyClicked = QuickCommandNotifyClicked; };
+ TagButton infoDirs { toolBar, this, text = "pths", tag = "-environment-directory", NotifyClicked = QuickCommandNotifyClicked; };
+ TagButton infoTemp { toolBar, this, text = "pths", tag = "-environment-temp", NotifyClicked = QuickCommandNotifyClicked; };
bool QuickCommandNotifyClicked(Button button, int x, int y, Modifiers mods)
{
return true;
}
- Label treeLabel { this, position = { 8, 69 }, labeledWindow = tree };
- ListBox tree
+ Label outputLabel { rightCol, this, position = { 4, 4 }, labeledWindow = output };
+ EditBox output
{
- this, text = $"Tree:";
- multiSelect = false, fullRowSelect = false, hasVertScroll = true, hasHorzScroll = true;
- borderStyle = deep, collapseControl = true, treeBranches = true;
- anchor = Anchor { left = 80, right = 8, top = 65, bottom = 100 };
+ rightCol, this, text = $"Output:", multiLine = true, hasVertScroll = true, hasHorzScroll = true;
+ size = { 328, 80 };
+ anchor = { left = rightCol.margin, right = rightCol.margin };
font = { panelFont.faceName, panelFont.size };
};
- Label outputLabel { this, position = { 8, 39 }, anchor = { left = 8, bottom = 73 }, labeledWindow = output };
- EditBox output
+ Label treeLabel { rightCol, this, position = { 4, 4 }, labeledWindow = tree };
+ ListBox tree
{
- this, text = $"Output:", multiLine = true, hasVertScroll = true, hasHorzScroll = true;
- size = { 328, 84 }, anchor = { left = 80, bottom = 8, right = 8 };
+ rightCol, this, text = $"Tree:";
+ multiSelect = false, fullRowSelect = false, hasVertScroll = true, hasHorzScroll = true;
+ borderStyle = deep, collapseControl = true, treeBranches = true;
+ anchor = { left = rightCol.margin, right = rightCol.margin };
font = { panelFont.faceName, panelFont.size };
};
{
if(string && strlen(string))
{
- commands.Add(Command { command = CopyString(string) });
+ Command cmd = Command { command = CopyString(string) };
+ commands.Add(cmd);
+ history.AddString(string).tag = (uint64)cmd;
lastCommand = commands.last;
if(created)
CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
ProjectConfig config = projectView.project.config;
int bitDepth = ide.workspace.bitDepth;
- ide.debugger.RunToCursor(compiler, config, bitDepth, fileName, line, false, false);
+ bool useValgrind = ide.workspace.useValgrind;
+ ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, false, false);
delete compiler;
}
}
CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
ProjectConfig config = projectView.project.config;
int bitDepth = ide.workspace.bitDepth;
- ide.debugger.RunToCursor(compiler, config, bitDepth, fileName, line, true, false);
+ bool useValgrind = ide.workspace.useValgrind;
+ ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, true, false);
delete compiler;
}
return true;
CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
ProjectConfig config = projectView.project.config;
int bitDepth = ide.workspace.bitDepth;
- ide.debugger.RunToCursor(compiler, config, bitDepth, fileName, line, true, true);
+ bool useValgrind = ide.workspace.useValgrind;
+ ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, true, true);
delete compiler;
}
return true;
// multiSelect = true, selectionColor = unfocusedSelectorColor;
fullRowSelect = true;
alwaysHighLight = true;
-
+
size = { 180 };
anchor = Anchor { left = 8, top = 24, right = 8, bottom = 36 };
text = $"Compilers";
}
}
MenuDivider { debugMenu };
+ MenuItem debugUseValgrindItem
+ {
+ debugMenu, $"Use Valgrind", d, disabled = true, checkable = true;
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ if(ide.workspace)
+ {
+ ide.workspace.useValgrind = selection.checked;
+ ide.workspace.Save();
+ }
+ ide.AdjustValgrindChecks();
+ return true;
+ }
+ }
+ MenuItem debugValgrindFullLeakCheckItem
+ {
+ debugMenu, $"Valgrind: Full Leak Check", d, disabled = true, checkable = true;
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ if(ide.workspace)
+ {
+ ide.workspace.vgFullLeakCheck = selection.checked;
+ ide.workspace.Save();
+ }
+ return true;
+ }
+ }
+ MenuDivider { debugMenu };
MenuItem debugStepIntoItem
{
debugMenu, $"Step Into", i, f11, disabled = true;
}
}
MenuPlacement debugSkipRunToCursorItem { debugMenu, $"Run To Cursor Skipping Breakpoints", u };
- MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", s };
+ MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", l };
//MenuDivider { debugMenu };
//MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
MenuPlacement imageMenu { menu, $"Image", i };
GDBDialog gdbDialog
{
master = this, parent = this;
- anchor = { left = 100, top = 100, right = 100, bottom = 100 };
+ //anchor = { left = 100, top = 100, right = 100, bottom = 100 };
void OnCommand(char * string)
{
toolBar.activeConfig.disabled = unavailable;
toolBar.activeCompiler.disabled = unavailable;
toolBar.activeBitDepth.disabled = unavailable;
+ debugUseValgrindItem.disabled = unavailable;
+ AdjustValgrindChecks();
AdjustFileMenus();
AdjustBuildMenus();
AdjustDebugMenus();
}
+ void AdjustValgrindChecks()
+ {
+ bool unavailable = !project || !debugUseValgrindItem.checked;
+ debugValgrindFullLeakCheckItem.disabled = unavailable;
+ }
+
property bool hasOpenedCodeEditors
{
get
void AdjustBuildMenus()
{
bool unavailable = project && projectView.buildInProgress;
+ bool naForRun = unavailable || !project || project.GetTargetType(project.config) != executable;
projectNewItem.disabled = unavailable;
toolBar.buttonNewProject.disabled = unavailable;
projectCloseItem.disabled = unavailable;
// toolBar.buttonCloseProject.disabled = unavailable;
- projectRunItem.disabled = unavailable || project.GetTargetType(project.config) != executable;
- toolBar.buttonRun.disabled = unavailable || project.GetTargetType(project.config) != executable;
+ projectRunItem.disabled = naForRun;
+ toolBar.buttonRun.disabled = naForRun;
projectBuildItem.disabled = false;
projectBuildItem.text = unavailable ? $"Stop Build" : $"Build";
return null;
//project = LoadProject(filePath, null);
}
-
+
if(workspace)
{
char absolutePath[MAX_LOCATION];
}
else
ChangeWorkingDir(topNode.path);
- // ChangeWorkingDir(topNode.path);
SetPath(true, compiler, config, bitDepth);
if(executableLauncher)
{
- char * prefixedTarget = new char[strlen(executableLauncher) + strlen(target) + 2];
+ char * prefixedTarget = new char[strlen(executableLauncher) + strlen(target) + 8];
prefixedTarget[0] = '\0';
strcat(prefixedTarget, executableLauncher);
strcat(prefixedTarget, " ");
CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
ProjectConfig config = project.config;
int bitDepth = ide.workspace.bitDepth;
+ bool useValgrind = ide.workspace.useValgrind;
TargetTypes targetType = project.GetTargetType(config);
if(targetType == sharedLibrary || targetType == staticLibrary)
MessageBox { master = ide, type = ok, text = $"Run", contents = $"Shared and static libraries cannot be run like executables." }.Modal();
}
else
{
- ide.debugger.Start(compiler, config, bitDepth);
+ ide.debugger.Start(compiler, config, bitDepth, useValgrind);
result = true;
}
}
CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
ProjectConfig config = project.config;
int bitDepth = ide.workspace.bitDepth;
+ bool useValgrind = ide.workspace.useValgrind;
bool result = false;
if(/*!IsProjectModified() ||*/ BuildInterrim(project, restart, compiler, config, bitDepth, false))
// For Restart, compiler and config will only be used if for
// whatever reason (if at all possible) the Debugger is in a
// 'terminated' or 'none' state
- ide.debugger.Restart(compiler, config, bitDepth);
+ ide.debugger.Restart(compiler, config, bitDepth, useValgrind);
result = true;
}
CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
ProjectConfig config = project.config;
int bitDepth = ide.workspace.bitDepth;
+ bool useValgrind = ide.workspace.useValgrind;
if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config, bitDepth, false)))
- ide.debugger.StepInto(compiler, config, bitDepth);
+ ide.debugger.StepInto(compiler, config, bitDepth, useValgrind);
delete compiler;
return true;
}
CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
ProjectConfig config = project.config;
int bitDepth = ide.workspace.bitDepth;
+ bool useValgrind = ide.workspace.useValgrind;
if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config, bitDepth, false)))
- ide.debugger.StepOver(compiler, config, bitDepth, skip);
+ ide.debugger.StepOver(compiler, config, bitDepth, useValgrind, skip);
delete compiler;
return true;
private:
String compiler;
int bitDepth;
+ bool useValgrind;
+ bool vgFullLeakCheck;
public:
void Save()