lib/netdev-dpdk: increase ring name length for dpdkr ports
[cascardo/ovs.git] / lib / backtrace.c
index 80cae54..5cb2954 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 #include <config.h>
-#include "backtrace.h"
-#include <errno.h>
 #include <inttypes.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include "compiler.h"
 
-#define THIS_MODULE VLM_backtrace
-#include "vlog.h"
+#include "backtrace.h"
+#include "openvswitch/vlog.h"
 
-static uintptr_t OVS_UNUSED
-get_max_stack(void)
-{
-    static const char file_name[] = "/proc/self/maps";
-    char line[1024];
-    int line_number;
-    FILE *f;
+VLOG_DEFINE_THIS_MODULE(backtrace);
 
-    f = fopen(file_name, "r");
-    if (f == NULL) {
-        VLOG_WARN("opening %s failed: %s", file_name, strerror(errno));
-        return -1;
-    }
+#ifdef HAVE_BACKTRACE
+#include <execinfo.h>
+void
+backtrace_capture(struct backtrace *b)
+{
+    void *frames[BACKTRACE_MAX_FRAMES];
+    int i;
 
-    for (line_number = 1; fgets(line, sizeof line, f); line_number++) {
-        if (strstr(line, "[stack]")) {
-            uintptr_t end;
-            if (sscanf(line, "%*x-%"SCNxPTR, &end) != 1) {
-                VLOG_WARN("%s:%d: parse error", file_name, line_number);
-                continue;
-            }
-            fclose(f);
-            return end;
-        }
+    b->n_frames = backtrace(frames, BACKTRACE_MAX_FRAMES);
+    for (i = 0; i < b->n_frames; i++) {
+        b->frames[i] = (uintptr_t) frames[i];
     }
-    fclose(f);
-
-    VLOG_WARN("%s: no stack found", file_name);
-    return -1;
 }
 
-static uintptr_t
-stack_high(void)
+#else
+void
+backtrace_capture(struct backtrace *backtrace)
 {
-    static uintptr_t high;
-    if (!high) {
-        high = get_max_stack();
-    }
-    return high;
+    backtrace->n_frames = 0;
 }
-
-static uintptr_t
-stack_low(void)
-{
-#ifdef __i386__
-    uintptr_t low;
-    asm("movl %%esp,%0" : "=g" (low));
-    return low;
-#elif __x86_64__
-    uintptr_t low;
-    asm("movq %%rsp,%0" : "=g" (low));
-    return low;
-#else
-    /* This causes a warning in GCC that cannot be disabled, so use it only on
-     * non-x86. */
-    int dummy;
-    return (uintptr_t) &dummy;
 #endif
-}
 
-static bool
-in_stack(void *p)
+static char *
+backtrace_format(const struct backtrace *b, struct ds *ds)
 {
-    uintptr_t address = (uintptr_t) p;
-    return address >= stack_low() && address < stack_high();
+    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
-backtrace_capture(struct backtrace *backtrace)
+log_backtrace_at(const char *msg, const char *where)
 {
-    void **frame;
-    size_t n;
+    struct backtrace b;
+    struct ds ds = DS_EMPTY_INITIALIZER;
 
-    n = 0;
-    for (frame = __builtin_frame_address(1);
-         frame != NULL && in_stack(frame) && frame[0] != NULL
-             && n < BACKTRACE_MAX_FRAMES;
-         frame = frame[0])
-    {
-        backtrace->frames[n++] = (uintptr_t) frame[1];
+    backtrace_capture(&b);
+    if (msg) {
+        ds_put_format(&ds, "%s ", msg);
     }
-    backtrace->n_frames = n;
+
+    ds_put_cstr(&ds, where);
+    VLOG_ERR("%s", backtrace_format(&b, &ds));
+
+    ds_destroy(&ds);
 }