about summary refs log tree commit diff
path: root/src/stacktrace_x86_64-inl.h
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2020-05-27T00·26+0100
committerVincent Ambo <tazjin@google.com>2020-05-27T00·26+0100
commitafe04691aca3f669f517adaeb5bd4a87a481fb4a (patch)
tree60ae6c91a3959b2f6486256e26ff126e598d1e5d /src/stacktrace_x86_64-inl.h
Squashed 'third_party/glog/' content from commit 9ef754a3023
git-subtree-dir: third_party/glog
git-subtree-split: 9ef754a3023e6fd10f20fe53dfca96dd898182e3
Diffstat (limited to 'src/stacktrace_x86_64-inl.h')
-rw-r--r--src/stacktrace_x86_64-inl.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/stacktrace_x86_64-inl.h b/src/stacktrace_x86_64-inl.h
new file mode 100644
index 000000000000..f7d1dca85bc1
--- /dev/null
+++ b/src/stacktrace_x86_64-inl.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2005 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * 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.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "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 COPYRIGHT
+// OWNER OR CONTRIBUTORS 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.
+//
+// Author: Arun Sharma
+//
+// Produce stack trace using libgcc
+
+extern "C" {
+#include <stdlib.h> // for NULL
+#include <unwind.h> // ABI defined unwinder
+}
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+typedef struct {
+  void **result;
+  int max_depth;
+  int skip_count;
+  int count;
+} trace_arg_t;
+
+
+// Workaround for the malloc() in _Unwind_Backtrace() issue.
+static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) {
+  return _URC_NO_REASON;
+}
+
+
+// This code is not considered ready to run until
+// static initializers run so that we are guaranteed
+// that any malloc-related initialization is done.
+static bool ready_to_run = false;
+class StackTraceInit {
+ public:
+   StackTraceInit() {
+     // Extra call to force initialization
+     _Unwind_Backtrace(nop_backtrace, NULL);
+     ready_to_run = true;
+   }
+};
+
+static StackTraceInit module_initializer;  // Force initialization
+
+static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
+  trace_arg_t *targ = (trace_arg_t *) opq;
+
+  if (targ->skip_count > 0) {
+    targ->skip_count--;
+  } else {
+    targ->result[targ->count++] = (void *) _Unwind_GetIP(uc);
+  }
+
+  if (targ->count == targ->max_depth)
+    return _URC_END_OF_STACK;
+
+  return _URC_NO_REASON;
+}
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+  if (!ready_to_run)
+    return 0;
+
+  trace_arg_t targ;
+
+  skip_count += 1;         // Do not include the "GetStackTrace" frame
+
+  targ.result = result;
+  targ.max_depth = max_depth;
+  targ.skip_count = skip_count;
+  targ.count = 0;
+
+  _Unwind_Backtrace(GetOneFrame, &targ);
+
+  return targ.count;
+}
+
+_END_GOOGLE_NAMESPACE_