Fix source mapping persistent file location
[qt-creator:android-qt-creator.git] / src / plugins / debugger / debuggeractions.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at info@qt.nokia.com.
30 **
31 **************************************************************************/
32
33 #include "debuggeractions.h"
34 #ifdef Q_OS_WIN
35 #include "registerpostmortemaction.h"
36 #endif
37
38 #include <coreplugin/icore.h>
39 #include <projectexplorer/persistentsettings.h>
40 #include <utils/savedaction.h>
41 #include <utils/qtcassert.h>
42 #include <utils/pathchooser.h>
43
44 #include <QtCore/QDateTime>
45 #include <QtCore/QDebug>
46 #include <QtCore/QVariant>
47 #include <QtCore/QSettings>
48 #include <QtCore/QFileInfo>
49
50
51 using namespace Utils;
52 using namespace ProjectExplorer;
53
54 static const char debugModeSettingsGroupC[] = "DebugMode";
55 static const char sourcePathMappingArrayNameC[] = "SourcePathMappings";
56 static const char sourcePathMappingSourceKeyC[] = "Source";
57 static const char sourcePathMappingTargetKeyC[] = "Target";
58
59 namespace Debugger {
60 namespace Internal {
61
62 namespace {
63     const QLatin1String sourcePathMappingFilename("/source_mapping.xml");
64     const char * const changeTimeStamp ="ChangeTimeStamp";
65     static QString settingsFileName()
66     {
67         return Core::ICore::instance()->resourcePath()
68                 + QLatin1String("/Nokia") + sourcePathMappingFilename;
69     }
70 }
71 void GlobalDebuggerOptions::toSettings(QSettings *s) const
72 {
73     QFileInfo fileInfo(settingsFileName());
74     if (fileInfo.exists())
75         s->setValue(changeTimeStamp, fileInfo.lastModified().toMSecsSinceEpoch()/1000);
76
77     s->beginWriteArray(QLatin1String(sourcePathMappingArrayNameC));
78     if (!sourcePathMap.isEmpty()) {
79         const QString sourcePathMappingSourceKey = QLatin1String(sourcePathMappingSourceKeyC);
80         const QString sourcePathMappingTargetKey = QLatin1String(sourcePathMappingTargetKeyC);
81         int i = 0;
82         const SourcePathMap::const_iterator cend = sourcePathMap.constEnd();
83         for (SourcePathMap::const_iterator it = sourcePathMap.constBegin(); it != cend; ++it, ++i) {
84             s->setArrayIndex(i);
85             s->setValue(sourcePathMappingSourceKey, it.key());
86             s->setValue(sourcePathMappingTargetKey, it.value());
87         }
88     }
89     s->endArray();
90 }
91
92 void GlobalDebuggerOptions::fromSettings(QSettings *s)
93 {
94     sourcePathMap.clear();
95     if (const int count = s->beginReadArray(QLatin1String(sourcePathMappingArrayNameC))) {
96         const QString sourcePathMappingSourceKey = QLatin1String(sourcePathMappingSourceKeyC);
97         const QString sourcePathMappingTargetKey = QLatin1String(sourcePathMappingTargetKeyC);
98         for (int i = 0; i < count; ++i) {
99              s->setArrayIndex(i);
100              sourcePathMap.insert(s->value(sourcePathMappingSourceKey).toString(),
101                                   s->value(sourcePathMappingTargetKey).toString());
102         }
103     }
104     s->endArray();
105     PersistentSettingsReader reader;
106     if (reader.load(settingsFileName()) && s->value(changeTimeStamp).toInt() != QFileInfo(settingsFileName()).lastModified().toMSecsSinceEpoch()/1000)
107     {
108         const QVariantMap map=reader.restoreValues();
109         foreach(QString key, map.keys())
110             sourcePathMap.insert(key, map[key].toString());
111     }
112 }
113
114 //////////////////////////////////////////////////////////////////////////
115 //
116 // DebuggerSettings
117 //
118 //////////////////////////////////////////////////////////////////////////
119
120 DebuggerSettings::DebuggerSettings(QSettings *settings)
121 {
122     m_settings = settings;
123     const QString debugModeGroup = QLatin1String(debugModeSettingsGroupC);
124
125     SavedAction *item = 0;
126
127     item = new SavedAction(this);
128     insertItem(SettingsDialog, item);
129     item->setText(tr("Debugger Properties..."));
130
131     //
132     // View
133     //
134     item = new SavedAction(this);
135     item->setText(tr("Always Adjust Column Widths to Contents"));
136     item->setCheckable(true);
137     item->setValue(false);
138     item->setDefaultValue(false);
139     item->setSettingsKey(debugModeGroup,
140         QLatin1String("AlwaysAdjustLocalsColumnWidths"));
141     insertItem(AlwaysAdjustLocalsColumnWidths, item);
142
143     item = new SavedAction(this);
144     item->setText(tr("Always Adjust Column Widths to Contents"));
145     item->setCheckable(true);
146     item->setValue(false);
147     item->setDefaultValue(false);
148     item->setSettingsKey(debugModeGroup,
149         QLatin1String("AlwaysAdjustStackColumnWidths"));
150     insertItem(AlwaysAdjustStackColumnWidths, item);
151
152     item = new SavedAction(this);
153     item->setText(tr("Always Adjust Column Widths to Contents"));
154     item->setCheckable(true);
155     item->setValue(false);
156     item->setDefaultValue(false);
157     item->setSettingsKey(debugModeGroup,
158         QLatin1String("AlwaysAdjustThreadsColumnWidths"));
159     insertItem(AlwaysAdjustThreadsColumnWidths, item);
160
161     item = new SavedAction(this);
162     item->setText(tr("Always Adjust Column Widths to Contents"));
163     item->setCheckable(true);
164     item->setValue(false);
165     item->setDefaultValue(false);
166     item->setSettingsKey(debugModeGroup,
167         QLatin1String("AlwaysAdjustRegistersColumnWidths"));
168     insertItem(AlwaysAdjustRegistersColumnWidths, item);
169
170     item = new SavedAction(this);
171     item->setText(tr("Always Adjust Column Widths to Contents"));
172     item->setCheckable(true);
173     item->setValue(false);
174     item->setDefaultValue(false);
175     item->setSettingsKey(debugModeGroup,
176         QLatin1String("AlwaysAdjustSnapshotsColumnWidths"));
177     insertItem(AlwaysAdjustSnapshotsColumnWidths, item);
178
179     item = new SavedAction(this);
180     item->setText(tr("Always Adjust Column Widths to Contents"));
181     item->setCheckable(true);
182     item->setValue(false);
183     item->setDefaultValue(false);
184     item->setSettingsKey(debugModeGroup,
185         QLatin1String("AlwaysAdjustBreakpointsColumnWidths"));
186     insertItem(AlwaysAdjustBreakpointsColumnWidths, item);
187
188     item = new SavedAction(this);
189     item->setText(tr("Always Adjust Column Widths to Contents"));
190     item->setCheckable(true);
191     item->setValue(false);
192     item->setDefaultValue(false);
193     item->setSettingsKey(debugModeGroup,
194         QLatin1String("AlwaysAdjustModulesColumnWidths"));
195     insertItem(AlwaysAdjustModulesColumnWidths, item);
196
197     item = new SavedAction(this);
198     item->setText(tr("Use Alternating Row Colors"));
199     item->setSettingsKey(debugModeGroup, QLatin1String("UseAlternatingRowColours"));
200     item->setCheckable(true);
201     item->setDefaultValue(false);
202     insertItem(UseAlternatingRowColors, item);
203
204     item = new SavedAction(this);
205     item->setText(tr("Debugger Font Size Follows Main Editor"));
206     item->setSettingsKey(debugModeGroup, QLatin1String("FontSizeFollowsEditor"));
207     item->setCheckable(true);
208     item->setDefaultValue(false);
209     insertItem(FontSizeFollowsEditor, item);
210
211     item = new SavedAction(this);
212     item->setText(tr("Show a Message Box When Receiving a Signal"));
213     item->setSettingsKey(debugModeGroup, QLatin1String("UseMessageBoxForSignals"));
214     item->setCheckable(true);
215     item->setDefaultValue(true);
216     item->setValue(true);
217     insertItem(UseMessageBoxForSignals, item);
218
219     item = new SavedAction(this);
220     item->setText(tr("Log Time Stamps"));
221     item->setSettingsKey(debugModeGroup, QLatin1String("LogTimeStamps"));
222     item->setCheckable(true);
223     item->setDefaultValue(false);
224     insertItem(LogTimeStamps, item);
225
226     item = new SavedAction(this);
227     item->setText(tr("Verbose Log"));
228     item->setSettingsKey(debugModeGroup, QLatin1String("VerboseLog"));
229     item->setCheckable(true);
230     item->setDefaultValue(false);
231     insertItem(VerboseLog, item);
232
233     item = new SavedAction(this);
234     item->setText(tr("Operate by Instruction"));
235     item->setCheckable(true);
236     item->setDefaultValue(false);
237     item->setIcon(QIcon(QLatin1String(":/debugger/images/debugger_singleinstructionmode.png")));
238     item->setToolTip(tr("This switches the debugger to instruction-wise "
239         "operation mode. In this mode, stepping operates on single "
240         "instructions and the source location view also shows the "
241         "disassembled instructions."));
242     item->setIconVisibleInMenu(false);
243     insertItem(OperateByInstruction, item);
244
245     item = new SavedAction(this);
246     item->setText(tr("Dereference Pointers Automatically"));
247     item->setCheckable(true);
248     item->setDefaultValue(true);
249     item->setSettingsKey(debugModeGroup, QLatin1String("AutoDerefPointers"));
250     item->setToolTip(tr("This switches the Locals&&Watchers view to "
251         "automatically dereference pointers. This saves a level in the "
252         "tree view, but also loses data for the now-missing intermediate "
253         "level."));
254     insertItem(AutoDerefPointers, item);
255
256     //
257     // Locals & Watchers
258     //
259     item = new SavedAction(this);
260     item->setSettingsKey(debugModeGroup, QLatin1String("ShowStandardNamespace"));
261     item->setText(tr("Show \"std::\" Namespace in Types"));
262     item->setCheckable(true);
263     item->setDefaultValue(true);
264     item->setValue(true);
265     insertItem(ShowStdNamespace, item);
266
267     item = new SavedAction(this);
268     item->setSettingsKey(debugModeGroup, QLatin1String("ShowQtNamespace"));
269     item->setText(tr("Show Qt's Namespace in Types"));
270     item->setCheckable(true);
271     item->setDefaultValue(true);
272     item->setValue(true);
273     insertItem(ShowQtNamespace, item);
274
275     item = new SavedAction(this);
276     item->setSettingsKey(debugModeGroup, QLatin1String("SortStructMembers"));
277     item->setText(tr("Sort Members of Classes and Structs Alphabetically"));
278     item->setCheckable(true);
279     item->setDefaultValue(true);
280     item->setValue(true);
281     insertItem(SortStructMembers, item);
282
283     //
284     // DebuggingHelper
285     //
286     item = new SavedAction(this);
287     item->setSettingsKey(debugModeGroup, QLatin1String("UseDebuggingHelper"));
288     item->setText(tr("Use Debugging Helpers"));
289     item->setCheckable(true);
290     item->setDefaultValue(true);
291     item->setValue(true);
292     insertItem(UseDebuggingHelpers, item);
293
294     item = new SavedAction(this);
295     item->setSettingsKey(debugModeGroup, QLatin1String("UseCodeModel"));
296     item->setText(tr("Use Code Model"));
297     item->setToolTip(tr("Selecting this causes the C++ Code Model being asked "
298       "for variable scope information. This might result in slightly faster "
299       "debugger operation but may fail for optimized code."));
300     item->setCheckable(true);
301     item->setDefaultValue(true);
302     item->setValue(true);
303     insertItem(UseCodeModel, item);
304
305     item = new SavedAction(this);
306     item->setSettingsKey(debugModeGroup, QLatin1String("ShowThreadNames"));
307     item->setCheckable(true);
308     item->setDefaultValue(false);
309     item->setValue(false);
310     insertItem(ShowThreadNames, item);
311
312
313     //
314     // Breakpoints
315     //
316     item = new SavedAction(this);
317     item->setText(tr("Synchronize Breakpoints"));
318     insertItem(SynchronizeBreakpoints, item);
319
320     item = new SavedAction(this);
321     item->setText(tr("Adjust Breakpoint Locations"));
322     item->setToolTip(tr("Not all source code lines generate "
323       "executable code. Putting a breakpoint on such a line acts as "
324       "if the breakpoint was set on the next line that generated code. "
325       "Selecting 'Adjust Breakpoint Locations' shifts the red "
326       "breakpoint markers in such cases to the location of the true "
327       "breakpoint."));
328     item->setCheckable(true);
329     item->setDefaultValue(true);
330     item->setValue(true);
331     item->setSettingsKey(debugModeGroup, QLatin1String("AdjustBreakpointLocations"));
332     insertItem(AdjustBreakpointLocations, item);
333
334     item = new SavedAction(this);
335     item->setText(tr("Break on \"throw\""));
336     item->setCheckable(true);
337     item->setDefaultValue(false);
338     item->setValue(false);
339     item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnThrow"));
340     insertItem(BreakOnThrow, item);
341
342     item = new SavedAction(this);
343     item->setText(tr("Break on \"catch\""));
344     item->setCheckable(true);
345     item->setDefaultValue(false);
346     item->setValue(false);
347     item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnCatch"));
348     insertItem(BreakOnCatch, item);
349
350     item = new SavedAction(this);
351     item->setText(tr("Break on \"qWarning\""));
352     item->setCheckable(true);
353     item->setDefaultValue(false);
354     item->setValue(false);
355     item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnWarning"));
356     insertItem(BreakOnWarning, item);
357
358     item = new SavedAction(this);
359     item->setText(tr("Break on \"qFatal\""));
360     item->setCheckable(true);
361     item->setDefaultValue(false);
362     item->setValue(false);
363     item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnFatal"));
364     insertItem(BreakOnFatal, item);
365
366     //
367     // Settings
368     //
369
370     item = new SavedAction(this);
371     item->setSettingsKey(debugModeGroup, QLatin1String("LoadGdbInit"));
372     item->setDefaultValue(QString());
373     item->setCheckable(true);
374     item->setDefaultValue(true);
375     item->setValue(true);
376     insertItem(LoadGdbInit, item);
377
378     item = new SavedAction(this);
379     item->setSettingsKey(debugModeGroup, QLatin1String("TargetAsync"));
380     item->setCheckable(true);
381     item->setDefaultValue(false);
382     item->setValue(false);
383     insertItem(TargetAsync, item);
384
385     item = new SavedAction(this);
386     item->setSettingsKey(debugModeGroup, QLatin1String("ScriptFile"));
387     item->setDefaultValue(QString());
388     insertItem(GdbScriptFile, item);
389
390     item = new SavedAction(this);
391     item->setSettingsKey(debugModeGroup, QLatin1String("CloseBuffersOnExit"));
392     item->setCheckable(true);
393     item->setDefaultValue(false);
394     insertItem(CloseBuffersOnExit, item);
395
396     item = new SavedAction(this);
397     item->setSettingsKey(debugModeGroup, QLatin1String("SwitchModeOnExit"));
398     item->setCheckable(true);
399     item->setDefaultValue(false);
400     insertItem(SwitchModeOnExit, item);
401
402     item = new SavedAction(this);
403     item->setSettingsKey(debugModeGroup, QLatin1String("AutoQuit"));
404     item->setText(tr("Automatically Quit Debugger"));
405     item->setCheckable(true);
406     item->setDefaultValue(false);
407     insertItem(AutoQuit, item);
408
409     item = new SavedAction(this);
410     item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTips"));
411     item->setText(tr("Use tooltips in main editor when debugging"));
412     item->setToolTip(tr("Checking this will enable tooltips for variable "
413         "values during debugging. Since this can slow down debugging and "
414         "does not provide reliable information as it does not use scope "
415         "information, it is switched off by default."));
416     item->setCheckable(true);
417     item->setDefaultValue(false);
418     insertItem(UseToolTipsInMainEditor, item);
419
420     item = new SavedAction(this);
421     item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInLocalsView"));
422     item->setText(tr("Use Tooltips in Locals View When Debugging"));
423     item->setToolTip(tr("Checking this will enable tooltips in the locals "
424         "view during debugging."));
425     item->setCheckable(true);
426     item->setDefaultValue(false);
427     insertItem(UseToolTipsInLocalsView, item);
428
429     item = new SavedAction(this);
430     item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInBreakpointsView"));
431     item->setText(tr("Use Tooltips in Breakpoints View When Debugging"));
432     item->setToolTip(tr("Checking this will enable tooltips in the breakpoints "
433         "view during debugging."));
434     item->setCheckable(true);
435     item->setDefaultValue(false);
436     insertItem(UseToolTipsInBreakpointsView, item);
437
438     item = new SavedAction(this);
439     item->setSettingsKey(debugModeGroup, QLatin1String("UseAddressInBreakpointsView"));
440     item->setText(tr("Show Address Data in Breakpoints View When Debugging"));
441     item->setToolTip(tr("Checking this will show a column with address "
442         "information in the breakpoint view during debugging."));
443     item->setCheckable(true);
444     item->setDefaultValue(false);
445     insertItem(UseAddressInBreakpointsView, item);
446
447     item = new SavedAction(this);
448     item->setSettingsKey(debugModeGroup, QLatin1String("UseAddressInStackView"));
449     item->setText(tr("Show Address Data in Stack View When Debugging"));
450     item->setToolTip(tr("Checking this will show a column with address "
451         "information in the stack view during debugging."));
452     item->setCheckable(true);
453     item->setDefaultValue(false);
454     insertItem(UseAddressInStackView, item);
455     item = new SavedAction(this);
456
457     item->setSettingsKey(debugModeGroup, QLatin1String("ListSourceFiles"));
458     item->setText(tr("List Source Files"));
459     item->setCheckable(true);
460     item->setDefaultValue(false);
461     insertItem(ListSourceFiles, item);
462
463     item = new SavedAction(this);
464     item->setSettingsKey(debugModeGroup, QLatin1String("SkipKnownFrames"));
465     item->setText(tr("Skip Known Frames"));
466     item->setCheckable(true);
467     item->setDefaultValue(false);
468     insertItem(SkipKnownFrames, item);
469
470     item = new SavedAction(this);
471     item->setSettingsKey(debugModeGroup, QLatin1String("EnableReverseDebugging"));
472     item->setText(tr("Enable Reverse Debugging"));
473     item->setCheckable(true);
474     item->setDefaultValue(false);
475     insertItem(EnableReverseDebugging, item);
476
477 #ifdef Q_OS_WIN
478     item = new RegisterPostMortemAction(this);
479     item->setSettingsKey(debugModeGroup, QLatin1String("RegisterForPostMortem"));
480     item->setText(tr("Register For Post-Mortem Debugging"));
481     item->setCheckable(true);
482     item->setDefaultValue(false);
483     insertItem(RegisterForPostMortem, item);
484 #endif
485
486     item = new SavedAction(this);
487     item->setSettingsKey(debugModeGroup, QLatin1String("AllPluginBreakpoints"));
488     item->setDefaultValue(true);
489     insertItem(AllPluginBreakpoints, item);
490
491     item = new SavedAction(this);
492     item->setSettingsKey(debugModeGroup, QLatin1String("SelectedPluginBreakpoints"));
493     item->setDefaultValue(false);
494     insertItem(SelectedPluginBreakpoints, item);
495
496     item = new SavedAction(this);
497     item->setSettingsKey(debugModeGroup, QLatin1String("NoPluginBreakpoints"));
498     item->setDefaultValue(false);
499     insertItem(NoPluginBreakpoints, item);
500
501     item = new SavedAction(this);
502     item->setSettingsKey(debugModeGroup, QLatin1String("SelectedPluginBreakpointsPattern"));
503     item->setDefaultValue(QLatin1String(".*"));
504     insertItem(SelectedPluginBreakpointsPattern, item);
505
506     item = new SavedAction(this);
507     item->setSettingsKey(debugModeGroup, QLatin1String("MaximalStackDepth"));
508     item->setDefaultValue(20);
509     insertItem(MaximalStackDepth, item);
510
511     item = new SavedAction(this);
512     item->setText(tr("Reload Full Stack"));
513     insertItem(ExpandStack, item);
514
515     item = new SavedAction(this);
516     item->setText(tr("Create Full Backtrace"));
517     insertItem(CreateFullBacktrace, item);
518
519     item = new SavedAction(this);
520     item->setSettingsKey(debugModeGroup, QLatin1String("WatchdogTimeout"));
521     item->setDefaultValue(20);
522     insertItem(GdbWatchdogTimeout, item);
523 }
524
525 DebuggerSettings::~DebuggerSettings()
526 {
527     qDeleteAll(m_items);
528 }
529
530 void DebuggerSettings::insertItem(int code, SavedAction *item)
531 {
532     QTC_ASSERT(!m_items.contains(code),
533         qDebug() << code << item->toString(); return);
534     QTC_ASSERT(item->settingsKey().isEmpty() || item->defaultValue().isValid(),
535         qDebug() << "NO DEFAULT VALUE FOR " << item->settingsKey());
536     m_items[code] = item;
537 }
538
539 void DebuggerSettings::readSettings()
540 {
541     foreach (SavedAction *item, m_items)
542         item->readSettings(m_settings);
543 }
544
545 void DebuggerSettings::writeSettings() const
546 {
547     foreach (SavedAction *item, m_items)
548         item->writeSettings(m_settings);
549 }
550
551 SavedAction *DebuggerSettings::item(int code) const
552 {
553     QTC_ASSERT(m_items.value(code, 0), qDebug() << "CODE: " << code; return 0);
554     return m_items.value(code, 0);
555 }
556
557 QString DebuggerSettings::dump() const
558 {
559     QString out;
560     QTextStream ts(&out);
561     ts << "Debugger settings: ";
562     foreach (SavedAction *item, m_items) {
563         QString key = item->settingsKey();
564         if (!key.isEmpty()) {
565             const QString current = item->value().toString();
566             const QString default_ = item->defaultValue().toString();
567             ts << '\n' << key << ": " << current
568                << "  (default: " << default_ << ")";
569             if (current != default_)
570                 ts <<  "  ***";
571         }
572     }
573     return out;
574 }
575
576 } // namespace Internal
577 } // namespace Debugger
578