1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "debugger_global.h"
29 #include "debuggerconstants.h"
30 #include "debuggeritem.h"
31 #include "debuggerprotocol.h"
32 #include "breakhandler.h"
33 #include "threadshandler.h"
34 
35 #include <coreplugin/icontext.h>
36 #include <projectexplorer/devicesupport/idevice.h>
37 #include <projectexplorer/runcontrol.h>
38 #include <texteditor/textmark.h>
39 #include <utils/fileutils.h>
40 
41 #include <QProcess>
42 
43 QT_BEGIN_NAMESPACE
44 class QDebug;
45 class QPoint;
46 QT_END_NAMESPACE
47 
48 namespace Core { class IOptionsPage; }
49 
50 namespace Utils {
51 class MacroExpander;
52 class Perspective;
53 } // Utils
54 
55 namespace Debugger {
56 
57 class DebuggerRunTool;
58 
59 enum DebuggerState
60 {
61     DebuggerNotReady,          // Debugger not started
62 
63     EngineSetupRequested,      // Engine starts
64     EngineSetupFailed,
65 
66     EngineRunRequested,
67     EngineRunFailed,
68 
69     InferiorUnrunnable,        // Used in the core dump adapter
70 
71     InferiorRunRequested,      // Debuggee requested to run
72     InferiorRunOk,             // Debuggee running
73     InferiorRunFailed,         // Debuggee not running
74 
75     InferiorStopRequested,     // Debuggee running, stop requested
76     InferiorStopOk,            // Debuggee stopped
77     InferiorStopFailed,        // Debuggee not stopped, will kill debugger
78 
79     InferiorShutdownRequested,
80     InferiorShutdownFinished,
81 
82     EngineShutdownRequested,
83     EngineShutdownFinished,
84 
85     DebuggerFinished
86 };
87 
88 DEBUGGER_EXPORT QDebug operator<<(QDebug str, DebuggerState state);
89 
90 namespace Internal {
91 
92 class DebuggerEnginePrivate;
93 class DebuggerPluginPrivate;
94 class DisassemblerAgent;
95 class MemoryAgent;
96 class WatchItem;
97 class BreakHandler;
98 class BreakpointParameters;
99 class LocationMark;
100 class LogWindow;
101 class ModulesHandler;
102 class RegisterHandler;
103 class PeripheralRegisterHandler;
104 class Section;
105 class SourceFilesHandler;
106 class StackFrame;
107 class StackHandler;
108 class Symbol;
109 class WatchHandler;
110 class WatchTreeView;
111 class DebuggerToolTipContext;
112 class DebuggerToolTipManager;
113 class MemoryViewSetupData;
114 class TerminalRunner;
115 
116 class DebuggerRunParameters
117 {
118 public:
119     DebuggerStartMode startMode = NoStartMode;
120     DebuggerCloseMode closeMode = KillAtClose;
121 
122     ProjectExplorer::Runnable inferior;
123     QString displayName; // Used in the Snapshots view.
124     Utils::ProcessHandle attachPID;
125     QStringList solibSearchPath;
126 
127     // Used by Qml debugging.
128     QUrl qmlServer;
129 
130     // Used by general remote debugging.
131     QString remoteChannel;
132     bool useExtendedRemote = false; // Whether to use GDB's target extended-remote or not.
133     Utils::FilePath symbolFile;
134 
135     // Used by Mer plugin (3rd party)
136     QMap<QString, QString> sourcePathMap;
137 
138     // Used by baremetal plugin
139     QString commandsForReset; // commands used for resetting the inferior
140     bool useContinueInsteadOfRun = false; // if connected to a hw debugger run is not possible but continue is used
141     QString commandsAfterConnect; // additional commands to post after connection to debug target
142 
143     // Used by Valgrind
144     QStringList expectedSignals;
145 
146     // For QNX debugging
147     bool useCtrlCStub = false;
148 
149     // Used by Android to avoid false positives on warnOnRelease
150     bool skipExecutableValidation = false;
151     bool useTargetAsync = false;
152     Utils::FilePaths additionalSearchDirectories;
153 
154     // Used by iOS.
155     QString platform;
156     QString deviceSymbolsRoot;
157     bool continueAfterAttach = false;
158     Utils::FilePath sysRoot;
159 
160     // Used by general core file debugging. Public access requested in QTCREATORBUG-17158.
161     QString coreFile;
162 
163     // Macro-expanded and passed to debugger startup.
164     QString additionalStartupCommands;
165 
166     DebuggerEngineType cppEngineType = NoEngineType;
167 
168     bool isQmlDebugging = false;
169     bool breakOnMain = false;
170     bool multiProcess = false; // Whether to set detach-on-fork off.
171     bool useTerminal = false;
172     bool runAsRoot = false;
173 
174     ProjectExplorer::Runnable debugger;
175     QString overrideStartScript; // Used in attach to core and remote debugging
176     QString startMessage; // First status message shown.
177     QString debugInfoLocation; // Gdb "set-debug-file-directory".
178     QStringList debugSourceLocation; // Gdb "directory"
179     QString qtPackageSourceLocation;
180     bool isSnapshot = false; // Set if created internally.
181     ProjectExplorer::Abi toolChainAbi;
182 
183     Utils::FilePath projectSourceDirectory;
184     Utils::FilePaths projectSourceFiles;
185 
186     // Used by Script debugging
187     QString interpreter;
188     QString mainScript;
189 
190     // Used by AttachCrashedExternal.
191     QString crashParameter;
192 
193     bool nativeMixedEnabled = false;
194 
195     bool isCppDebugging() const;
196     bool isNativeMixedDebugging() const;
197 
198     Utils::MacroExpander *macroExpander = nullptr;
199 
200     Utils::optional<int> exitCode = {};
201 
202     // For Debugger testing.
203     int testCase = 0;
204 
205     QStringList validationErrors;
206 };
207 
208 class UpdateParameters
209 {
210 public:
211     UpdateParameters(const QString &partialVariable = QString()) :
partialVariable(partialVariable)212         partialVariable(partialVariable) {}
213 
partialVariables()214     QStringList partialVariables() const
215     {
216         QStringList result;
217         if (!partialVariable.isEmpty())
218             result.append(partialVariable);
219         return result;
220     }
221 
222     QString partialVariable;
223 };
224 
225 class Location
226 {
227 public:
228     Location() = default;
Location(quint64 address)229     Location(quint64 address) { m_address = address; }
Location(const Utils::FilePath & file)230     Location(const Utils::FilePath &file) { m_fileName = file; }
231     Location(const Utils::FilePath &file, int line, bool marker = true)
232         { m_lineNumber = line; m_fileName = file; m_needsMarker = marker; }
233     Location(const StackFrame &frame, bool marker = true);
fileName()234     Utils::FilePath fileName() const { return m_fileName; }
functionName()235     QString functionName() const { return m_functionName; }
from()236     QString from() const { return m_from; }
lineNumber()237     int lineNumber() const { return m_lineNumber; }
setNeedsRaise(bool on)238     void setNeedsRaise(bool on) { m_needsRaise = on; }
setNeedsMarker(bool on)239     void setNeedsMarker(bool on) { m_needsMarker = on; }
setFileName(const Utils::FilePath & fileName)240     void setFileName(const Utils::FilePath &fileName) { m_fileName = fileName; }
setUseAssembler(bool on)241     void setUseAssembler(bool on) { m_hasDebugInfo = !on; }
needsRaise()242     bool needsRaise() const { return m_needsRaise; }
needsMarker()243     bool needsMarker() const { return m_needsMarker; }
hasDebugInfo()244     bool hasDebugInfo() const { return m_hasDebugInfo; }
canBeDisassembled()245     bool canBeDisassembled() const
246         { return m_address != quint64(-1) || !m_functionName.isEmpty(); }
address()247     quint64 address() const { return m_address; }
248 
249 private:
250     bool m_needsMarker = false;
251     bool m_needsRaise = true;
252     bool m_hasDebugInfo = true;
253     int m_lineNumber = -1;
254     Utils::FilePath m_fileName;
255     QString m_functionName;
256     QString m_from;
257     quint64 m_address = 0;
258 };
259 
260 class DebuggerEngine : public QObject
261 {
262     Q_OBJECT
263 
264 public:
265     DebuggerEngine();
266     ~DebuggerEngine() override;
267 
268     void setRunTool(DebuggerRunTool *runTool);
269     void setRunParameters(const DebuggerRunParameters &runParameters);
270 
271     void setRunId(const QString &id);
272     QString runId() const;
273 
274     const DebuggerRunParameters &runParameters() const;
275     void setCompanionEngine(DebuggerEngine *engine);
276     void setSecondaryEngine();
277 
278     void start();
279 
280     enum {
281         // Remove need to qualify each use.
282         NeedsTemporaryStop = DebuggerCommand::NeedsTemporaryStop,
283         NeedsFullStop = DebuggerCommand::NeedsFullStop,
284         Discardable = DebuggerCommand::Discardable,
285         ConsoleCommand = DebuggerCommand::ConsoleCommand,
286         NeedsFlush = DebuggerCommand::NeedsFlush,
287         ExitRequest = DebuggerCommand::ExitRequest,
288         RunRequest = DebuggerCommand::RunRequest,
289         LosesChild = DebuggerCommand::LosesChild,
290         InUpdateLocals = DebuggerCommand::InUpdateLocals,
291         NativeCommand = DebuggerCommand::NativeCommand,
292         Silent = DebuggerCommand::Silent
293     };
294 
295     virtual bool canHandleToolTip(const DebuggerToolTipContext &) const;
296     virtual void expandItem(const QString &iname); // Called when item in tree gets expanded.
297     virtual void updateItem(const QString &iname); // Called for fresh watch items.
298     void updateWatchData(const QString &iname); // FIXME: Merge with above.
299     virtual void selectWatchData(const QString &iname);
300 
validateRunParameters(DebuggerRunParameters &)301     virtual void validateRunParameters(DebuggerRunParameters &) {}
prepareForRestart()302     virtual void prepareForRestart() {}
abortDebuggerProcess()303     virtual void abortDebuggerProcess() {} // second attempt
304 
305     virtual void watchPoint(const QPoint &pnt);
306     virtual void runCommand(const DebuggerCommand &cmd);
307     virtual void openMemoryView(const MemoryViewSetupData &data);
308     virtual void fetchMemory(MemoryAgent *, quint64 addr, quint64 length);
309     virtual void changeMemory(MemoryAgent *, quint64 addr, const QByteArray &data);
310     virtual void updateMemoryViews();
311     virtual void openDisassemblerView(const Internal::Location &location);
312     virtual void fetchDisassembler(Internal::DisassemblerAgent *);
313     virtual void activateFrame(int index);
314 
315     virtual void reloadModules();
316     virtual void examineModules();
317     virtual void loadSymbols(const QString &moduleName);
318     virtual void loadSymbolsForStack();
319     virtual void loadAllSymbols();
320     virtual void requestModuleSymbols(const QString &moduleName);
321     virtual void requestModuleSections(const QString &moduleName);
322 
323     virtual void reloadRegisters();
324     virtual void reloadPeripheralRegisters();
325     virtual void reloadSourceFiles();
326     virtual void reloadFullStack();
327     virtual void loadAdditionalQmlStack();
328     virtual void reloadDebuggingHelpers();
329 
330     virtual void setRegisterValue(const QString &name, const QString &value);
331     virtual void setPeripheralRegisterValue(quint64 address, quint64 value);
332     virtual void addOptionPages(QList<Core::IOptionsPage*> *) const;
333     virtual bool hasCapability(unsigned cap) const = 0;
debugLastCommand()334     virtual void debugLastCommand() {}
335 
336     virtual QString qtNamespace() const;
337     void setQtNamespace(const QString &ns);
338 
339     virtual void createSnapshot();
340     virtual void updateAll();
341     virtual void updateLocals();
342 
343     Core::Context debuggerContext() const;
languageContext()344     virtual Core::Context languageContext() const { return {}; }
345     QString displayName() const;
346 
347     virtual bool acceptsBreakpoint(const BreakpointParameters &bp) const = 0;
348     virtual void insertBreakpoint(const Breakpoint &bp) = 0;
349     virtual void removeBreakpoint(const Breakpoint &bp) = 0;
350     virtual void updateBreakpoint(const Breakpoint &bp) = 0;
351     virtual void enableSubBreakpoint(const SubBreakpoint &sbp, bool enabled);
352 
acceptsDebuggerCommands()353     virtual bool acceptsDebuggerCommands() const { return true; }
354     virtual void executeDebuggerCommand(const QString &command);
355 
356     virtual void assignValueInDebugger(WatchItem *item,
357         const QString &expr, const QVariant &value);
358     virtual void selectThread(const Internal::Thread &thread) = 0;
359 
executeRecordReverse(bool)360     virtual void executeRecordReverse(bool) {}
executeReverse(bool)361     virtual void executeReverse(bool) {}
362 
363     ModulesHandler *modulesHandler() const;
364     RegisterHandler *registerHandler() const;
365     PeripheralRegisterHandler *peripheralRegisterHandler() const;
366     StackHandler *stackHandler() const;
367     ThreadsHandler *threadsHandler() const;
368     WatchHandler *watchHandler() const;
369     SourceFilesHandler *sourceFilesHandler() const;
370     BreakHandler *breakHandler() const;
371     LogWindow *logWindow() const;
372     DisassemblerAgent *disassemblerAgent() const;
373 
374     void progressPing();
375     bool debuggerActionsEnabled() const;
376     virtual bool companionPreventsActions() const;
377 
378     bool operatesByInstruction() const;
379     virtual void operateByInstructionTriggered(bool on); // FIXME: Remove.
380 
381     DebuggerState state() const;
382     bool isDying() const;
383 
384     static QString stateName(int s);
385 
386     void notifyExitCode(int code);
387     void notifyInferiorPid(const Utils::ProcessHandle &pid);
388     qint64 inferiorPid() const;
389 
390     bool isReverseDebugging() const;
391     void handleBeginOfRecordingReached();
392     void handleRecordingFailed();
393     void handleRecordReverse(bool);
394     void handleReverseDirection(bool);
395 
396     // Convenience
397     void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1) const;
398     void showStatusMessage(const QString &msg, int timeout = -1) const;
399 
400     virtual void resetLocation();
401     virtual void gotoLocation(const Internal::Location &location);
402     void gotoCurrentLocation();
403     virtual void quitDebugger(); // called when pressing the stop button
404     void abortDebugger();
405     void updateUi(bool isCurrentEngine);
406 
407     bool isPrimaryEngine() const;
408 
409     virtual bool canDisplayTooltip() const;
410 
411     QString expand(const QString &string) const;
412     QString nativeStartupCommands() const;
413     Utils::Perspective *perspective() const;
414     void updateMarkers();
415 
416     void updateToolTips();
417     DebuggerToolTipManager *toolTipManager();
418 
419 signals:
420     void engineStarted();
421     void engineFinished();
422     void requestRunControlFinish();
423     void requestRunControlStop();
424     void attachToCoreRequested(const QString &coreFile);
425     void appendMessageRequested(const QString &msg,
426                                 Utils::OutputFormat format,
427                                 bool appendNewLine) const;
428 
429 protected:
430     void notifyEngineSetupOk();
431     void notifyEngineSetupFailed();
432     void notifyEngineRunFailed();
433 
434     void notifyEngineRunAndInferiorRunOk();
435     void notifyEngineRunAndInferiorStopOk();
436     void notifyEngineRunOkAndInferiorUnrunnable(); // Called by CoreAdapter.
437 
438     // Use notifyInferiorRunRequested() plus notifyInferiorRunOk() instead.
439     // void notifyInferiorSpontaneousRun();
440 
441     void notifyInferiorRunRequested();
442     void notifyInferiorRunOk();
443     void notifyInferiorRunFailed();
444 
445     void notifyInferiorIll();
446     void notifyInferiorExited();
447 
448     void notifyInferiorStopOk();
449     void notifyInferiorSpontaneousStop();
450     void notifyInferiorStopFailed();
451 
452 public:
453     void updateState();
454     QString formatStartParameters() const;
455     WatchTreeView *inspectorView();
456     void updateLocalsWindow(bool showReturn);
457     void raiseWatchersWindow();
458     QString debuggerName() const;
459 
460     bool isRegistersWindowVisible() const;
461     bool isPeripheralRegistersWindowVisible() const;
462     bool isModulesWindowVisible() const;
463 
464     void openMemoryEditor();
465 
466     static void showModuleSymbols(const QString &moduleName, const QVector<Symbol> &symbols);
467     static void showModuleSections(const QString &moduleName, const QVector<Section> &sections);
468 
469     void handleExecDetach();
470     void handleExecContinue();
471     void handleExecInterrupt();
472     void handleUserStop();
473     void handleAbort();
474     void handleReset();
475     void handleExecStepIn();
476     void handleExecStepOver();
477     void handleExecStepOut();
478     void handleExecReturn();
479     void handleExecJumpToLine();
480     void handleExecRunToLine();
481     void handleExecRunToSelectedFunction();
482     void handleAddToWatchWindow();
483     void handleFrameDown();
484     void handleFrameUp();
485 
486     // Breakpoint state transitions
487     void notifyBreakpointInsertProceeding(const Breakpoint &bp);
488     void notifyBreakpointInsertOk(const Breakpoint &bp);
489     void notifyBreakpointInsertFailed(const Breakpoint &bp);
490     void notifyBreakpointChangeOk(const Breakpoint &bp);
491     void notifyBreakpointChangeProceeding(const Breakpoint &bp);
492     void notifyBreakpointChangeFailed(const Breakpoint &bp);
493     void notifyBreakpointPending(const Breakpoint &bp);
494     void notifyBreakpointRemoveProceeding(const Breakpoint &bp);
495     void notifyBreakpointRemoveOk(const Breakpoint &bp);
496     void notifyBreakpointRemoveFailed(const Breakpoint &bp);
497     void notifyBreakpointNeedsReinsertion(const Breakpoint &bp);
498 
499 protected:
500     void setDebuggerName(const QString &name);
501     void notifyDebuggerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus,
502                                        const QString &backendName);
503 
504     virtual void setState(DebuggerState state, bool forced = false);
505 
506     void notifyInferiorShutdownFinished();
507 
508     void notifyEngineSpontaneousShutdown();
509     void notifyEngineShutdownFinished();
510 
511     void notifyEngineIll();
512 
513     virtual void setupEngine() = 0;
514     virtual void shutdownInferior() = 0;
515     virtual void shutdownEngine() = 0;
resetInferior()516     virtual void resetInferior() {}
517 
detachDebugger()518     virtual void detachDebugger() {}
519     virtual void executeStepOver(bool /*byInstruction*/ = false) {}
520     virtual void executeStepIn(bool /*byInstruction*/ = false) {}
executeStepOut()521     virtual void executeStepOut() {}
executeReturn()522     virtual void executeReturn() {}
523 
continueInferior()524     virtual void continueInferior() {}
interruptInferior()525     virtual void interruptInferior() {}
526     void requestInterruptInferior();
527 
executeRunToLine(const Internal::ContextData &)528     virtual void executeRunToLine(const Internal::ContextData &) {}
executeRunToFunction(const QString &)529     virtual void executeRunToFunction(const QString &) {}
executeJumpToLine(const Internal::ContextData &)530     virtual void executeJumpToLine(const Internal::ContextData &) {}
531 
532     virtual void frameUp();
533     virtual void frameDown();
534 
535     virtual void doUpdateLocals(const UpdateParameters &params);
536 
537     TerminalRunner *terminal() const;
538 
539     static QString msgStopped(const QString &reason = QString());
540     static QString msgStoppedBySignal(const QString &meaning, const QString &name);
541     static QString msgStoppedByException(const QString &description,
542         const QString &threadId);
543     static QString msgInterrupted();
544     bool showStoppedBySignalMessageBox(const QString meaning, QString name);
545     void showStoppedByExceptionMessageBox(const QString &description);
546 
547     void updateLocalsView(const GdbMi &all);
548     void checkState(DebuggerState state, const char *file, int line);
549     bool isNativeMixedEnabled() const;
550     bool isNativeMixedActive() const;
551     bool isNativeMixedActiveFrame() const;
552     void startDying() const;
553 
554     ProjectExplorer::IDevice::ConstPtr device() const;
555     DebuggerEngine *companionEngine() const;
556 
557 private:
558     friend class DebuggerPluginPrivate;
559     friend class DebuggerEnginePrivate;
560     friend class LocationMark;
561     friend class PeripheralRegisterHandler;
562     DebuggerEnginePrivate *d;
563 };
564 
565 class CppDebuggerEngine : public DebuggerEngine
566 {
567 public:
CppDebuggerEngine()568     CppDebuggerEngine() {}
~CppDebuggerEngine()569     ~CppDebuggerEngine() override {}
570 
571     void validateRunParameters(DebuggerRunParameters &rp) override;
572     Core::Context languageContext() const override;
573 };
574 
575 class LocationMark : public TextEditor::TextMark
576 {
577 public:
578     LocationMark(DebuggerEngine *engine, const Utils::FilePath &file, int line);
removedFromEditor()579     void removedFromEditor() override { updateLineNumber(0); }
580 
581     void updateIcon();
582 
583 private:
584     bool isDraggable() const override;
585     void dragToLine(int line) override;
586 
587     QPointer<DebuggerEngine> m_engine;
588 };
589 
590 } // namespace Internal
591 } // namespace Debugger
592 
593 Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
594 Q_DECLARE_METATYPE(Debugger::Internal::ContextData)
595