230
237
void GdbTest::testDisableBreakpoint()
239
//Description: We must stop only on the third breakpoint
241
int firstBreakLine=28;
242
int secondBreakLine=23;
243
int thirdBreakLine=24;
244
int fourthBreakLine=31;
232
246
TestDebugSession *session = new TestDebugSession;
234
248
TestLaunchConfiguration cfg;
236
250
KDevelop::Breakpoint *b;
238
//add disabled breakpoint before startProgram
239
b = breakpoints()->addCodeBreakpoint(debugeeFileName, 29);
240
b->setData(KDevelop::Breakpoint::EnableColumn, false);
242
b = breakpoints()->addCodeBreakpoint(debugeeFileName, 21);
243
session->startProgram(&cfg);
252
b = breakpoints()->addCodeBreakpoint(debugeeFileName, firstBreakLine);
253
b->setData(KDevelop::Breakpoint::EnableColumn, Qt::Unchecked);
256
//this is needed to emulate debug from GUI. If we are in edit mode, the debugSession doesn't exist.
257
KDevelop::ICore::self()->debugController()->breakpointModel()->blockSignals(true);
258
b = breakpoints()->addCodeBreakpoint(debugeeFileName, secondBreakLine);
259
b->setData(KDevelop::Breakpoint::EnableColumn, Qt::Unchecked);
260
//all disabled breakpoints were added
262
KDevelop::Breakpoint * thirdBreak = breakpoints()->addCodeBreakpoint(debugeeFileName, thirdBreakLine);
263
KDevelop::ICore::self()->debugController()->breakpointModel()->blockSignals(false);
266
session->startProgram(&cfg, m_iface);
244
267
WAIT_FOR_STATE(session, DebugSession::PausedState);
269
QCOMPARE(session->currentLine(), thirdBreak->line());
246
271
//disable existing breakpoint
247
b->setData(KDevelop::Breakpoint::EnableColumn, false);
272
thirdBreak->setData(KDevelop::Breakpoint::EnableColumn, Qt::Unchecked);
249
274
//add another disabled breakpoint
250
b = breakpoints()->addCodeBreakpoint(debugeeFileName, 31);
275
b = breakpoints()->addCodeBreakpoint(debugeeFileName, fourthBreakLine);
251
276
QTest::qWait(300);
252
b->setData(KDevelop::Breakpoint::EnableColumn, false);
277
b->setData(KDevelop::Breakpoint::EnableColumn, Qt::Unchecked);
254
279
QTest::qWait(300);
256
281
WAIT_FOR_STATE(session, DebugSession::EndedState);
260
284
void GdbTest::testChangeLocationBreakpoint()
713
737
stackModel->fetchMoreFrames();
714
738
QTest::qWait(200);
715
739
QCOMPARE(stackModel->fetchFramesCalled, 3);
716
QCOMPARE(stackModel->rowCount(tIdx), 61);
740
QCOMPARE(stackModel->rowCount(tIdx), 121);
717
741
COMPARE_DATA(tIdx.child(40, 0), "40");
718
742
COMPARE_DATA(tIdx.child(41, 0), "41");
719
743
COMPARE_DATA(tIdx.child(42, 0), "42");
720
COMPARE_DATA(tIdx.child(60, 0), "60");
744
COMPARE_DATA(tIdx.child(119, 0), "119");
745
COMPARE_DATA(tIdx.child(120, 0), "120");
722
747
stackModel->fetchMoreFrames();
723
748
QTest::qWait(200);
724
749
QCOMPARE(stackModel->fetchFramesCalled, 4);
725
QCOMPARE(stackModel->rowCount(tIdx), 81);
727
stackModel->fetchMoreFrames();
729
QCOMPARE(stackModel->fetchFramesCalled, 5);
730
QCOMPARE(stackModel->rowCount(tIdx), 101);
731
COMPARE_DATA(tIdx.child(100, 0), "100");
732
COMPARE_DATA(tIdx.child(100, 1), "main");
733
COMPARE_DATA(tIdx.child(100, 2), fileName+":30");
750
QCOMPARE(stackModel->rowCount(tIdx), 301);
751
COMPARE_DATA(tIdx.child(120, 0), "120");
752
COMPARE_DATA(tIdx.child(121, 0), "121");
753
COMPARE_DATA(tIdx.child(122, 0), "122");
754
COMPARE_DATA(tIdx.child(300, 0), "300");
755
COMPARE_DATA(tIdx.child(300, 1), "main");
756
COMPARE_DATA(tIdx.child(300, 2), fileName+":30");
735
758
stackModel->fetchMoreFrames(); //nothing to fetch, we are at the end
736
759
QTest::qWait(200);
737
QCOMPARE(stackModel->fetchFramesCalled, 5);
738
QCOMPARE(stackModel->rowCount(tIdx), 101);
760
QCOMPARE(stackModel->fetchFramesCalled, 4);
761
QCOMPARE(stackModel->rowCount(tIdx), 301);
741
764
WAIT_FOR_STATE(session, DebugSession::EndedState);
1098
1132
TestLaunchConfiguration cfg;
1100
1134
breakpoints()->addCodeBreakpoint(debugeeFileName, 38);
1101
QVERIFY(session->startProgram(&cfg));
1135
QVERIFY(session->startProgram(&cfg, m_iface));
1102
1136
WAIT_FOR_STATE(session, DebugSession::PausedState);
1104
1138
session = new TestDebugSession;
1105
1139
session->variableController()->setAutoUpdate(KDevelop::IVariableController::UpdateLocals);
1107
1141
breakpoints()->addCodeBreakpoint(debugeeFileName, 38);
1108
QVERIFY(session->startProgram(&cfg));
1142
QVERIFY(session->startProgram(&cfg, m_iface));
1109
1143
WAIT_FOR_STATE(session, DebugSession::PausedState);
1111
1145
session->run();
1299
1333
TestLaunchConfiguration cfg;
1301
1335
breakpoints()->addCodeBreakpoint(KUrl("debugee.cpp"), 31);
1302
QVERIFY(session->startProgram(&cfg));
1336
breakpoints()->addCodeBreakpoint(KUrl("debugee.cpp"), 21);
1337
QVERIFY(session->startProgram(&cfg, m_iface));
1304
1339
//inject here, so it behaves similar like a command from .gdbinit
1305
1340
session->addCommandToFront(new GDBCommand(GDBMI::NonMI, "break debugee.cpp:32"));
1341
session->addCommandToFront(new GDBCommand(GDBMI::NonMI, "break foo"));
1307
1343
WAIT_FOR_STATE(session, DebugSession::PausedState);
1309
1345
session->stepInto();
1310
1346
WAIT_FOR_STATE(session, DebugSession::PausedState);
1311
1347
QTest::qWait(1000); //wait for breakpoints update
1312
QCOMPARE(breakpoints()->breakpoints().count(), 1);
1313
QCOMPARE(breakpoints()->rowCount(), 1+1);
1348
QCOMPARE(breakpoints()->breakpoints().count(), 2);
1315
1350
KDevelop::Breakpoint *b = breakpoints()->breakpoint(0);
1317
1352
QCOMPARE(b->line(), 31); //we start with 0, gdb with 1
1318
1353
QCOMPARE(b->url().url(), QString("debugee.cpp"));
1355
b = breakpoints()->breakpoint(1);
1357
QCOMPARE(b->line(), 21);
1358
QCOMPARE(b->url().url(), QString("debugee.cpp"));
1321
1361
void GdbTest::testRunGdbScript()
1540
1595
breakpoints()->addCodeBreakpoint(findSourceFile("debugeeexception.cpp"), 29);
1542
session->startProgram(&cfg);
1597
session->startProgram(&cfg, m_iface);
1543
1598
WAIT_FOR_STATE(session, DebugSession::PausedState);
1544
1599
QTest::qWait(1000);
1545
1600
TestFrameStackModel* fsModel = session->frameStackModel();
1546
1601
QCOMPARE(fsModel->currentFrame(), 0);
1547
1602
QCOMPARE(session->line(), 29);
1549
QModelIndex i = variableCollection()->index(1, 0);
1550
COMPARE_DATA(i, "Locals");
1551
qDebug() << variableCollection()->index(0, 1, i);
1552
qDebug() << variableCollection()->index(1, 1, i);
1553
QCOMPARE(variableCollection()->rowCount(i), 2);
1555
1604
session->addCommand(new GDBCommand(GDBMI::NonMI, "catch throw"));
1556
1605
session->run();
1557
1606
WAIT_FOR_STATE(session, DebugSession::PausedState);
1558
1607
QTest::qWait(1000);
1559
QCOMPARE(fsModel->currentFrame(), 1); //first frame skiped because somewhere inside stdlib
1560
QCOMPARE(session->line(), 22);
1562
qDebug() << variableCollection()->index(0, 1, i);
1563
qDebug() << variableCollection()->index(1, 1, i);
1564
QCOMPARE(variableCollection()->rowCount(i), 1);
1565
COMPARE_DATA(variableCollection()->index(0, 0, i), "i");
1566
COMPARE_DATA(variableCollection()->index(0, 1, i), "20");
1609
// TODO: Fix API in FrameStackModel? At least introduce FrameStackModel::frames(int)
1610
typedef KDevelop::IFrameStackModel::FrameItem FrameItem;
1611
QVector<FrameItem> frames;
1612
const QModelIndex thread1Index = fsModel->index(0, 0);
1613
for (int i = 0; i < fsModel->rowCount(thread1Index); ++i) {
1614
FrameItem frame = fsModel->frame(fsModel->index(i, 0, thread1Index));
1616
qDebug() << frame.file << frame.line;
1619
QVERIFY(frames.size() >= 2);
1620
// frame 0 is somewhere inside libstdc++
1621
QCOMPARE(frames[1].file, KUrl(findSourceFile("debugeeexception.cpp")));
1622
QCOMPARE(frames[1].line, 22);
1568
1624
session->run();
1569
1625
WAIT_FOR_STATE(session, DebugSession::EndedState);
1628
//TODO: figure out why do we need this test? And do we need it at all??
1573
1629
void GdbTest::testThreadAndFrameInfo()
1575
1631
TestDebugSession *session = new TestDebugSession;
1576
1632
TestLaunchConfiguration cfg(findExecutable("debugeethreads"));
1577
1633
QString fileName = findSourceFile("debugeethreads.cpp");
1635
breakpoints()->addCodeBreakpoint(fileName, 38);
1636
QVERIFY(session->startProgram(&cfg, m_iface));
1637
WAIT_FOR_STATE(session, DebugSession::PausedState);
1578
1640
QSignalSpy outputSpy(session, SIGNAL(gdbUserCommandStdout(QString)));
1580
breakpoints()->addCodeBreakpoint(fileName, 38);
1581
QVERIFY(session->startProgram(&cfg));
1582
session->frameStackModel()->fetchThreads();
1642
session->addCommand(
1643
new UserCommand(GDBMI::ThreadInfo,""));
1583
1644
session->addCommand(new UserCommand(GDBMI::StackListLocals, QLatin1String("0")));
1584
WAIT_FOR_STATE(session, DebugSession::PausedState);
1585
1645
QTest::qWait(1000);
1587
QVERIFY(outputSpy.count() == 2);
1646
QCOMPARE(outputSpy.count(), 2);
1588
1647
QVERIFY(outputSpy.last().at(0).toString().contains(QLatin1String("--thread 1")));
1590
1649
session->run();
1682
1741
WAIT_FOR_STATE(session, DebugSession::EndedState);
1744
void GdbTest::testMultipleBreakpoint()
1746
TestDebugSession *session = new TestDebugSession;
1748
//there'll be about 3-4 breakpoints, but we treat it like one.
1749
TestLaunchConfiguration c(findExecutable("debugeemultiplebreakpoint"));
1750
KDevelop::Breakpoint *b = breakpoints()->addCodeBreakpoint("debugeemultiplebreakpoint.cpp:52");
1751
session->startProgram(&c, m_iface);
1752
WAIT_FOR_STATE(session, DebugSession::PausedState);
1753
QCOMPARE(breakpoints()->breakpoints().count(), 1);
1755
b->setData(KDevelop::Breakpoint::EnableColumn, Qt::Unchecked);
1757
WAIT_FOR_STATE(session, DebugSession::EndedState);
1760
void GdbTest::testRegularExpressionBreakpoint()
1762
TestDebugSession *session = new TestDebugSession;
1764
TestLaunchConfiguration c(findExecutable("debugeemultilocbreakpoint"));
1765
breakpoints()->addCodeBreakpoint("main");
1766
session->startProgram(&c, m_iface);
1767
WAIT_FOR_STATE(session, DebugSession::PausedState);
1768
session->addCommand(new GDBCommand(GDBMI::NonMI, "rbreak .*aPl.*B"));
1771
WAIT_FOR_STATE(session, DebugSession::PausedState);
1772
QCOMPARE(breakpoints()->breakpoints().count(), 3);
1774
session->addCommand(new GDBCommand(GDBMI::BreakDelete, ""));
1776
WAIT_FOR_STATE(session, DebugSession::EndedState);
1779
void GdbTest::testChangeBreakpointWhileRunning() {
1781
TestDebugSession *session = new TestDebugSession;
1783
TestLaunchConfiguration c(findExecutable("debugeeslow"));
1784
KDevelop::Breakpoint* b = breakpoints()->addCodeBreakpoint("debugeeslow.cpp:25");
1785
session->startProgram(&c, m_iface);
1787
WAIT_FOR_STATE(session, DebugSession::PausedState);
1788
QVERIFY(session->currentLine() >= 24 && session->currentLine() <= 26 );
1790
WAIT_FOR_STATE(session, DebugSession::ActiveState);
1791
b->setData(KDevelop::Breakpoint::EnableColumn, Qt::Unchecked);
1794
WAIT_FOR_STATE(session, DebugSession::ActiveState);
1796
b->setData(KDevelop::Breakpoint::EnableColumn, Qt::Checked);
1798
WAIT_FOR_STATE(session, DebugSession::PausedState);
1799
b->setData(KDevelop::Breakpoint::EnableColumn, Qt::Unchecked);
1802
WAIT_FOR_STATE(session, DebugSession::EndedState);
1805
void GdbTest::testDebugInExternalTerminal()
1807
TestLaunchConfiguration cfg;
1809
foreach (const QString & console, QStringList() << "konsole" << "xterm" << "xfce4-terminal" << "gnome-terminal") {
1811
TestDebugSession* session = 0;
1812
if (KStandardDirs::findExe(console).isEmpty()) {
1816
session = new TestDebugSession();
1818
cfg.config().writeEntry("External Terminal"/*ExecutePlugin::terminalEntry*/, console);
1819
cfg.config().writeEntry("Use External Terminal"/*ExecutePlugin::useTerminalEntry*/, true);
1821
KDevelop::Breakpoint* b = breakpoints()->addCodeBreakpoint(debugeeFileName, 28);
1823
session->startProgram(&cfg, m_iface);
1824
WAIT_FOR_STATE(session, DebugSession::PausedState);
1825
QCOMPARE(session->breakpointController()->breakpointState(b), KDevelop::Breakpoint::CleanState);
1826
session->stepInto();
1827
WAIT_FOR_STATE(session, DebugSession::PausedState);
1829
WAIT_FOR_STATE(session, DebugSession::EndedState);
1685
1833
void GdbTest::waitForState(GDBDebugger::DebugSession *session, DebugSession::DebuggerState state,
1686
1834
const char *file, int line, bool expectFail)