more cleanup
[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 # ifdef HAVE_ABI____CXA_DEMANGLE
29 # include <cxxabi.h>
30 # endif
31
32 # ifdef HAVE_DLFCN_H
33 # include <dlfcn.h>
34 # endif
35
36 const int MAX_DEPTH = 50;
37
38 void custom_backtrace(void) {
39 void *backtrace_buffer[MAX_DEPTH + 1];
40
41 int stack_frames = backtrace(backtrace_buffer, MAX_DEPTH);
42 if (stack_frames) {
43 char **symbollist = backtrace_symbols(backtrace_buffer, stack_frames);
44 if (symbollist) {
45 for (int x = 0; x < stack_frames; x++) {
46 bool was_demangled = false;
47
48 # ifdef HAVE_ABI____CXA_DEMANGLE
49 # ifdef HAVE_DLFCN_H
50 Dl_info dlinfo;
51 if (dladdr(backtrace_buffer[x], &dlinfo)) {
52 char demangled_buffer[1024];
53 const char *called_in = "<unresolved>";
54 if (dlinfo.dli_sname) {
55 size_t demangled_size = sizeof(demangled_buffer);
56 int status;
57 char *demangled;
58 if ((demangled = abi::__cxa_demangle(dlinfo.dli_sname, demangled_buffer,
59 &demangled_size, &status))) {
60 called_in = demangled;
61 fprintf(stderr, "---> demangled: %s -> %s\n", demangled_buffer, demangled);
62 } else {
63 called_in = dlinfo.dli_sname;
64 }
65
66 was_demangled = true;
67 fprintf(stderr, "#%d %p in %s at %s\n", x, backtrace_buffer[x], called_in,
68 dlinfo.dli_fname);
69 }
70 }
71 # endif
72 # endif
73
74 if (was_demangled == false) {
75 fprintf(stderr, "?%d %p in %s\n", x, backtrace_buffer[x], symbollist[x]);
76 }
77 }
78
79 ::free(symbollist);
80 }
81 }
82 }
83
84 #else // HAVE_BACKTRACE
85
86 void custom_backtrace(void) {
87 fprintf(stderr, "Backtrace null function called\n");
88 }
89 #endif // HAVE_BACKTRACE