1 // Copyright 2005 - 2007 Google Inc.
2 // All rights reserved.
6 // Produce stack trace using libunwind
11 #define UNW_LOCAL_ONLY
12 #include <libunwind.h>
14 #include "glog/raw_logging.h"
15 #include "stacktrace.h"
17 _START_GOOGLE_NAMESPACE_
19 // Sometimes, we can try to get a stack trace from within a stack
20 // trace, because libunwind can call mmap (maybe indirectly via an
21 // internal mmap based memory allocator), and that mmap gets trapped
22 // and causes a stack-trace request. If were to try to honor that
23 // recursive request, we'd end up with infinite recursion or deadlock.
24 // Luckily, it's safe to gnore those subsequent traces. In such cases,
25 // we return 0 to indicate the situation.
26 static bool g_now_entering = false;
28 // If you change this function, also change GetStackFrames below.
29 int GetStackTrace(void** result, int max_depth, int skip_count) {
35 if (sync_val_compare_and_swap(&g_now_entering, false, true)) {
40 RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed");
41 skip_count++; // Do not include the "GetStackTrace" frame
43 while (n < max_depth) {
44 int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip);
52 ret = unw_step(&cursor);
57 g_now_entering = false;
61 _END_GOOGLE_NAMESPACE_