#include "gdbmi.h" #include "json.h" #include #include #include #include //#include using namespace Debugger; using namespace Debugger::Internal; static const char gdbmi1[] = "[frame={level=\"0\",addr=\"0x00000000004061ca\"," "func=\"main\",file=\"test1.cpp\"," "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]"; static const char gdbmi2[] = "[frame={level=\"0\",addr=\"0x00002ac058675840\"," "func=\"QApplication\",file=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\"," "fullname=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\",line=\"592\"}," "frame={level=\"1\",addr=\"0x00000000004061e0\",func=\"main\",file=\"test1.cpp\"," "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]"; static const char gdbmi3[] = "[stack={frame={level=\"0\",addr=\"0x00000000004061ca\"," "func=\"main\",file=\"test1.cpp\"," "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}}]"; static const char gdbmi4[] = "&\"source /home/apoenitz/dev/ide/main/bin/gdb/qt4macros\\n\"" "4^done\n"; static const char gdbmi5[] = "[reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"1\"," "frame={addr=\"0x0000000000405738\",func=\"main\"," "args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\"0x7fff1ac78f28\"}]," "file=\"test1.cpp\",fullname=\"/home/apoenitz/work/test1/test1.cpp\"," "line=\"209\"}]"; static const char gdbmi8[] = "[data={locals={{name=\"a\"},{name=\"w\"}}}]"; static const char gdbmi9[] = "[data={locals=[name=\"baz\",name=\"urgs\",name=\"purgs\"]}]"; static const char gdbmi10[] = "[name=\"urgs\",numchild=\"1\",type=\"Urgs\"]"; static const char gdbmi11[] = "[{name=\"size\",value=\"1\",type=\"size_t\",readonly=\"true\"}," "{name=\"0\",value=\"one\",type=\"QByteArray\"}]"; static const char gdbmi12[] = "[{iname=\"local.hallo\",value=\"\\\"\\\\\\00382\\t\\377\",type=\"QByteArray\"," "numchild=\"0\"}]"; static const char jsont1[] = "{\"Size\":100564,\"UID\":0,\"GID\":0,\"Permissions\":33261," "\"ATime\":1242370878000,\"MTime\":1239154689000}"; class tst_Debugger : public QObject { Q_OBJECT public: tst_Debugger() {} void testMi(const char* input) { QCOMPARE('\n' + QString::fromLatin1(GdbMi(input).toString(false)), '\n' + QString(input)); } void testJson(const char* input) { QCOMPARE('\n' + QString::fromLatin1(JsonValue(input).toString(false)), '\n' + QString(input)); } private slots: void mi1() { testMi(gdbmi1); } void mi2() { testMi(gdbmi2); } void mi3() { testMi(gdbmi3); } //void mi4() { testMi(gdbmi4); } void mi5() { testMi(gdbmi5); } void mi8() { testMi(gdbmi8); } void mi9() { testMi(gdbmi9); } void mi10() { testMi(gdbmi10); } void mi11() { testMi(gdbmi11); } //void mi12() { testMi(gdbmi12); } void json1() { testJson(jsont1); } void infoBreak(); public slots: void runQtc(); public slots: void readStandardOutput(); void readStandardError(); private: QProcess m_proc; // the Qt Creator process }; static QByteArray stripped(QByteArray ba) { for (int i = ba.size(); --i >= 0; ) { if (ba.at(i) == '\n' || ba.at(i) == ' ') ba.chop(1); else break; } return ba; } void tst_Debugger::infoBreak() { // This tests the regular expression used in GdbEngine::extractDataFromInfoBreak // to discover breakpoints in constructors. // Copied from gdbengine.cpp: QRegExp re("MULTIPLE.*(0x[0-9a-f]+) in (.*)\\s+at (.*):([\\d]+)([^\\d]|$)"); re.setMinimal(true); QCOMPARE(re.indexIn( "2 breakpoint keep y 0x0040168e\n" "2.1 y 0x0040168e " "in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7\n" "2.2 y 0x00401792 " "in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7\n"), 33); QCOMPARE(re.cap(1), QString("0x0040168e")); QCOMPARE(re.cap(2).trimmed(), QString("MainWindow::MainWindow(QWidget*)")); QCOMPARE(re.cap(3), QString("mainwindow.cpp")); QCOMPARE(re.cap(4), QString("7")); QCOMPARE(re.indexIn( "Num Type Disp Enb Address What" "4 breakpoint keep y 0x00000000004066ad" "4.1 y 0x00000000004066ad in CTorTester" " at /main/tests/manual/gdbdebugger/simple/app.cpp:124"), 88); QCOMPARE(re.cap(1), QString("0x00000000004066ad")); QCOMPARE(re.cap(2).trimmed(), QString("CTorTester")); QCOMPARE(re.cap(3), QString("/main/tests/manual/gdbdebugger/simple/app.cpp")); QCOMPARE(re.cap(4), QString("124")); } void tst_Debugger::readStandardOutput() { qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput()); } void tst_Debugger::readStandardError() { qDebug() << "qtcreator-err: " << stripped(m_proc.readAllStandardError()); } void tst_Debugger::runQtc() { QString test = QFileInfo(qApp->arguments().at(0)).absoluteFilePath(); QString qtc = QFileInfo(test).absolutePath() + "/../../../bin/qtcreator.bin"; qtc = QFileInfo(qtc).absoluteFilePath(); QStringList env = QProcess::systemEnvironment(); env.append("QTC_DEBUGGER_TEST=" + test); m_proc.setEnvironment(env); connect(&m_proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput())); connect(&m_proc, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError())); m_proc.start(qtc); m_proc.waitForStarted(); QCOMPARE(m_proc.state(), QProcess::Running); m_proc.waitForFinished(); QCOMPARE(m_proc.state(), QProcess::NotRunning); } void runDebuggee() { qDebug() << "RUNNING DEBUGGEE"; } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QStringList args = app.arguments(); if (args.size() == 2 && args.at(1) == "--run-debuggee") { runDebuggee(); app.exec(); return 0; } tst_Debugger test; return QTest::qExec(&test, argc, argv); } #include "main.moc"