summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-05-25 19:34:47 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-05-25 19:34:47 -0500
commitc12a32aec01bb5f6956ecfcd086997322eb7ec68 (patch)
tree73339f13893838325653d34fa5b4f58055612049
parent013eed4fdc2587ac7752777484de3c8bd9c170e1 (diff)
downloadtdebase-c12a32aec01bb5f6956ecfcd086997322eb7ec68.tar.gz
tdebase-c12a32aec01bb5f6956ecfcd086997322eb7ec68.zip
Properly obtain threading debug information in TDE crash handler
Fix potential TDE crash handler lockup uncer certain circumstances Enhance crashtest program with three threads
-rw-r--r--drkonqi/backtrace.cpp67
-rw-r--r--drkonqi/crashtest.cpp30
-rw-r--r--drkonqi/crashtest.h40
-rw-r--r--drkonqi/debuggers/gdbrc3
-rw-r--r--drkonqi/krashconf.cpp1
-rw-r--r--drkonqi/krashconf.h2
6 files changed, 132 insertions, 11 deletions
diff --git a/drkonqi/backtrace.cpp b/drkonqi/backtrace.cpp
index 2b349d288..61ae8130c 100644
--- a/drkonqi/backtrace.cpp
+++ b/drkonqi/backtrace.cpp
@@ -176,8 +176,22 @@ void BackTrace::slotProcessExited(TDEProcess *proc)
bool BackTrace::usefulBacktrace()
{
// remove crap
- if( !m_krashconf->removeFromBacktraceRegExp().isEmpty())
+ if( !m_krashconf->removeFromBacktraceRegExp().isEmpty()) {
m_strBt.replace(TQRegExp( m_krashconf->removeFromBacktraceRegExp()), TQString());
+ }
+
+ // fix threading info output
+ if( !m_krashconf->threadRegExp().isEmpty()) {
+ int pos = -1;
+ TQRegExp threadRegExpression( m_krashconf->threadRegExp());
+ do {
+ threadRegExpression.search(m_strBt);
+ pos = threadRegExpression.pos();
+ if (pos > -1) {
+ m_strBt.insert(threadRegExpression.pos()+1, "==== ");
+ }
+ } while (pos > -1);
+ }
if( m_krashconf->disableChecks())
return true;
@@ -204,20 +218,32 @@ void BackTrace::processBacktrace()
{
if( !m_krashconf->kcrashRegExp().isEmpty()) {
TQRegExp kcrashregexp( m_krashconf->kcrashRegExp());
- int pos = -1;
- while ((pos = kcrashregexp.search( m_strBt )) >= 0) {
- pos = kcrashregexp.search( m_strBt );
+ kcrashregexp.setMinimal(true);
+ int pos = 0;
+ int prevpos = 0;
+ while ((pos = kcrashregexp.search( m_strBt, pos )) >= 0) {
+ if (prevpos == pos) {
+ // Avoid infinite loop
+ // Shouldn't ever get here, but given that this is a crash handler, better safe than sorry!
+ break;
+ }
+ prevpos = pos;
if( pos >= 0 ) {
int len = kcrashregexp.matchedLength();
int nextinfochunkpos = m_strBt.find("====", pos);
if (nextinfochunkpos >= 0) {
// Trying to delete too much!
- int chunkpos = pos;
- TQString limitedstrBt = m_strBt.mid(pos, nextinfochunkpos - pos);
- pos = kcrashregexp.search( limitedstrBt ) + chunkpos;
- len = kcrashregexp.matchedLength();
+ int limitedlen = nextinfochunkpos - pos;
+ TQString limitedstrBt = m_strBt.mid(pos, limitedlen);
+ int limitedpos = kcrashregexp.search( limitedstrBt );
+ if (limitedpos >= 0) {
+ len = kcrashregexp.matchedLength();
+ }
+ else {
+ len = 0;
+ }
}
- if (pos >= 0) {
+ if ((pos >= 0) && (len > 0)) {
if( m_strBt[ pos ] == '\n' ) {
++pos;
--len;
@@ -226,6 +252,17 @@ void BackTrace::processBacktrace()
m_strBt.insert( pos, TQString::fromLatin1( "[TDECrash handler]\n" ));
}
}
+ if (pos < 0) {
+ // Avoid infinite loop
+ // Shouldn't ever get here, but given that this is a crash handler, better safe than sorry!
+ break;
+ }
+ pos++;
+ if ((uint)pos >= m_strBt.length()) {
+ // Avoid infinite loop
+ // Shouldn't ever get here, but given that this is a crash handler, better safe than sorry!
+ break;
+ }
}
}
if( !m_krashconf->kcrashRegExpSingle().isEmpty()) {
@@ -242,7 +279,7 @@ void BackTrace::processBacktrace()
}
// Append potentially important hardware information
- m_strBt.append("\n\n==== (tdehwlib) hardware information ====\n");
+ m_strBt.append("\n==== (tdehwlib) hardware information ====\n");
TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
TDEGenericHardwareList hwlist = hwdevices->listAllPhysicalDevices();
TDEGenericDevice *hwdevice;
@@ -259,4 +296,14 @@ void BackTrace::processBacktrace()
m_strBt.append("\n");
}
}
+
+ {
+ // Clean up hard to read debug blocks
+ TQRegExp kcrashregexp( "[^\n]\n==== ");
+ kcrashregexp.setMinimal(true);
+ int pos = 0;
+ while ((pos = kcrashregexp.search( m_strBt, pos )) >= 0) {
+ m_strBt.insert(pos+1, "\n");
+ }
+ }
}
diff --git a/drkonqi/crashtest.cpp b/drkonqi/crashtest.cpp
index 2583c1273..ff38fae24 100644
--- a/drkonqi/crashtest.cpp
+++ b/drkonqi/crashtest.cpp
@@ -1,11 +1,28 @@
// Let's crash.
+#include <unistd.h>
#include <tdeapplication.h>
#include <tdeaboutdata.h>
#include <tdecmdlineargs.h>
+#include <tqthread.h>
+#include <tqtimer.h>
#include <kdebug.h>
#include <stdio.h>
#include <assert.h>
+#include "crashtest.h"
+
+void WorkerObject::run()
+{
+ while (1) {
+ sleep(10000);
+ }
+}
+
+#define SET_UP_WORKER(x, y) \
+ WorkerObject x; \
+ x.moveToThread(&y); \
+ TQTimer::singleShot(0, &x, SLOT(run()));
+
static TDECmdLineOptions options[] =
{
{ "+crash|malloc|div0|assert", "Type of crash.", 0 },
@@ -74,6 +91,17 @@ int main(int argc, char *argv[])
TDEAboutData::License_GPL,
"(c) 2000-2002 David Faure, Waldo Bastian");
+ // Start 3 threads
+ TQEventLoopThread workerthread0;
+ TQEventLoopThread workerthread1;
+ TQEventLoopThread workerthread2;
+ SET_UP_WORKER(worker0, workerthread0)
+ SET_UP_WORKER(worker1, workerthread1)
+ SET_UP_WORKER(worker2, workerthread2)
+ workerthread0.start();
+ workerthread1.start();
+ workerthread2.start();
+
TDECmdLineArgs::init(argc, argv, &aboutData);
TDECmdLineArgs::addCmdLineOptions(options);
@@ -90,3 +118,5 @@ int main(int argc, char *argv[])
level1(crashtype);
return app.exec();
}
+
+#include "crashtest.moc" \ No newline at end of file
diff --git a/drkonqi/crashtest.h b/drkonqi/crashtest.h
new file mode 100644
index 000000000..482c410ca
--- /dev/null
+++ b/drkonqi/crashtest.h
@@ -0,0 +1,40 @@
+/*****************************************************************
+ *
+ * Copyright (C) 2013 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************/
+
+#ifndef CRASHTEST_H
+#define CRASHTEST_H
+
+#include <tqobject.h>
+
+class WorkerObject : public TQObject
+{
+ Q_OBJECT
+
+ public slots:
+ void run();
+};
+
+#endif // CRASHTEST_H \ No newline at end of file
diff --git a/drkonqi/debuggers/gdbrc b/drkonqi/debuggers/gdbrc
index e414d86a0..1aa1f8c36 100644
--- a/drkonqi/debuggers/gdbrc
+++ b/drkonqi/debuggers/gdbrc
@@ -158,10 +158,11 @@ Comment[zu]=Umcoshi wamaphutha osekelwe umbhalo osuka kwi-GNU kwikhonsoli
Exec=konsole -e gdb -nw %execname %pid
ExecBatch=gdb -nw -n -batch -x %tempfile %execname %pid
TryExec=gdb
-BacktraceCommand=echo \\n\necho ==== (gdb) bt ====\\n\nbt\necho \\n\\n\necho ==== (gdb) bt full ====\\n\nbt full\necho\\n\\n\necho ==== (gdb) thread apply all bt ====\\n\nthread apply all bt
+BacktraceCommand=echo \\n\necho ==== (gdb) bt ====\\n\nbt\necho \\n\\n\necho ==== (gdb) bt full ====\\n\nbt full\necho\\n\\n\necho ==== (gdb) info thread ====\\n\ninfo thread\necho\\n\\n\necho ==== (gdb) thread apply all bt ====\\n\nthread apply all bt
RemoveFromBacktraceRegExp=\(no debugging symbols found\)\.\.\.\\n?
InvalidStackFrameRegExp=\\n#[0-9]+\\s+0x[0-9A-Fa-f]+ \w* \?\?
FrameRegExp=\\n#[0-9]+\\s+0x[0-9A-Fa-f]+
NeededInValidBacktraceRegExp=\\n#5
TDECrashRegExp=\\n#0[ ]*0x[0123456789abcdefABCDEF]+.*<signal handler called>[ ]*\\n
TDECrashRegExpSingle=\\n0x[0123456789abcdefABCDEF][^\\n]*\\n
+ThreadRegExp=\\nThread [0123456789]
diff --git a/drkonqi/krashconf.cpp b/drkonqi/krashconf.cpp
index 6a96c4aab..84bbfee8c 100644
--- a/drkonqi/krashconf.cpp
+++ b/drkonqi/krashconf.cpp
@@ -112,6 +112,7 @@ void KrashConfig :: readConfig()
m_neededInValidBacktraceRegExp = debuggers.readEntry("NeededInValidBacktraceRegExp");
m_kcrashRegExp = debuggers.readEntry("TDECrashRegExp");
m_kcrashRegExpSingle = debuggers.readEntry("TDECrashRegExpSingle");
+ m_threadRegExp = debuggers.readEntry("ThreadRegExp");
TDEConfig preset(TQString::fromLatin1("presets/%1rc").arg(configname),
true, false, "appdata");
diff --git a/drkonqi/krashconf.h b/drkonqi/krashconf.h
index 2e4c414ee..074cfce6f 100644
--- a/drkonqi/krashconf.h
+++ b/drkonqi/krashconf.h
@@ -67,6 +67,7 @@ public:
TQString neededInValidBacktraceRegExp() const { return m_neededInValidBacktraceRegExp; }
TQString kcrashRegExp() const { return m_kcrashRegExp; }
TQString kcrashRegExpSingle() const { return m_kcrashRegExpSingle; }
+ TQString threadRegExp() const { return m_threadRegExp; }
bool showBacktrace() const { return m_showbacktrace; };
bool showDebugger() const { return m_showdebugger && !m_debugger.isNull(); };
bool showBugReport() const { return m_showbugreport; };
@@ -110,6 +111,7 @@ private:
TQString m_neededInValidBacktraceRegExp;
TQString m_kcrashRegExp;
TQString m_kcrashRegExpSingle;
+ TQString m_threadRegExp;
};
#endif