[ovs-dev] [PATCH] backtrace: add LOG_BACKTRACE()

Andy Zhou azhou at nicira.com
Fri Mar 14 01:17:14 UTC 2014


LOG_BACKTRACE() logs the back trace into the log file. I find it
to be helpful when debugging unit tests. "backtrace.h" documents
the usage. It is not being called directly in the code, but rather as
a handy tool available when needed.

Signed-off-by: Andy Zhou <azhou at nicira.com>
---
 lib/backtrace.c |   30 ++++++++++++++++++++++++++++++
 lib/backtrace.h |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/lib/backtrace.c b/lib/backtrace.c
index 861a109..c606357 100644
--- a/lib/backtrace.c
+++ b/lib/backtrace.c
@@ -17,6 +17,10 @@
 #include <config.h>
 
 #include "backtrace.h"
+#include "inttypes.h"
+#include "vlog.h"
+
+VLOG_DEFINE_THIS_MODULE(backtrace);
 
 #ifdef HAVE_BACKTRACE
 #include <execinfo.h>
@@ -31,6 +35,7 @@ backtrace_capture(struct backtrace *b)
         b->frames[i] = (uintptr_t) frames[i];
     }
 }
+
 #else
 void
 backtrace_capture(struct backtrace *backtrace)
@@ -38,3 +43,28 @@ backtrace_capture(struct backtrace *backtrace)
     backtrace->n_frames = 0;
 }
 #endif
+
+char *
+backtrace_format(const struct backtrace *b, struct ds *ds)
+{
+    if (b->n_frames) {
+        int i;
+
+        ds_put_cstr(ds, " (backtrace:");
+        for (i = 0; i < b->n_frames; i++) {
+            ds_put_format(ds, " 0x%08"PRIxPTR, b->frames[i]);
+        }
+        ds_put_cstr(ds, ")");
+    }
+
+    return ds_cstr(ds);
+}
+
+void
+log_backtrace(const char *file, int line, const struct backtrace *b)
+{
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    ds_put_format(&ds, "%s:%d:", file, line);
+    VLOG_ERR("%s", backtrace_format(b, &ds));
+    ds_destroy(&ds);
+}
diff --git a/lib/backtrace.h b/lib/backtrace.h
index cee0602..e9dc5ec 100644
--- a/lib/backtrace.h
+++ b/lib/backtrace.h
@@ -18,6 +18,50 @@
 #define BACKTRACE_H 1
 
 #include <stdint.h>
+#include "dynamic-string.h"
+
+/* LOG_BACKTRACE() will save the backtrace of a running program
+ * into the log at the DEBUG level.
+ *
+ * To use it, insert the following code to where backtrace is
+ * desired:
+ *       #include "backtrace.h"
+ *
+ *       LOG_BACKTRACE();
+ *
+ * A typical log will look like the following. The hex numbers listed after
+ * "backtrace" are the addresses of the backtrace.
+ *
+ * 2014-03-13T23:18:11.979Z|00002|backtrace(revalidator_6)|ERR|lib/dpif-netdev.c:1312: (backtrace: 0x00521f57 0x00460365 0x00463ea4 0x0046470b 0x0043b32d 0x0043bac3 0x0043bae2 0x0043943b 0x004c22b3 0x2b5b3ac94e9a 0x2b5b3b4a33fd)
+ *
+ * The following bash command can be used to  view backtrace in
+ * a more readable form.
+ * addr2line -p -e vswitchd/ovs-vswitchd <cut-and-paste back traces>
+ *
+ * An typical run and output will look like:
+ * addr2line -p -e vswitchd/ovs-vswitchd  0x00521f57 0x00460365 0x00463ea4
+ * 0x0046470b 0x0043b32d 0x0043bac3 0x0043bae2 0x0043943b 0x004c22b3
+ * 0x2b5b3ac94e9a 0x2b5b3b4a33fd
+ *
+ * openvswitch/lib/backtrace.c:33
+ * openvswitch/lib/dpif-netdev.c:1312
+ * openvswitch/lib/dpif.c:937
+ * openvswitch/lib/dpif.c:1258
+ * openvswitch/ofproto/ofproto-dpif-upcall.c:1440
+ * openvswitch/ofproto/ofproto-dpif-upcall.c:1595
+ * openvswitch/ofproto/ofproto-dpif-upcall.c:160
+ * openvswitch/ofproto/ofproto-dpif-upcall.c:717
+ * openvswitch/lib/ovs-thread.c:268
+ * ??:0
+ * ??:0
+ */
+
+#define LOG_BACKTRACE() \
+    { \
+        struct backtrace b; \
+        backtrace_capture(&b); \
+        log_backtrace(__FILE__, __LINE__, &b); \
+    } \
 
 #define BACKTRACE_MAX_FRAMES 31
 
@@ -27,5 +71,7 @@ struct backtrace {
 };
 
 void backtrace_capture(struct backtrace *);
+char *backtrace_format(const struct backtrace *b, struct ds *ds);
+void log_backtrace(const char *file, const int line, const struct backtrace *);
 
 #endif /* backtrace.h */
-- 
1.7.9.5




More information about the dev mailing list