-
Notifications
You must be signed in to change notification settings - Fork 6k
Add Windows support for //flutter/fml/backtrace.h
#36202
Changes from all commits
760e866
6b26b25
aa92903
1d5b4fc
09649c1
dca3616
dba4017
a5b212c
4fe24c3
f67dcf6
393233e
edfe8c1
30105e7
51eaf5d
8df181b
6d5f7c2
a5a124a
763d211
987eee5
d6c28d9
20b6dc4
ce81ec5
a4f3850
b6c657e
a99f0dc
24b2aa5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,68 +4,56 @@ | |
|
|
||
| #include "flutter/fml/backtrace.h" | ||
|
|
||
| #include <cxxabi.h> | ||
| #include <dlfcn.h> | ||
| #include <execinfo.h> | ||
|
|
||
| #include <csignal> | ||
| #include <sstream> | ||
|
|
||
| #if FML_OS_WIN | ||
| #include <crtdbg.h> | ||
| #include <debugapi.h> | ||
| #endif | ||
|
|
||
| #include "flutter/fml/build_config.h" | ||
| #include "flutter/fml/logging.h" | ||
| #include "flutter/fml/paths.h" | ||
| #include "third_party/abseil-cpp/absl/debugging/symbolize.h" | ||
|
|
||
| #ifdef FML_OS_WIN | ||
| #include <Windows.h> | ||
| #include <crtdbg.h> | ||
| #include <debugapi.h> | ||
| #else // FML_OS_WIN | ||
| #include <execinfo.h> | ||
| #endif // FML_OS_WIN | ||
|
|
||
| namespace fml { | ||
|
|
||
| static std::string kKUnknownFrameName = "Unknown"; | ||
|
|
||
| static std::string DemangleSymbolName(const std::string& mangled) { | ||
| if (mangled == kKUnknownFrameName) { | ||
| return kKUnknownFrameName; | ||
| } | ||
|
|
||
| int status = 0; | ||
| size_t length = 0; | ||
| char* demangled = __cxxabiv1::__cxa_demangle( | ||
| mangled.data(), // mangled name | ||
| nullptr, // output buffer (malloc-ed if nullptr) | ||
| &length, // demangled length | ||
| &status); | ||
|
|
||
| if (demangled == nullptr || status != 0) { | ||
| return mangled; | ||
| } | ||
|
|
||
| auto demangled_string = std::string{demangled, length}; | ||
| free(demangled); | ||
| return demangled_string; | ||
| } | ||
|
|
||
| static std::string GetSymbolName(void* symbol) { | ||
| char name[1024]; | ||
| if (!absl::Symbolize(symbol, name, sizeof(name))) { | ||
| return kKUnknownFrameName; | ||
| } | ||
| return name; | ||
| } | ||
|
|
||
| return DemangleSymbolName({name}); | ||
| static int Backtrace(void** symbols, int size) { | ||
| #if FML_OS_WIN | ||
| return CaptureStackBackTrace(0, size, symbols, NULL); | ||
| #else | ||
| return ::backtrace(symbols, size); | ||
| #endif // FML_OS_WIN | ||
| } | ||
|
|
||
| std::string BacktraceHere(size_t offset) { | ||
| constexpr size_t kMaxFrames = 256; | ||
| void* symbols[kMaxFrames]; | ||
| const auto available_frames = ::backtrace(symbols, kMaxFrames); | ||
| const auto available_frames = Backtrace(symbols, kMaxFrames); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should/could we use abseil's
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks nice! I'm replacing with this. I'll check output on linux...
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also find
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Source code (prototype): moko256@3ca3f10 Linux: |
||
| if (available_frames <= 0) { | ||
| return ""; | ||
| } | ||
|
|
||
| // Exclude here. | ||
| offset += 2; | ||
|
|
||
| std::stringstream stream; | ||
| for (int i = 1 + offset; i < available_frames; ++i) { | ||
| stream << "Frame " << i - 1 - offset << ": " << symbols[i] << " " | ||
| for (int i = offset; i < available_frames; ++i) { | ||
| stream << "Frame " << i - offset << ": " << symbols[i] << " " | ||
| << GetSymbolName(symbols[i]) << std::endl; | ||
| } | ||
| return stream.str(); | ||
|
|
@@ -74,12 +62,14 @@ std::string BacktraceHere(size_t offset) { | |
| static size_t kKnownSignalHandlers[] = { | ||
| SIGABRT, // abort program | ||
| SIGFPE, // floating-point exception | ||
| SIGBUS, // bus error | ||
| SIGTERM, // software termination signal | ||
| SIGSEGV, // segmentation violation | ||
| #if !FML_OS_WIN | ||
| SIGBUS, // bus error | ||
| SIGSYS, // non-existent system call invoked | ||
| SIGPIPE, // write on a pipe with no reader | ||
| SIGALRM, // real-time timer expired | ||
| SIGTERM, // software termination signal | ||
| #endif // !FML_OS_WIN | ||
| }; | ||
|
|
||
| static std::string SignalNameToString(int signal) { | ||
|
|
@@ -88,18 +78,20 @@ static std::string SignalNameToString(int signal) { | |
| return "SIGABRT"; | ||
| case SIGFPE: | ||
| return "SIGFPE"; | ||
| case SIGBUS: | ||
| return "SIGBUS"; | ||
| case SIGSEGV: | ||
| return "SIGSEGV"; | ||
| case SIGTERM: | ||
| return "SIGTERM"; | ||
| #if !FML_OS_WIN | ||
| case SIGBUS: | ||
| return "SIGBUS"; | ||
| case SIGSYS: | ||
| return "SIGSYS"; | ||
| case SIGPIPE: | ||
| return "SIGPIPE"; | ||
| case SIGALRM: | ||
| return "SIGALRM"; | ||
| case SIGTERM: | ||
| return "SIGTERM"; | ||
| #endif // !FML_OS_WIN | ||
| }; | ||
| return std::to_string(signal); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,9 @@ | |
|
|
||
| namespace fml { | ||
|
|
||
| // Retrieve the backtrace, for debugging. | ||
| // | ||
| // If the |offset| is 0, the backtrace is included caller function. | ||
| std::string BacktraceHere(size_t offset = 0); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why remove this function? I presume the intent was for use when debugging.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the #16450, which introduced I just intended to avoid bitrot to follow the style guide. I know this can be used to debug. If any engine's contributors use it to debug, I'll restore it.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sgtm -- I don't use it to debug, so personally I'm fine if we remove it (we can always restore it in a followup patch with appropriate tweaks if desired)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't have code that isn't used, but I do end up using this call frequently when debugging/testing locally. Does absl have a similar function?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (This is not blocking for landing, but I'd like to know for my own edification)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If people are using it for development, and if absl doesn't have an equivalent then let's restore it (the existing test will avoid bitrot, at least to some extent). If absl does have an equivalent call, maybe we could add a "// See: absl::SomethingOrOther" type comment to the class docs as a little breadcrumb to help developers find it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
|
||
| void InstallCrashHandler(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.