[RDP] A Debugging and error tracing tool.

Dan Mills dmills at exponent.myzen.co.uk
Tue Nov 20 15:20:02 EST 2007


Hi all, 
While trying to track down a particularly aggravating bug, I wrote this
patch that may be of use to others.

Basically it adds a macro TRACE(x) which works very like a C style
assert except that it dumps the call stack at the time it fails to
stdout (and if you hook up a signal to a log writer, also to the log
file for whatever you are running), AND THEN CONTINUES EXECUTION.
This can be very handy when trying to work out how the flow of control
got somewhere.


I am considering adding this permanently in rddebug.[cpp,h], comments?

------------------------------
Index: lib/Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/Makefile.am,v
retrieving revision 1.105
diff -B -b -U3 -r1.105 Makefile.am
--- lib/Makefile.am	28 Oct 2007 20:13:32 -0000	1.105
+++ lib/Makefile.am	20 Nov 2007 20:04:27 -0000
@@ -206,7 +206,7 @@
                           moc_rdslider.cpp moc_rdsocket.cpp\
                           moc_rdstereometer.cpp moc_rdtimeengine.cpp\
                           moc_rdtransportbutton.cpp moc_rddb.cpp\
-                          moc_rdlivewire.cpp
+                          moc_rdlivewire.cpp moc_rddebug.cpp
 
 librd_la_LDFLAGS = -release $(VERSION)
 
Index: lib/rddebug.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rddebug.cpp,v
retrieving revision 1.3
diff -B -b -U3 -r1.3 rddebug.cpp
--- lib/rddebug.cpp	14 Feb 2007 21:48:41 -0000	1.3
+++ lib/rddebug.cpp	20 Nov 2007 20:04:27 -0000
@@ -19,9 +19,9 @@
 //   License along with this program; if not, write to the Free Software
 //   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 //
-
+#include <execinfo.h>
+#include <stdlib.h>
 #include <stdio.h>
-
 #include <rddebug.h>
 
 
@@ -30,3 +30,64 @@
   printf("RDTimePoint - %s: %s\n",(const char *)label,
 	 (const char *)QTime::currentTime().toString("hh:mm:ss.zzz"));
 }
+
+RDTrace::RDTrace()
+{
+  f = popen ("c++filt","w");
+  po = true;
+  if (!f) {
+    f = stdout;
+    po = false;
+  }
+  connect (this,SIGNAL(logText(QString)),this,SLOT(write(QString))); 
+}
+
+RDTrace::~RDTrace()
+{
+  if (!po){
+    pclose (f);
+  }
+}
+
+void RDTrace::write (QString s)
+{
+  fprintf (f,"%s\n",s.ascii());
+  fflush (f);
+}
+
+void RDTrace::trace (QString label, bool test, bool abort_run)
+/* Obtain a backtrace and print it to stdout. */
+{
+  void *array[200];
+  size_t size;
+  char **strings;
+  size_t i;
+  if (!test){
+    size = backtrace (array, 200);
+    strings = backtrace_symbols (array, size);
+    if (label.ascii()){
+      emit logText (label);
+    }
+    emit logText (QString().sprintf ("Backtrace obtained %zd stack frames.", size));
+    for (i = 0; i < size; i++){ 
+      emit logText (QString (strings[i]));
+    }
+    free (strings); 
+    if (abort_run) { 
+      abort ();
+    }
+  }
+}  
+
+RDTrace * tracer()
+{
+  static RDTrace *rdt = NULL;
+  if (rdt == NULL){
+    rdt = new RDTrace;
+  }
+  return rdt;
+}
+
+
+
+
Index: lib/rddebug.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rddebug.h,v
retrieving revision 1.3
diff -B -b -U3 -r1.3 rddebug.h
--- lib/rddebug.h	14 Feb 2007 21:48:41 -0000	1.3
+++ lib/rddebug.h	20 Nov 2007 20:04:27 -0000
@@ -21,7 +21,7 @@
 //
 
 #include <qdatetime.h>
-
+#include <qobject.h>
 
 #ifndef RDDEBUG_H
 #define RDDEBUG_H
@@ -29,6 +29,30 @@
 
 void RDTimePoint(QString label);
 
-
+class RDTrace : public QObject
+{
+  Q_OBJECT
+ signals:
+  void logText(QString);
+ public:
+  void trace (QString label = QString(), bool test = false, bool abort_run = false);
+  RDTrace();
+  ~RDTrace();
+ private:
+  bool po;
+  FILE *f;
+  friend RDTrace * tracer();
+  private slots:
+  void write (QString s);
+
+};
+
+RDTrace * tracer();
+
+#ifndef NDEBUG
+#define TRACE(x) tracer()->trace(QString ("Trace assertion failed : ")+QString(__FILE__ ":")+QString (__PRETTY_FUNCTION__)+QString().sprintf (" (%d)",__LINE__) ,(x))
+#else
+#define TRACE(x) 
+#endif 
 #endif  // RDDEBUG_H




More information about the Rivendell-prog mailing list