Flutter Engine
The Flutter Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
std::pair< bool, std::string > GetExecutablePath()
Definition: ascii_trie.cc:9
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
static SkString to_string(int n)
Definition: nanobench.cpp:119
SeparatedVector2 offset
#define ERROR(message)
Definition: elf_loader.cc:260