16
16
17
17
#if SUPPORTS_BACKTRACE
18
18
#include < cxxabi.h>
19
+ #ifdef C10_ANDROID
20
+ #include < dlfcn.h>
21
+ #include < unwind.h>
22
+ #else
19
23
#include < execinfo.h>
20
24
#endif
25
+ #endif
21
26
22
27
#ifdef FBCODE_CAFFE2
23
28
#include < common/process/StackTrace.h>
24
29
#endif
25
30
26
31
namespace c10 {
27
32
33
+ #if SUPPORTS_BACKTRACE && defined(C10_ANDROID)
34
+
35
+ struct AndroidBacktraceState {
36
+ std::vector<void *> buffer;
37
+ };
38
+
39
+ _Unwind_Reason_Code android_unwind_callback (
40
+ struct _Unwind_Context * context,
41
+ void * arg) {
42
+ AndroidBacktraceState* state = (AndroidBacktraceState*)arg;
43
+ uintptr_t pc = _Unwind_GetIP (context);
44
+ if (pc) {
45
+ state->buffer .emplace_back (reinterpret_cast <void *>(pc));
46
+ }
47
+ return _URC_NO_REASON;
48
+ }
49
+
50
+ void dump_stack (
51
+ std::ostream& os,
52
+ size_t frames_to_skip,
53
+ size_t maximum_number_of_frames) {
54
+ AndroidBacktraceState state;
55
+
56
+ _Unwind_Backtrace (android_unwind_callback, &state);
57
+
58
+ int idx = 0 ;
59
+ char * demangled = nullptr ;
60
+ size_t length = 0 ;
61
+
62
+ for (const void * addr : state.buffer ) {
63
+ const char * symbol = " " ;
64
+
65
+ Dl_info info;
66
+ if (dladdr (addr, &info) && info.dli_sname ) {
67
+ symbol = info.dli_sname ;
68
+ }
69
+
70
+ int status = 0 ;
71
+ demangled = __cxxabiv1::__cxa_demangle (
72
+ /* mangled_name*/ symbol,
73
+ /* output_buffer*/ demangled,
74
+ /* length*/ &length,
75
+ /* status*/ &status);
76
+
77
+ os << " frame #" << idx++ << " \t "
78
+ << ((demangled != NULL && status == 0 ) ? demangled : symbol) << " ["
79
+ << addr << " ]\t " << std::endl;
80
+ }
81
+ free (demangled);
82
+ }
83
+
84
+ #endif /* SUPPORTS_BACKTRACE && defined(C10_ANDROID) */
85
+
28
86
#if SUPPORTS_BACKTRACE
29
87
namespace {
30
88
@@ -42,6 +100,7 @@ struct FrameInformation {
42
100
std::string object_file;
43
101
};
44
102
103
+ #ifndef C10_ANDROID
45
104
bool is_python_frame (const FrameInformation& frame) {
46
105
return frame.object_file == " python" || frame.object_file == " python3" ||
47
106
(frame.object_file .find (" libpython" ) != std::string::npos);
@@ -113,6 +172,7 @@ c10::optional<FrameInformation> parse_frame_information(
113
172
frame.function_name = demangle (mangled_function_name.c_str ());
114
173
return frame;
115
174
}
175
+ #endif /* !defined(C10_ANDROID) */
116
176
} // anonymous namespace
117
177
#elif defined(_MSC_VER)
118
178
namespace {
@@ -178,7 +238,7 @@ std::string get_backtrace(
178
238
facebook::process::StackTrace st;
179
239
return st.toString ();
180
240
181
- #elif SUPPORTS_BACKTRACE
241
+ #elif SUPPORTS_BACKTRACE && !defined(C10_ANDROID)
182
242
183
243
// We always skip this frame (backtrace).
184
244
frames_to_skip += 1 ;
@@ -249,6 +309,13 @@ std::string get_backtrace(
249
309
}
250
310
251
311
return stream.str ();
312
+
313
+ #elif SUPPORTS_BACKTRACE && defined(C10_ANDROID)
314
+
315
+ std::ostringstream oss;
316
+ dump_stack (oss, frames_to_skip, maximum_number_of_frames);
317
+ return oss.str ().c_str ();
318
+
252
319
#elif defined(_MSC_VER) // !SUPPORTS_BACKTRACE
253
320
// This backtrace retrieval is implemented on Windows via the Windows
254
321
// API using `CaptureStackBackTrace`, `SymFromAddr` and
0 commit comments