3687d62c873bd666bd67d750cee1aebe7d2c8296
[m6w6/libmemcached] / src / libmemcached / backtrace.cc
1 /*
2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
14 */
15
16 #include "mem_config.h"
17
18 #include "libmemcached/backtrace.hpp"
19
20 #include <cstdio>
21 #include <cstdlib>
22 #include <cstring>
23
24 #if HAVE_BACKTRACE
25
26 # include BACKTRACE_HEADER
27
28 # if HAVE_ABI____CXA_DEMANGLE
29 # include <cxxabi.h>
30 # define USE_DEMANGLE 1
31 # else
32 # define USE_DEMANGLE 0
33 # endif
34
35 # ifdef HAVE_DLFCN_H
36 # include <dlfcn.h>
37 # endif
38
39 const int MAX_DEPTH = 50;
40
41 void custom_backtrace(void) {
42 void *backtrace_buffer[MAX_DEPTH + 1];
43
44 int stack_frames = backtrace(backtrace_buffer, MAX_DEPTH);
45 if (stack_frames) {
46 char **symbollist = backtrace_symbols(backtrace_buffer, stack_frames);
47 if (symbollist) {
48 for (int x = 0; x < stack_frames; x++) {
49 bool was_demangled = false;
50
51 if (USE_DEMANGLE) {
52 # ifdef HAVE_DLFCN_H
53 Dl_info dlinfo;
54 if (dladdr(backtrace_buffer[x], &dlinfo)) {
55 char demangled_buffer[1024];
56 const char *called_in = "<unresolved>";
57 if (dlinfo.dli_sname) {
58 size_t demangled_size = sizeof(demangled_buffer);
59 int status;
60 char *demangled;
61 if ((demangled = abi::__cxa_demangle(dlinfo.dli_sname, demangled_buffer,
62 &demangled_size, &status))) {
63 called_in = demangled;
64 fprintf(stderr, "---> demangled: %s -> %s\n", demangled_buffer, demangled);
65 } else {
66 called_in = dlinfo.dli_sname;
67 }
68
69 was_demangled = true;
70 fprintf(stderr, "#%d %p in %s at %s\n", x, backtrace_buffer[x], called_in,
71 dlinfo.dli_fname);
72 }
73 }
74 # endif
75 }
76
77 if (was_demangled == false) {
78 fprintf(stderr, "?%d %p in %s\n", x, backtrace_buffer[x], symbollist[x]);
79 }
80 }
81
82 ::free(symbollist);
83 }
84 }
85 }
86
87 #else // HAVE_BACKTRACE
88
89 void custom_backtrace(void) {
90 fprintf(stderr, "Backtrace null function called\n");
91 }
92 #endif // HAVE_BACKTRACE