forked from qt-creator/qt-creator
Debugger: Fix hitting breakpoints repeatedly in multithreading
This change resolves an issue where gdb.parse_and_eval could rerun the multithreading application, causing breakpoints to be hit repeatedly in different threads, leading to an infinite loop. Added checkbox which enables skipping the execution of gdb.parse_and_eval in few places that mitigate the issue. Fixes: QTCREATORBUG-23219 Change-Id: I856d382d033f8a4da394d7422ebb3e131de28e09 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -227,6 +227,7 @@ class DumperBase():
|
||||
self.watchers = args.get('watchers', {})
|
||||
self.useDynamicType = int(args.get('dyntype', '0'))
|
||||
self.useFancy = int(args.get('fancy', '0'))
|
||||
self.allowInferiorCalls = int(args.get('allowinferiorcalls', '0'))
|
||||
self.forceQtNamespace = int(args.get('forcens', '0'))
|
||||
self.passExceptions = int(args.get('passexceptions', '0'))
|
||||
self.isTesting = int(args.get('testing', '0'))
|
||||
|
@@ -739,6 +739,9 @@ class Dumper(DumperBase):
|
||||
def nativeParseAndEvaluate(self, exp):
|
||||
#self.warn('EVALUATE "%s"' % exp)
|
||||
try:
|
||||
if not self.allowInferiorCalls:
|
||||
return None
|
||||
|
||||
val = gdb.parse_and_eval(exp)
|
||||
return val
|
||||
except RuntimeError as error:
|
||||
@@ -772,6 +775,9 @@ class Dumper(DumperBase):
|
||||
#self.warn('PTR: %s -> %s(%s)' % (value, function, addr))
|
||||
exp = '((%s*)0x%x)->%s(%s)' % (type_name, addr, function, arg)
|
||||
#self.warn('CALL: %s' % exp)
|
||||
if not self.allowInferiorCalls:
|
||||
return None
|
||||
|
||||
result = gdb.parse_and_eval(exp)
|
||||
#self.warn(' -> %s' % result)
|
||||
res = self.fromNativeValue(result)
|
||||
@@ -1504,6 +1510,12 @@ class CliDumper(Dumper):
|
||||
|
||||
args = {}
|
||||
args['fancy'] = 1
|
||||
# It enables skipping the execution of gdb.parse_and_eval which prevents the application from being rerun,
|
||||
# which could lead to hitting breakpoints repeatedly in different threads, causing an infinite loop.
|
||||
# Currently, gdb.parse_and_eval is bypassed in several places, resolving the bug QTCREATORBUG-23219.
|
||||
# In the future, a full wrapper for gdb.parse_and_eval might be necessary to avoid this issue entirely.
|
||||
# For now, we leave it as-is to retain as much pretty-printing functionality as possible.
|
||||
args['allowinferiorcalls'] = 1
|
||||
args['passexceptions'] = 1
|
||||
args['autoderef'] = 1
|
||||
args['qobjectnames'] = 1
|
||||
|
@@ -235,6 +235,10 @@ LocalsAndExpressionsSettings::LocalsAndExpressionsSettings()
|
||||
useDebuggingHelpers.setDefaultValue(true);
|
||||
useDebuggingHelpers.setLabelText(Tr::tr("Use Debugging Helpers"));
|
||||
|
||||
allowInferiorCalls.setSettingsKey(debugModeGroup, "AllowInferiorCalls");
|
||||
allowInferiorCalls.setDefaultValue(true);
|
||||
allowInferiorCalls.setLabelText(Tr::tr("Allow inferior calls in debugging helper"));
|
||||
|
||||
useCodeModel.setSettingsKey(debugModeGroup, "UseCodeModel");
|
||||
useCodeModel.setDefaultValue(true);
|
||||
useCodeModel.setLabelText(Tr::tr("Use code model"));
|
||||
@@ -354,6 +358,7 @@ LocalsAndExpressionsSettings::LocalsAndExpressionsSettings()
|
||||
|
||||
return Column {
|
||||
useDebuggingHelpers,
|
||||
allowInferiorCalls,
|
||||
useHelper,
|
||||
Space(10),
|
||||
showStdNamespace,
|
||||
|
@@ -76,6 +76,7 @@ public:
|
||||
LocalsAndExpressionsSettings();
|
||||
|
||||
Utils::BoolAspect useDebuggingHelpers{this};
|
||||
Utils::BoolAspect allowInferiorCalls{this};
|
||||
Utils::BoolAspect useCodeModel{this};
|
||||
Utils::BoolAspect showThreadNames{this};
|
||||
Utils::FilePathAspect extraDumperFile{this}; // For loading a file. Recommended.
|
||||
|
@@ -76,6 +76,7 @@ DebuggerSettings::DebuggerSettings() :
|
||||
|
||||
// Page 4
|
||||
useDebuggingHelpers{localsAndExpressionSettings().useDebuggingHelpers},
|
||||
allowInferiorCalls{localsAndExpressionSettings().allowInferiorCalls},
|
||||
useCodeModel{localsAndExpressionSettings().useCodeModel},
|
||||
showThreadNames{localsAndExpressionSettings().showThreadNames},
|
||||
extraDumperFile{localsAndExpressionSettings().extraDumperFile}, // For loading a file. Recommended.
|
||||
|
@@ -65,6 +65,7 @@ public:
|
||||
|
||||
// Page 4: Locals and expressions
|
||||
Utils::BoolAspect &useDebuggingHelpers;
|
||||
Utils::BoolAspect &allowInferiorCalls;
|
||||
Utils::BoolAspect &useCodeModel;
|
||||
Utils::BoolAspect &showThreadNames;
|
||||
Utils::FilePathAspect &extraDumperFile; // For loading a file. Recommended.
|
||||
|
@@ -145,6 +145,8 @@ GdbEngine::GdbEngine()
|
||||
this, &GdbEngine::createFullBacktrace);
|
||||
connect(&s.useDebuggingHelpers, &BaseAspect::changed,
|
||||
this, &GdbEngine::reloadLocals);
|
||||
connect(&s.allowInferiorCalls, &BaseAspect::changed,
|
||||
this, &GdbEngine::reloadLocals);
|
||||
connect(&s.useDynamicType, &BaseAspect::changed,
|
||||
this, &GdbEngine::reloadLocals);
|
||||
|
||||
@@ -2638,6 +2640,7 @@ void GdbEngine::insertBreakpoint(const Breakpoint &bp)
|
||||
const DebuggerSettings &s = settings();
|
||||
cmd.arg("passexceptions", alwaysVerbose);
|
||||
cmd.arg("fancy", s.useDebuggingHelpers());
|
||||
cmd.arg("allowinferiorcalls", s.allowInferiorCalls());
|
||||
cmd.arg("autoderef", s.autoDerefPointers());
|
||||
cmd.arg("dyntype", s.useDynamicType());
|
||||
cmd.arg("qobjectnames", s.showQObjectNames());
|
||||
@@ -5164,6 +5167,7 @@ void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms)
|
||||
const DebuggerSettings &s = settings();
|
||||
cmd.arg("passexceptions", alwaysVerbose);
|
||||
cmd.arg("fancy", s.useDebuggingHelpers());
|
||||
cmd.arg("allowinferiorcalls", s.allowInferiorCalls());
|
||||
cmd.arg("autoderef", s.autoDerefPointers());
|
||||
cmd.arg("dyntype", s.useDynamicType());
|
||||
cmd.arg("qobjectnames", s.showQObjectNames());
|
||||
|
Reference in New Issue
Block a user