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):
#4.1 y 0x08056673 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"
#6 breakpoint keep y 0xb6cf18e5 <__cxa_throw+5>\n"
lines = catchCliOutput("info break")
lines.reverse()
......@@ -128,10 +129,15 @@ def listOfBreakpoints(d):
number = line[0:5]
pos0x = line.find(" 0x")
posin = line.find(" in ", pos0x)
poslt = line.find(" <", pos0x)
posat = line.find(" at ", posin)
poscol = line.find(":", posat)
if pos0x < posin and pos0x != -1:
bp.address.append(line[pos0x + 1 : posin])
if pos0x != -1:
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.
#if line.find("<PENDING>") >= 0:
# bp.address.append("<PENDING>")
......
......@@ -335,13 +335,15 @@ void BreakHandler::clear()
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) {
const BreakpointData *data = at(index);
// clear hit.
// Clear hit.
qDebug() << " TEST: " << data->toString();
if (data->bpNumber == needle.bpNumber)
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
if (fileNameMatch(data->fileName, needle.bpFileName)
&& data->lineNumber == needle.bpLineNumber)
......
......@@ -79,8 +79,8 @@ public:
//
///////////////////////////////////////////////////////////////////////
BreakWindow::BreakWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false)
BreakWindow::BreakWindow(DebuggerManager *manager)
: m_manager(manager), m_alwaysResizeColumnsToContents(false)
{
QAction *act = theDebuggerAction(UseAlternatingRowColors);
setWindowTitle(tr("Breakpoints"));
......@@ -143,6 +143,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
si = normalizeIndexes(si);
const int rowCount = itemModel->rowCount();
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
QAction *deleteAction = new QAction(tr("Delete breakpoint"), &menu);
deleteAction->setEnabled(si.size() > 0);
......@@ -190,12 +191,18 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
toggleEnabledAction->setEnabled(si.size() > 0);
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);
pathAction->setEnabled(si.size() > 0);
QAction *breakAtFunctionAction = new QAction(tr("Set Breakpoint at Function..."), this);
QAction *breakAtMainAction = new QAction(tr("Set Breakpoint at Function \"main\""), this);
QAction *breakAtFunctionAction =
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(editConditionAction);
......@@ -209,6 +216,10 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
menu.addSeparator();
menu.addAction(breakAtFunctionAction);
menu.addAction(breakAtMainAction);
if (engineCapabilities & BreakOnThrowAndCatchCapability) {
menu.addAction(breakAtThrowAction);
menu.addAction(breakAtCatchAction);
}
menu.addSeparator();
menu.addAction(theDebuggerAction(UseToolTipsInBreakpointsView));
menu.addAction(theDebuggerAction(UseAddressInBreakpointsView));
......@@ -246,6 +257,10 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
emit breakByFunctionRequested(dlg.functionName());
} else if (act == breakAtMainAction)
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)
......
......@@ -33,6 +33,9 @@
#include <QtGui/QTreeView>
namespace Debugger {
class DebuggerManager;
namespace Internal {
class BreakWindow : public QTreeView
......@@ -40,7 +43,7 @@ class BreakWindow : public QTreeView
Q_OBJECT
public:
BreakWindow(QWidget *parent = 0);
explicit BreakWindow(DebuggerManager *manager);
public slots:
void resizeColumnsToContents();
......@@ -70,6 +73,7 @@ private:
void setBreakpointsEnabled(const QModelIndexList &list, bool enabled);
void setBreakpointsFullPath(const QModelIndexList &list, bool fullpath);
DebuggerManager *m_manager;
bool m_alwaysResizeColumnsToContents;
};
......
......@@ -279,6 +279,22 @@ DebuggerSettings *DebuggerSettings::instance()
item->setSettingsKey(debugModeGroup, QLatin1String("UsePreciseBreakpoints"));
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
//
......
......@@ -130,7 +130,9 @@ enum DebuggerActionCode
SelectedPluginBreakpoints,
NoPluginBreakpoints,
SelectedPluginBreakpointsPattern,
UsePreciseBreakpoints
UsePreciseBreakpoints,
BreakOnThrow,
BreakOnCatch
};
// singleton access
......
......@@ -120,6 +120,7 @@ enum DebuggerCapabilities
JumpToLineCapability = 0x40,
ReloadModuleCapability = 0x80,
ReloadModuleSymbolsCapability = 0x100,
BreakOnThrowAndCatchCapability = 0x200,
};
enum LogChannel
......
......@@ -351,7 +351,7 @@ void DebuggerManager::init()
d->m_statusLabel = new QLabel;
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_outputWindow = new DebuggerOutputWindow;
d->m_registerWindow = new RegisterWindow(this);
......
......@@ -368,6 +368,8 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent)
m_group.insert(theDebuggerAction(LogTimeStamps), 0);
m_group.insert(theDebuggerAction(VerboseLog), 0);
m_group.insert(theDebuggerAction(UsePreciseBreakpoints), 0);
m_group.insert(theDebuggerAction(BreakOnThrow), 0);
m_group.insert(theDebuggerAction(BreakOnCatch), 0);
#ifdef USE_REVERSE_DEBUGGING
m_ui.checkBoxEnableReverseDebugging->hide();
......
......@@ -1708,7 +1708,7 @@ unsigned GdbEngine::debuggerCapabilities() const
| AutoDerefPointersCapability | DisassemblerCapability
| RegisterCapability | ShowMemoryCapability
| JumpToLineCapability | ReloadModuleCapability
| ReloadModuleSymbolsCapability;
| ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability;
}
void GdbEngine::continueInferiorInternal()
......
......@@ -169,7 +169,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
&& bp->fileName != bp->bpFileName)
bp->markerFileName = bp->fileName;
} else {
QTC_ASSERT(false, qDebug() << child.toString());
QTC_ASSERT(false, qDebug() << child.toString() << bpNumber);
//bp->bpNumber = "<unavailable>";
}
}
......
......@@ -33,9 +33,11 @@
#include <QtGui/QTreeView>
namespace Debugger {
class DebuggerManager;
namespace Internal {
class RegisterWindow : public QTreeView
{
Q_OBJECT
......
......@@ -230,6 +230,27 @@ void testQByteArray()
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()
{
QDateTime date;
......@@ -1422,6 +1443,7 @@ int main(int argc, char *argv[])
testIO();
testHidden();
testArray();
testCatchThrow();
testQByteArray();
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