| 334 | } |
| 335 | |
| 336 | void GdbTest::testRemoteDebug() |
| 337 | { |
| 338 | const QString gdbserverExecutable = QStandardPaths::findExecutable(QStringLiteral("gdbserver")); |
| 339 | if (gdbserverExecutable.isEmpty()) { |
| 340 | QSKIP("Skipping, gdbserver not available"); |
| 341 | } |
| 342 | |
| 343 | auto *session = new TestDebugSession; |
| 344 | |
| 345 | QFETCH(const QList<int>, linesToAddBreakpointsAt); |
| 346 | for (const auto line : linesToAddBreakpointsAt) { |
| 347 | addDebugeeBreakpoint(line); |
| 348 | } |
| 349 | |
| 350 | // In case the shell script QTemporaryFile object is alive during debugging: |
| 351 | // 1) the sh process started in DebugSession::execInferior() exits immediately with the code 126 |
| 352 | // (which means "A specified command_file could not be executed due to an [ENOEXEC] error"); |
| 353 | // 2) the GDB command `source path/to/runscript` fails with the following error message: |
| 354 | // "/path/to/runscript:2: Error in sourced command file: |
| 355 | // could not connect: Connection timed out."; |
| 356 | // 3) and the debug session is stuck in the starting state, so the test |
| 357 | // fails due to a timeout while waiting for the first paused state. |
| 358 | // These errors likely occur because the QTemporaryFile object always keeps |
| 359 | // the unique temporary file open internally (according to its documentation). |
| 360 | // Prevent the errors by destroying the QTemporaryFile object before starting debugging. |
| 361 | QString shellScriptFileName; |
| 362 | { |
| 363 | QTemporaryFile shellScript(QDir::currentPath()+"/shellscript"); |
| 364 | OPEN_WRITE_AND_CLOSE_TEMPORARY_FILE( |
| 365 | shellScript, |
| 366 | QLatin1String{"gdbserver localhost:2345 %1\n"}.arg(findExecutable("debuggee_debugee").toLocalFile())); |
| 367 | QVERIFY(shellScript.setPermissions(shellScript.permissions() | QFile::ExeUser)); |
| 368 | |
| 369 | shellScriptFileName = shellScript.fileName(); |
| 370 | shellScript.setAutoRemove(false); |
| 371 | } |
| 372 | QVERIFY(!shellScriptFileName.isEmpty()); |
| 373 | const QScopeGuard shellScriptGuard([&shellScriptFileName] { |
| 374 | QFile::remove(shellScriptFileName); |
| 375 | }); |
| 376 | |
| 377 | QTemporaryFile runScript(QDir::currentPath()+"/runscript"); |
| 378 | const auto runScriptContents = QLatin1String{R"(file %1 |
| 379 | target remote localhost:2345 |
| 380 | break debugee.cpp:30 |
| 381 | continue |
| 382 | )"} |
| 383 | .arg(findExecutable("debuggee_debugee").toLocalFile()); |
| 384 | OPEN_WRITE_AND_CLOSE_TEMPORARY_FILE(runScript, runScriptContents); |
| 385 | |
| 386 | TestLaunchConfiguration cfg; |
| 387 | KConfigGroup grp = cfg.config(); |
| 388 | grp.writeEntry(Config::RemoteGdbShellEntry, QUrl::fromLocalFile(shellScriptFileName)); |
| 389 | grp.writeEntry(Config::RemoteGdbRunEntry, QUrl::fromLocalFile(runScript.fileName())); |
| 390 | |
| 391 | START_DEBUGGING_E(session, cfg); |
| 392 | WAIT_FOR_STATE_AND_IDLE(session, DebugSession::PausedState); |
| 393 | QCOMPARE(currentMiLine(session), 30); |
nothing calls this directly
no test coverage detected