diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 16aab0c920c..0dc2d321613 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -406,6 +406,10 @@ void CdbEngine::setupEngine() if (!oldCdbExtensionPath.isEmpty()) inferiorEnvironment.appendOrSet(cdbExtensionPathVariableC, oldCdbExtensionPath); + if (!inferiorEnvironment.hasKey(Debugger::Constants::NO_DEBUG_HEAP)) { + const QString value = s.enableHeapDebugging() ? "0" : "1"; + inferiorEnvironment.set(Debugger::Constants::NO_DEBUG_HEAP, value); + } m_process.setEnvironment(inferiorEnvironment); if (!sp.inferior.workingDirectory.isEmpty()) m_process.setWorkingDirectory(sp.inferior.workingDirectory); diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp index ef3586e61b6..1cf5a2a2855 100644 --- a/src/plugins/debugger/cdb/cdboptionspage.cpp +++ b/src/plugins/debugger/cdb/cdboptionspage.cpp @@ -171,6 +171,7 @@ CdbOptionsPageWidget::CdbOptionsPageWidget() m_breakEventWidget->setBreakEvents(settings().cdbBreakEvents()); + // clang-format off Column { Row { Group { @@ -188,7 +189,8 @@ CdbOptionsPageWidget::CdbOptionsPageWidget() s.ignoreFirstChanceAccessViolation, s.cdbBreakOnCrtDbgReport, s.cdbBreakPointCorrection, - s.cdbUsePythonDumper + s.cdbUsePythonDumper, + s.enableHeapDebugging } } }, @@ -209,6 +211,7 @@ CdbOptionsPageWidget::CdbOptionsPageWidget() st }.attachTo(this); + // clang-format on } void CdbOptionsPageWidget::apply() diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 20ff6cddefd..1033524538a 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -190,6 +190,14 @@ DebuggerSettings::DebuggerSettings() : ignoreFirstChanceAccessViolation.setSettingsKey(cdbSettingsGroup, "IgnoreFirstChanceAccessViolation"); ignoreFirstChanceAccessViolation.setLabelText(Tr::tr("Ignore first chance access violations")); + enableHeapDebugging.setSettingsKey(cdbSettingsGroup, "EnableHeapDebugging"); + enableHeapDebugging.setLabelText(Tr::tr("Enable heap debugging")); + enableHeapDebugging.setToolTip( + "

" + + Tr::tr("Allocate memory using the debug heap rather than the normal heap. The debug heap " + "enables additional checks to help diagnose heap related bugs. However it comes " + "at a performance cost when allocating memory in the debugged process")); + // // Locals & Watchers sortStructMembers.setSettingsKey(debugModeGroup, "SortStructMembers"); @@ -255,6 +263,7 @@ DebuggerSettings::DebuggerSettings() : page5.registerAspect(&firstChanceExceptionTaskEntry); page5.registerAspect(&secondChanceExceptionTaskEntry); page5.registerAspect(&ignoreFirstChanceAccessViolation); + page5.registerAspect(&enableHeapDebugging); // Page 6 page6.registerAspect(&cdbSymbolPaths); diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 2134c5d03a4..e5d1ae0fa29 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -89,6 +89,7 @@ public: Utils::BoolAspect firstChanceExceptionTaskEntry; Utils::BoolAspect secondChanceExceptionTaskEntry; Utils::BoolAspect ignoreFirstChanceAccessViolation; + Utils::BoolAspect enableHeapDebugging; // Page 6: CDB Paths Utils::StringListAspect cdbSymbolPaths; diff --git a/src/plugins/debugger/debuggerinternalconstants.h b/src/plugins/debugger/debuggerinternalconstants.h index c1cef9f7f7f..26c703ddcf4 100644 --- a/src/plugins/debugger/debuggerinternalconstants.h +++ b/src/plugins/debugger/debuggerinternalconstants.h @@ -53,6 +53,8 @@ const char DISASSEMBLER_SOURCE_FILE[] = "DisassemblerSourceFile"; const char CRT_DEBUG_REPORT[] = "CrtDbgReport"; +const char NO_DEBUG_HEAP[] = "_NO_DEBUG_HEAP"; + } // namespace Constants enum ModelRoles diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 65b45cbda61..93e82be4c0d 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -264,22 +264,31 @@ void LldbEngine::handleLldbStarted() for (const FilePath &path : rp.solibSearchPath) executeDebuggerCommand("settings append target.exec-search-paths " + path.toString()); + const ProcessRunData &inferior = rp.inferior; + const FilePath &executable = inferior.command.executable(); DebuggerCommand cmd2("setupInferior"); - cmd2.arg("executable", rp.inferior.command.executable().path()); + cmd2.arg("executable", executable.path()); cmd2.arg("breakonmain", rp.breakOnMain); cmd2.arg("useterminal", usesTerminal()); cmd2.arg("startmode", rp.startMode); cmd2.arg("nativemixed", isNativeMixedActive()); - cmd2.arg("workingdirectory", rp.inferior.workingDirectory.path()); - QStringList environment = rp.inferior.environment.toStringList(); + cmd2.arg("workingdirectory", inferior.workingDirectory.path()); + Environment environment = inferior.environment; // Prevent lldb from automatically setting OS_ACTIVITY_DT_MODE to mirror // NSLog to stderr, as that will also mirror os_log, which we pick up in // AppleUnifiedLogger::preventsStderrLogging(), and end up disabling Qt's // default stderr logger. We prefer Qt's own stderr logging if we can. - environment << "IDE_DISABLED_OS_ACTIVITY_DT_MODE=1"; - cmd2.arg("environment", environment); - cmd2.arg("processargs", toHex(ProcessArgs::splitArgs(rp.inferior.command.arguments(), - HostOsInfo::hostOs()).join(QChar(0)))); + environment.set("IDE_DISABLED_OS_ACTIVITY_DT_MODE", "1"); + if (executable.osType() == Utils::OsTypeWindows + && !environment.hasKey(Debugger::Constants::NO_DEBUG_HEAP)) { + const QString value = settings().enableHeapDebugging() ? "0" : "1"; + environment.set(Debugger::Constants::NO_DEBUG_HEAP, value); + } + cmd2.arg("environment", environment.toStringList()); + cmd2.arg( + "processargs", + toHex(ProcessArgs::splitArgs(inferior.command.arguments(), HostOsInfo::hostOs()) + .join(QChar(0)))); cmd2.arg("platform", rp.platform); cmd2.arg("symbolfile", rp.symbolFile.path());