diff options
author | hjk <hjk@qt.io> | 2023-04-03 18:46:43 +0200 |
---|---|---|
committer | hjk <hjk@qt.io> | 2023-04-05 06:26:11 +0000 |
commit | de546ff3ecbf9929d4bf19b50243c5b94e328616 (patch) | |
tree | cc758349d42d2b0d9fcb624b047dacf1a234690d /src/plugins/debugger/gdb/gdbengine.cpp | |
parent | 808f5c0e1d2070acc13dc90fba3cc440dd065b7d (diff) | |
download | qt-creator-de546ff3ecbf9929d4bf19b50243c5b94e328616.tar.gz |
Debugger: Support piping dumpers into gdb
This allows using dumpers available on the host being used from
remotely running gdb. No lldb/cdb yet.
Task-number: QTCREATORBUG-29000
Task-number: QTCREATORBUG-16246
Change-Id: Ib1a40a8c0284dcf41e8800d70ca3e632c699b2fa
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Diffstat (limited to 'src/plugins/debugger/gdb/gdbengine.cpp')
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 23ebc1df94..532c9ef069 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -765,7 +765,8 @@ void GdbEngine::runCommand(const DebuggerCommand &command) if (cmd.flags & ConsoleCommand) cmd.function = "-interpreter-exec console \"" + cmd.function + '"'; cmd.function = QString::number(token) + cmd.function; - showMessage(cmd.function, LogInput); + + showMessage(cmd.function.left(100), LogInput); if (m_scheduledTestResponses.contains(token)) { // Fake response for test cases. @@ -3969,15 +3970,59 @@ void GdbEngine::handleGdbStarted() //if (terminal()->isUsable()) // runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice())}); - runCommand({"python sys.path.insert(1, '" + rp.dumperPath.path() + "')"}); + const FilePath dumperPath = ICore::resourcePath("debugger"); + if (rp.debugger.command.executable().needsDevice()) { + // Gdb itself running remotely. + const FilePath loadOrderFile = dumperPath / "loadorder.txt"; + const expected_str<QByteArray> toLoad = loadOrderFile.fileContents(); + if (!toLoad) { + AsynchronousMessageBox::critical( + Tr::tr("Cannot Find Debugger Initialization Script"), + Tr::tr("Cannot read %1: %2").arg(loadOrderFile.toUserOutput(), toLoad.error())); + notifyEngineSetupFailed(); + return; + } + + runCommand({"python import sys, types"}); + QStringList moduleList; + for (const QByteArray &rawModuleName : toLoad->split('\n')) { + const QString module = QString::fromUtf8(rawModuleName).trimmed(); + if (module.startsWith('#')) + continue; + + const FilePath codeFile = dumperPath / (module + ".py"); + const expected_str<QByteArray> code = codeFile.fileContents(); + if (!code) { + qDebug() << Tr::tr("Cannot read %1: %2").arg(codeFile.toUserOutput(), code.error()); + continue; + } + + showMessage("Reading " + codeFile.toUserOutput(), LogInput); + runCommand({QString("python module = types.ModuleType('%1')").arg(module)}); + runCommand({QString("python code = bytes.fromhex('%1').decode('utf-8')") + .arg(QString::fromUtf8(code->toHex()))}); + runCommand({QString("python exec(code, module.__dict__)")}); + runCommand({QString("python sys.modules['%1'] = module").arg(module)}); + runCommand({QString("python import %1").arg(module)}); + + if (module.endsWith("types")) + moduleList.append('"' + module + '"'); + } - // This is useful (only) in custom gdb builds that did not run 'make install' - const FilePath uninstalledData = rp.debugger.command.executable().parentDir() - / "data-directory/python"; - if (uninstalledData.exists()) - runCommand({"python sys.path.append('" + uninstalledData.path() + "')"}); + runCommand({"python from gdbbridge import *"}); + runCommand(QString("python theDumper.dumpermodules = [%1]").arg(moduleList.join(','))); - runCommand({"python from gdbbridge import *"}); + } else { + // Gdb on local host + // This is useful (only) in custom gdb builds that did not run 'make install' + const FilePath uninstalledData = rp.debugger.command.executable().parentDir() + / "data-directory/python"; + if (uninstalledData.exists()) + runCommand({"python sys.path.append('" + uninstalledData.path() + "')"}); + + runCommand({"python sys.path.insert(1, '" + dumperPath.path() + "')"}); + runCommand({"python from gdbbridge import *"}); + } const QString path = debuggerSettings()->extraDumperFile.value(); if (!path.isEmpty() && QFileInfo(path).isReadable()) { |