Commit cfa43ed2 authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧

Read the new message string after rather than before

Summary: This way if we're linking against an old KF5, we still generate a backtrace

Reviewers: #frameworks, broulik, sitter

Reviewed By: broulik, sitter

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D28129
parent 607094bd
......@@ -92,9 +92,15 @@ bool BacktraceGenerator::start()
m_temp->write("\n", 1);
m_temp->flush();
auto preamble = new QTemporaryFile(m_proc);
preamble->open();
preamble->write(m_debugger.preambleCommands().toUtf8());
preamble->write("\n", 1);
preamble->flush();
// start the debugger
QString str = m_debugger.command();
Debugger::expandString(str, Debugger::ExpansionUsageShell, m_temp->fileName());
Debugger::expandString(str, Debugger::ExpansionUsageShell, m_temp->fileName(), preamble->fileName());
*m_proc << KShell::splitArgs(str);
m_proc->setOutputChannelMode(KProcess::OnlyStdoutChannel);
......@@ -102,7 +108,7 @@ bool BacktraceGenerator::start()
// check if the debugger should take its input from a file we'll generate,
// and take the appropriate steps if so
QString stdinFile = m_debugger.backendValueOfParameter(QStringLiteral("ExecInputFile"));
Debugger::expandString(stdinFile, Debugger::ExpansionUsageShell, m_temp->fileName());
Debugger::expandString(stdinFile, Debugger::ExpansionUsageShell, m_temp->fileName(), preamble->fileName());
if (!stdinFile.isEmpty() && QFile::exists(stdinFile)) {
m_proc->setStandardInputFile(stdinFile);
}
......@@ -182,7 +188,7 @@ void BacktraceGenerator::slotProcessExited(int exitCode, QProcess::ExitStatus ex
QString tmp(QStringLiteral("Application: %progname (%execname), signal: %signame\n"));
Debugger::expandString(tmp);
m_parsedBacktrace = tmp + m_parser->parsedBacktrace();
m_parsedBacktrace = tmp + m_parser->informationLines() + m_parser->parsedBacktrace();
m_state = Loaded;
#ifdef BACKTRACE_PARSER_DEBUG
......
......@@ -74,5 +74,6 @@ TryExec=gdb
Backends=KCrash
[KCrash]
Exec=gdb -nw -n -batch -x %tempfile -p %pid %execpath
BatchCommands=set width 200\nprint "Content of s_kcrashErrorMessage:"\nprint s_kcrashErrorMessage\nthread\nthread apply all bt
Exec=gdb -nw -n -batch -x %preamblefile -x %tempfile -p %pid %execpath
PreambleCommands=set width 200\nprintf "KCRASH_INFO_MESSAGE: Content of s_kcrashErrorMessage: %s\\n", s_kcrashErrorMessage
BatchCommands=thread\nthread apply all bt
......@@ -39,4 +39,4 @@ Backends=KCrash
[KCrash]
Exec=lldb -p %pid
ExecInputFile=%tempfile
BatchCommands=settings set term-width 200\nprint "Content of s_kcrashErrorMessage:"\nprint s_kcrashErrorMessage\nthread info\nbt all\ndetach
BatchCommands=settings set term-width 200\nthread info\nbt all
......@@ -103,6 +103,12 @@ QString Debugger::backtraceBatchCommands() const
? m_config->group(m_backend).readPathEntry("BatchCommands", QString())
: QString();
}
QString Debugger::preambleCommands() const
{
return (isValid() && m_config->hasGroup(m_backend))
? m_config->group(m_backend).readPathEntry("PreambleCommands", QString())
: QString();
}
bool Debugger::runInTerminal() const
{
......@@ -119,7 +125,7 @@ QString Debugger::backendValueOfParameter(const QString &key) const
}
//static
void Debugger::expandString(QString & str, ExpandStringUsage usage, const QString & tempFile)
void Debugger::expandString(QString & str, ExpandStringUsage usage, const QString & tempFile, const QString & preambleFile)
{
const CrashedApplication *appInfo = DrKonqi::crashedApplication();
const QHash<QString, QString> map = {
......@@ -130,6 +136,7 @@ void Debugger::expandString(QString & str, ExpandStringUsage usage, const QStrin
{ QLatin1String("signame"), appInfo->signalName() },
{ QLatin1String("pid"), QString::number(appInfo->pid()) },
{ QLatin1String("tempfile"), tempFile },
{ QLatin1String("preamblefile"), preambleFile },
{ QLatin1String("thread"), QString::number(appInfo->thread()) },
};
......
......@@ -67,6 +67,11 @@ public:
*/
QString backtraceBatchCommands() const;
/** Returns the commands that should be given to the debugger before
* getting the backtrace
*/
QString preambleCommands() const;
/** If this is an external debugger, it returns whether it should be run in a terminal or not */
bool runInTerminal() const;
......@@ -79,7 +84,7 @@ public:
};
static void expandString(QString & str, ExpandStringUsage usage = ExpansionUsagePlainText,
const QString & tempFile = QString());
const QString & tempFile = QString(), const QString & preambleFile = QString());
private:
static QList<Debugger> availableDebuggers(const QString &path, const QString & backend);
......
......@@ -35,7 +35,8 @@ public:
ThreadStart, //line indicates the start of a thread's stack.
SignalHandlerStart, //line indicates the signal handler start
//(contains "<signal handler called>")
StackFrame //line is a normal stack frame
StackFrame, //line is a normal stack frame
Info //< additional information on the bt
};
enum LineRating {
......
......@@ -405,4 +405,11 @@ void BacktraceParser::calculateRatingData()
qCDebug(DRKONQI_PARSER_LOG) << "Have seen stack base:" << haveSeenStackBase << "Lines counted:" << counter;
}
QString BacktraceParser::informationLines() const
{
Q_D(const BacktraceParser);
QString ret = d->m_infoLines.join(QLatin1Char('\n'));
if (!ret.endsWith(QLatin1Char('\n')))
ret += QLatin1Char('\n');
return ret;
}
......@@ -67,6 +67,8 @@ public:
/*! Returns a list of libraries/executables that are missing debug symbols. */
virtual QSet<QString> librariesWithMissingDebugSymbols() const;
QString informationLines() const;
private Q_SLOTS:
void resetState();
......
......@@ -26,6 +26,7 @@ public:
BacktraceParserPrivate() : m_usefulness(BacktraceParser::InvalidUsefulness) {}
~BacktraceParserPrivate() {}
QStringList m_infoLines;
QList<BacktraceLine> m_linesList;
QList<BacktraceLine> m_linesToRate;
QStringList m_firstUsefulFunctions;
......
......@@ -24,8 +24,10 @@
//BEGIN BacktraceLineGdb
const QLatin1String BacktraceParserGdb::KCRASH_INFO_MESSAGE("KCRASH_INFO_MESSAGE: ");
BacktraceLineGdb::BacktraceLineGdb(const QString & lineStr)
: BacktraceLine()
: BacktraceLine()
{
d->m_line = lineStr;
d->m_functionName = QLatin1String("??");
......@@ -96,6 +98,12 @@ void BacktraceLineGdb::parse()
return;
}
if (d->m_line.contains(BacktraceParserGdb::KCRASH_INFO_MESSAGE)) {
qCDebug(DRKONQI_PARSER_LOG) << "info:" << d->m_line;
d->m_type = Info;
return;
}
regExp.setPattern(QStringLiteral(".*\\(no debugging symbols found\\).*|"
".*\\[Thread debugging using libthread_db enabled\\].*|"
".*\\[New .*|"
......@@ -203,6 +211,9 @@ void BacktraceParserGdb::parseLine(const QString & lineStr)
switch (line.type()) {
case BacktraceLine::Crap:
break; //we don't want crap in the backtrace ;)
case BacktraceLine::Info:
d->m_infoLines << line.toString().mid(KCRASH_INFO_MESSAGE.size());
break;
case BacktraceLine::ThreadStart:
d->m_linesList.append(line);
d->m_possibleKCrashStart = d->m_linesList.size();
......
......@@ -40,6 +40,7 @@ public:
QString parsedBacktrace() const override;
QList<BacktraceLine> parsedBacktraceLines() const override;
static const QLatin1String KCRASH_INFO_MESSAGE;
protected:
BacktraceParserPrivate *constructPrivate() const override;
......
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