Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
backtrace.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/fml/backtrace.h"
6
7#include <csignal>
8#include <sstream>
9
10#include "flutter/fml/build_config.h"
11#include "flutter/fml/logging.h"
12#include "flutter/fml/paths.h"
13#include "flutter/third_party/abseil-cpp/absl/debugging/symbolize.h"
14
15#ifdef FML_OS_WIN
16#include <Windows.h>
17#include <crtdbg.h>
18#include <debugapi.h>
19#else // FML_OS_WIN
20#include <execinfo.h>
21#endif // FML_OS_WIN
22
23namespace fml {
24
25static std::string kKUnknownFrameName = "Unknown";
26
27static std::string GetSymbolName(void* symbol) {
28 char name[1024];
29 if (!absl::Symbolize(symbol, name, sizeof(name))) {
30 return kKUnknownFrameName;
31 }
32 return name;
33}
34
35static int Backtrace(void** symbols, int size) {
36#if FML_OS_WIN
37 return CaptureStackBackTrace(0, size, symbols, NULL);
38#else
39 return ::backtrace(symbols, size);
40#endif // FML_OS_WIN
41}
42
43std::string BacktraceHere(size_t offset) {
44 constexpr size_t kMaxFrames = 256;
45 void* symbols[kMaxFrames];
46 const auto available_frames = Backtrace(symbols, kMaxFrames);
47 if (available_frames <= 0) {
48 return "";
49 }
50
51 // Exclude here.
52 offset += 2;
53
54 std::stringstream stream;
55 for (int i = offset; i < available_frames; ++i) {
56 stream << "Frame " << i - offset << ": " << symbols[i] << " "
57 << GetSymbolName(symbols[i]) << std::endl;
58 }
59 return stream.str();
60}
61
62static size_t kKnownSignalHandlers[] = {
63 SIGABRT, // abort program
64 SIGFPE, // floating-point exception
65 SIGTERM, // software termination signal
66 SIGSEGV, // segmentation violation
67#if !FML_OS_WIN
68 SIGBUS, // bus error
69 SIGSYS, // non-existent system call invoked
70 SIGPIPE, // write on a pipe with no reader
71 SIGALRM, // real-time timer expired
72#endif // !FML_OS_WIN
73};
74
75static std::string SignalNameToString(int signal) {
76 switch (signal) {
77 case SIGABRT:
78 return "SIGABRT";
79 case SIGFPE:
80 return "SIGFPE";
81 case SIGSEGV:
82 return "SIGSEGV";
83 case SIGTERM:
84 return "SIGTERM";
85#if !FML_OS_WIN
86 case SIGBUS:
87 return "SIGBUS";
88 case SIGSYS:
89 return "SIGSYS";
90 case SIGPIPE:
91 return "SIGPIPE";
92 case SIGALRM:
93 return "SIGALRM";
94#endif // !FML_OS_WIN
95 };
96 return std::to_string(signal);
97}
98
99static void ToggleSignalHandlers(bool set);
100
101static void SignalHandler(int signal) {
102 // We are a crash signal handler. This can only happen once. Since we don't
103 // want to catch crashes while we are generating the crash reports, disable
104 // all set signal handlers to their default values before reporting the crash
105 // and re-raising the signal.
107
108 FML_LOG(ERROR) << "Caught signal " << SignalNameToString(signal)
109 << " during program execution." << std::endl
110 << BacktraceHere(3);
111
112 ::raise(signal);
113}
114
115static void ToggleSignalHandlers(bool set) {
116 for (size_t i = 0; i < sizeof(kKnownSignalHandlers) / sizeof(size_t); ++i) {
117 auto signal_name = kKnownSignalHandlers[i];
118 auto handler = set ? &SignalHandler : SIG_DFL;
119
120 if (::signal(signal_name, handler) == SIG_ERR) {
121 FML_LOG(ERROR) << "Could not attach signal handler for " << signal_name;
122 }
123 }
124}
125
127#if FML_OS_WIN
128 if (!IsDebuggerPresent()) {
129 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
130 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
131 }
132#endif
133 auto exe_path = fml::paths::GetExecutablePath();
134 if (exe_path.first) {
135 absl::InitializeSymbolizer(exe_path.second.c_str());
136 }
138}
139
141 return true;
142}
143
144} // namespace fml
#define FML_LOG(severity)
Definition logging.h:82
const char * name
Definition fuchsia.cc:50
std::pair< bool, std::string > GetExecutablePath()
constexpr std::size_t size(T(&array)[N])
Definition size.h:13
static std::string GetSymbolName(void *symbol)
Definition backtrace.cc:27
static size_t kKnownSignalHandlers[]
Definition backtrace.cc:62
std::string BacktraceHere(size_t offset)
Definition backtrace.cc:43
static std::string SignalNameToString(int signal)
Definition backtrace.cc:75
bool IsCrashHandlingSupported()
Definition backtrace.cc:140
static void ToggleSignalHandlers(bool set)
Definition backtrace.cc:115
static int Backtrace(void **symbols, int size)
Definition backtrace.cc:35
void InstallCrashHandler()
Definition backtrace.cc:126
static void SignalHandler(int signal)
Definition backtrace.cc:101
static std::string kKUnknownFrameName
Definition backtrace.cc:25
Point offset
#define ERROR(message)