Setting tag sliver-openvswitch-2.2.90-1
[sliver-openvswitch.git] / lib / backtrace.c
index 1c0dfd6..9b7c52b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 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"
+#include "backtrace.h"
 #include "vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(backtrace);
@@ -41,82 +35,44 @@ backtrace_capture(struct backtrace *b)
         b->frames[i] = (uintptr_t) frames[i];
     }
 }
-#elif __GNUC__
-static uintptr_t
-get_max_stack(void)
-{
-    static const char file_name[] = "/proc/self/maps";
-    char line[1024];
-    int line_number;
-    FILE *f;
-
-    f = fopen(file_name, "r");
-    if (f == NULL) {
-        VLOG_WARN("opening %s failed: %s", file_name, strerror(errno));
-        return -1;
-    }
-
-    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;
-        }
-    }
-    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;
 }
+#endif
 
-static uintptr_t
-stack_low(void)
+static char *
+backtrace_format(const struct backtrace *b, struct ds *ds)
 {
-    uintptr_t low = (uintptr_t) &low;
-    return low;
-}
+    if (b->n_frames) {
+        int i;
 
-static bool
-in_stack(void *p)
-{
-    uintptr_t address = (uintptr_t) p;
-    return address >= stack_low() && address < stack_high();
+        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;
-}
-#else  /* !HAVE_BACKTRACE && !__GNUC__ */
-void
-backtrace_capture(struct backtrace *backtrace)
-{
-    backtrace->n_frames = 0;
+
+    ds_put_cstr(&ds, where);
+    VLOG_ERR("%s", backtrace_format(&b, &ds));
+
+    ds_destroy(&ds);
 }
-#endif