]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/port/stack_trace.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
6 #include "port/stack_trace.h"
8 #if defined(ROCKSDB_LITE) || !(defined(ROCKSDB_BACKTRACE) || defined(OS_MACOSX)) || \
9 defined(CYGWIN) || defined(OS_FREEBSD) || defined(OS_SOLARIS)
15 void InstallStackTraceHandler() {}
16 void PrintStack(int first_frames_to_skip
) {}
18 } // namespace rocksdb
36 const char* GetExecutableName() {
37 static char name
[1024];
40 snprintf(link
, sizeof(link
), "/proc/%d/exe", getpid());
41 auto read
= readlink(link
, name
, sizeof(name
) - 1);
50 void PrintStackTraceLine(const char* symbol
, void* frame
) {
51 static const char* executable
= GetExecutableName();
53 fprintf(stderr
, "%s ", symbol
);
56 // out source to addr2line, for the address translation
57 const int kLineMax
= 256;
59 snprintf(cmd
, kLineMax
, "addr2line %p -e %s -f -C 2>&1", frame
, executable
);
60 auto f
= popen(cmd
, "r");
63 while (fgets(line
, sizeof(line
), f
)) {
64 line
[strlen(line
) - 1] = 0; // remove newline
65 fprintf(stderr
, "%s\t", line
);
70 fprintf(stderr
, " %p", frame
);
73 fprintf(stderr
, "\n");
75 #elif defined(OS_MACOSX)
77 void PrintStackTraceLine(const char* symbol
, void* frame
) {
78 static int pid
= getpid();
79 // out source to atos, for the address translation
80 const int kLineMax
= 256;
82 snprintf(cmd
, kLineMax
, "xcrun atos %p -p %d 2>&1", frame
, pid
);
83 auto f
= popen(cmd
, "r");
86 while (fgets(line
, sizeof(line
), f
)) {
87 line
[strlen(line
) - 1] = 0; // remove newline
88 fprintf(stderr
, "%s\t", line
);
92 fprintf(stderr
, "%s ", symbol
);
95 fprintf(stderr
, "\n");
102 void PrintStack(int first_frames_to_skip
) {
103 const int kMaxFrames
= 100;
104 void* frames
[kMaxFrames
];
106 auto num_frames
= backtrace(frames
, kMaxFrames
);
107 auto symbols
= backtrace_symbols(frames
, num_frames
);
109 for (int i
= first_frames_to_skip
; i
< num_frames
; ++i
) {
110 fprintf(stderr
, "#%-2d ", i
- first_frames_to_skip
);
111 PrintStackTraceLine((symbols
!= nullptr) ? symbols
[i
] : nullptr, frames
[i
]);
116 static void StackTraceHandler(int sig
) {
117 // reset to default handler
118 signal(sig
, SIG_DFL
);
119 fprintf(stderr
, "Received signal %d (%s)\n", sig
, strsignal(sig
));
120 // skip the top three signal handler related frames
122 // re-signal to default handler (so we still get core dump if needed...)
126 void InstallStackTraceHandler() {
127 // just use the plain old signal as it's simple and sufficient
129 signal(SIGILL
, StackTraceHandler
);
130 signal(SIGSEGV
, StackTraceHandler
);
131 signal(SIGBUS
, StackTraceHandler
);
132 signal(SIGABRT
, StackTraceHandler
);
136 } // namespace rocksdb