Commit 47fa65be authored by hjk's avatar hjk

debugger: some basic support for 'catch catch' and 'catch throw'

Hidden in the Breakpoints context menu.
parent 14d1edd5
...@@ -110,6 +110,7 @@ def listOfBreakpoints(d): ...@@ -110,6 +110,7 @@ def listOfBreakpoints(d):
#4.1 y 0x08056673 in Foo at ../app.cpp:126\n" #4.1 y 0x08056673 in Foo at ../app.cpp:126\n"
#4.2 y 0x0805678b in Foo at ../app.cpp:126\n" #4.2 y 0x0805678b in Foo at ../app.cpp:126\n"
#5 hw watchpoint keep y &main\n" #5 hw watchpoint keep y &main\n"
#6 breakpoint keep y 0xb6cf18e5 <__cxa_throw+5>\n"
lines = catchCliOutput("info break") lines = catchCliOutput("info break")
lines.reverse() lines.reverse()
...@@ -128,10 +129,15 @@ def listOfBreakpoints(d): ...@@ -128,10 +129,15 @@ def listOfBreakpoints(d):
number = line[0:5] number = line[0:5]
pos0x = line.find(" 0x") pos0x = line.find(" 0x")
posin = line.find(" in ", pos0x) posin = line.find(" in ", pos0x)
poslt = line.find(" <", pos0x)
posat = line.find(" at ", posin) posat = line.find(" at ", posin)
poscol = line.find(":", posat) poscol = line.find(":", posat)
if pos0x < posin and pos0x != -1: if pos0x != -1:
bp.address.append(line[pos0x + 1 : posin]) if pos0x < posin:
bp.address.append(line[pos0x + 1 : posin])
elif pos0x < poslt:
bp.address.append(line[pos0x + 1 : poslt])
bp.function = line[poslt + 2 : line.find('>', poslt)]
# Take "no address" as indication that the bp is pending. # Take "no address" as indication that the bp is pending.
#if line.find("<PENDING>") >= 0: #if line.find("<PENDING>") >= 0:
# bp.address.append("<PENDING>") # bp.address.append("<PENDING>")
......
...@@ -335,13 +335,15 @@ void BreakHandler::clear() ...@@ -335,13 +335,15 @@ void BreakHandler::clear()
int BreakHandler::findBreakpoint(const BreakpointData &needle) int BreakHandler::findBreakpoint(const BreakpointData &needle)
{ {
// looks for a breakpoint we might refer to // Search a breakpoint we might refer to.
qDebug() << "NEEDLE: " << needle.toString();
for (int index = 0; index != size(); ++index) { for (int index = 0; index != size(); ++index) {
const BreakpointData *data = at(index); const BreakpointData *data = at(index);
// clear hit. // Clear hit.
qDebug() << " TEST: " << data->toString();
if (data->bpNumber == needle.bpNumber) if (data->bpNumber == needle.bpNumber)
return index; return index;
// at least at a position we were looking for // At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location // FIXME: breaks multiple breakpoints at the same location
if (fileNameMatch(data->fileName, needle.bpFileName) if (fileNameMatch(data->fileName, needle.bpFileName)
&& data->lineNumber == needle.bpLineNumber) && data->lineNumber == needle.bpLineNumber)
......
...@@ -79,8 +79,8 @@ public: ...@@ -79,8 +79,8 @@ public:
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
BreakWindow::BreakWindow(QWidget *parent) BreakWindow::BreakWindow(DebuggerManager *manager)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false) : m_manager(manager), m_alwaysResizeColumnsToContents(false)
{ {
QAction *act = theDebuggerAction(UseAlternatingRowColors); QAction *act = theDebuggerAction(UseAlternatingRowColors);
setWindowTitle(tr("Breakpoints")); setWindowTitle(tr("Breakpoints"));
...@@ -143,6 +143,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev) ...@@ -143,6 +143,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
si = normalizeIndexes(si); si = normalizeIndexes(si);
const int rowCount = itemModel->rowCount(); const int rowCount = itemModel->rowCount();
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
QAction *deleteAction = new QAction(tr("Delete breakpoint"), &menu); QAction *deleteAction = new QAction(tr("Delete breakpoint"), &menu);
deleteAction->setEnabled(si.size() > 0); deleteAction->setEnabled(si.size() > 0);
...@@ -190,12 +191,18 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev) ...@@ -190,12 +191,18 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
toggleEnabledAction->setEnabled(si.size() > 0); toggleEnabledAction->setEnabled(si.size() > 0);
const bool fullpath = si.isEmpty() || itemModel->data(idx2, Qt::UserRole).toBool(); const bool fullpath = si.isEmpty() || itemModel->data(idx2, Qt::UserRole).toBool();
const QString str6 = fullpath ? tr("Use short path") : tr("Use full path"); const QString str6 = fullpath ? tr("Use Short Path") : tr("Use Full Path");
QAction *pathAction = new QAction(str6, &menu); QAction *pathAction = new QAction(str6, &menu);
pathAction->setEnabled(si.size() > 0); pathAction->setEnabled(si.size() > 0);
QAction *breakAtFunctionAction = new QAction(tr("Set Breakpoint at Function..."), this); QAction *breakAtFunctionAction =
QAction *breakAtMainAction = new QAction(tr("Set Breakpoint at Function \"main\""), this); new QAction(tr("Set Breakpoint at Function..."), this);
QAction *breakAtMainAction =
new QAction(tr("Set Breakpoint at Function \"main\""), this);
QAction *breakAtThrowAction =
new QAction(tr("Set Breakpoint at \"throw\""), this);
QAction *breakAtCatchAction =
new QAction(tr("Set Breakpoint at \"catch\""), this);
menu.addAction(deleteAction); menu.addAction(deleteAction);
menu.addAction(editConditionAction); menu.addAction(editConditionAction);
...@@ -209,6 +216,10 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev) ...@@ -209,6 +216,10 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
menu.addSeparator(); menu.addSeparator();
menu.addAction(breakAtFunctionAction); menu.addAction(breakAtFunctionAction);
menu.addAction(breakAtMainAction); menu.addAction(breakAtMainAction);
if (engineCapabilities & BreakOnThrowAndCatchCapability) {
menu.addAction(breakAtThrowAction);
menu.addAction(breakAtCatchAction);
}
menu.addSeparator(); menu.addSeparator();
menu.addAction(theDebuggerAction(UseToolTipsInBreakpointsView)); menu.addAction(theDebuggerAction(UseToolTipsInBreakpointsView));
menu.addAction(theDebuggerAction(UseAddressInBreakpointsView)); menu.addAction(theDebuggerAction(UseAddressInBreakpointsView));
...@@ -246,6 +257,10 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev) ...@@ -246,6 +257,10 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
emit breakByFunctionRequested(dlg.functionName()); emit breakByFunctionRequested(dlg.functionName());
} else if (act == breakAtMainAction) } else if (act == breakAtMainAction)
emit breakByFunctionMainRequested(); emit breakByFunctionMainRequested();
else if (act == breakAtThrowAction)
emit breakByFunctionRequested("__cxa_throw");
else if (act == breakAtCatchAction)
emit breakByFunctionRequested("__cxa_begin_catch");
} }
void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled) void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled)
......
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
#include <QtGui/QTreeView> #include <QtGui/QTreeView>
namespace Debugger { namespace Debugger {
class DebuggerManager;
namespace Internal { namespace Internal {
class BreakWindow : public QTreeView class BreakWindow : public QTreeView
...@@ -40,7 +43,7 @@ class BreakWindow : public QTreeView ...@@ -40,7 +43,7 @@ class BreakWindow : public QTreeView
Q_OBJECT Q_OBJECT
public: public:
BreakWindow(QWidget *parent = 0); explicit BreakWindow(DebuggerManager *manager);
public slots: public slots:
void resizeColumnsToContents(); void resizeColumnsToContents();
...@@ -70,6 +73,7 @@ private: ...@@ -70,6 +73,7 @@ private:
void setBreakpointsEnabled(const QModelIndexList &list, bool enabled); void setBreakpointsEnabled(const QModelIndexList &list, bool enabled);
void setBreakpointsFullPath(const QModelIndexList &list, bool fullpath); void setBreakpointsFullPath(const QModelIndexList &list, bool fullpath);
DebuggerManager *m_manager;
bool m_alwaysResizeColumnsToContents; bool m_alwaysResizeColumnsToContents;
}; };
......
...@@ -279,6 +279,22 @@ DebuggerSettings *DebuggerSettings::instance() ...@@ -279,6 +279,22 @@ DebuggerSettings *DebuggerSettings::instance()
item->setSettingsKey(debugModeGroup, QLatin1String("UsePreciseBreakpoints")); item->setSettingsKey(debugModeGroup, QLatin1String("UsePreciseBreakpoints"));
instance->insertItem(UsePreciseBreakpoints, item); instance->insertItem(UsePreciseBreakpoints, item);
item = new SavedAction(instance);
item->setText(tr("Break on \"throw\""));
item->setCheckable(true);
item->setDefaultValue(false);
item->setValue(false);
item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnThrow"));
instance->insertItem(BreakOnThrow, item);
item = new SavedAction(instance);
item->setText(tr("Break on \"catch\""));
item->setCheckable(true);
item->setDefaultValue(false);
item->setValue(false);
item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnCatch"));
instance->insertItem(BreakOnCatch, item);
// //
// Settings // Settings
// //
......
...@@ -130,7 +130,9 @@ enum DebuggerActionCode ...@@ -130,7 +130,9 @@ enum DebuggerActionCode
SelectedPluginBreakpoints, SelectedPluginBreakpoints,
NoPluginBreakpoints, NoPluginBreakpoints,
SelectedPluginBreakpointsPattern, SelectedPluginBreakpointsPattern,
UsePreciseBreakpoints UsePreciseBreakpoints,
BreakOnThrow,
BreakOnCatch
}; };
// singleton access // singleton access
......
...@@ -120,6 +120,7 @@ enum DebuggerCapabilities ...@@ -120,6 +120,7 @@ enum DebuggerCapabilities
JumpToLineCapability = 0x40, JumpToLineCapability = 0x40,
ReloadModuleCapability = 0x80, ReloadModuleCapability = 0x80,
ReloadModuleSymbolsCapability = 0x100, ReloadModuleSymbolsCapability = 0x100,
BreakOnThrowAndCatchCapability = 0x200,
}; };
enum LogChannel enum LogChannel
......
...@@ -351,7 +351,7 @@ void DebuggerManager::init() ...@@ -351,7 +351,7 @@ void DebuggerManager::init()
d->m_statusLabel = new QLabel; d->m_statusLabel = new QLabel;
d->m_statusLabel->setMinimumSize(QSize(30, 10)); d->m_statusLabel->setMinimumSize(QSize(30, 10));
d->m_breakWindow = new BreakWindow; d->m_breakWindow = new BreakWindow(this);
d->m_modulesWindow = new ModulesWindow(this); d->m_modulesWindow = new ModulesWindow(this);
d->m_outputWindow = new DebuggerOutputWindow; d->m_outputWindow = new DebuggerOutputWindow;
d->m_registerWindow = new RegisterWindow(this); d->m_registerWindow = new RegisterWindow(this);
......
...@@ -368,6 +368,8 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent) ...@@ -368,6 +368,8 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent)
m_group.insert(theDebuggerAction(LogTimeStamps), 0); m_group.insert(theDebuggerAction(LogTimeStamps), 0);
m_group.insert(theDebuggerAction(VerboseLog), 0); m_group.insert(theDebuggerAction(VerboseLog), 0);
m_group.insert(theDebuggerAction(UsePreciseBreakpoints), 0); m_group.insert(theDebuggerAction(UsePreciseBreakpoints), 0);
m_group.insert(theDebuggerAction(BreakOnThrow), 0);
m_group.insert(theDebuggerAction(BreakOnCatch), 0);
#ifdef USE_REVERSE_DEBUGGING #ifdef USE_REVERSE_DEBUGGING
m_ui.checkBoxEnableReverseDebugging->hide(); m_ui.checkBoxEnableReverseDebugging->hide();
......
...@@ -1708,7 +1708,7 @@ unsigned GdbEngine::debuggerCapabilities() const ...@@ -1708,7 +1708,7 @@ unsigned GdbEngine::debuggerCapabilities() const
| AutoDerefPointersCapability | DisassemblerCapability | AutoDerefPointersCapability | DisassemblerCapability
| RegisterCapability | ShowMemoryCapability | RegisterCapability | ShowMemoryCapability
| JumpToLineCapability | ReloadModuleCapability | JumpToLineCapability | ReloadModuleCapability
| ReloadModuleSymbolsCapability; | ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability;
} }
void GdbEngine::continueInferiorInternal() void GdbEngine::continueInferiorInternal()
......
...@@ -169,7 +169,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response) ...@@ -169,7 +169,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
&& bp->fileName != bp->bpFileName) && bp->fileName != bp->bpFileName)
bp->markerFileName = bp->fileName; bp->markerFileName = bp->fileName;
} else { } else {
QTC_ASSERT(false, qDebug() << child.toString()); QTC_ASSERT(false, qDebug() << child.toString() << bpNumber);
//bp->bpNumber = "<unavailable>"; //bp->bpNumber = "<unavailable>";
} }
} }
......
...@@ -33,9 +33,11 @@ ...@@ -33,9 +33,11 @@
#include <QtGui/QTreeView> #include <QtGui/QTreeView>
namespace Debugger { namespace Debugger {
class DebuggerManager; class DebuggerManager;
namespace Internal { namespace Internal {
class RegisterWindow : public QTreeView class RegisterWindow : public QTreeView
{ {
Q_OBJECT Q_OBJECT
......
...@@ -230,6 +230,27 @@ void testQByteArray() ...@@ -230,6 +230,27 @@ void testQByteArray()
ba += 2; ba += 2;
} }
static void throwit1()
{
throw 14;
}
static void throwit()
{
throwit1();
}
int testCatchThrow()
{
int gotit = 0;
try {
throwit();
} catch (int what) {
gotit = what;
}
return gotit;
}
void testQDateTime() void testQDateTime()
{ {
QDateTime date; QDateTime date;
...@@ -1422,6 +1443,7 @@ int main(int argc, char *argv[]) ...@@ -1422,6 +1443,7 @@ int main(int argc, char *argv[])
testIO(); testIO();
testHidden(); testHidden();
testArray(); testArray();
testCatchThrow();
testQByteArray(); testQByteArray();
testStdDeque(); testStdDeque();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment