aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/benchmain.cpp2
-rw-r--r--dm/DM.cpp2
-rw-r--r--gm/gmmain.cpp2
-rw-r--r--gyp/bench.gyp5
-rw-r--r--gyp/crash_handler.gyp11
-rw-r--r--gyp/dm.gyp7
-rw-r--r--gyp/gm.gyp3
-rw-r--r--gyp/tests.gyp1
-rw-r--r--gyp/tools.gyp3
-rw-r--r--tests/skia_test.cpp2
-rw-r--r--tools/CrashHandler.cpp88
-rw-r--r--tools/CrashHandler.h9
-rw-r--r--tools/bench_pictures_main.cpp2
13 files changed, 130 insertions, 7 deletions
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
index 6e18a8ab3a..078a2e80e0 100644
--- a/bench/benchmain.cpp
+++ b/bench/benchmain.cpp
@@ -6,6 +6,7 @@
*/
#include "BenchTimer.h"
+#include "CrashHandler.h"
#include "ResultsWriter.h"
#include "SkBenchLogger.h"
#include "SkBenchmark.h"
@@ -271,6 +272,7 @@ static bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw)
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+ SetupCrashHandler();
SkCommandLineFlags::Parse(argc, argv);
#if SK_ENABLE_INST_COUNT
if (FLAGS_leaks) {
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 776b642e7b..0de661677a 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -9,6 +9,7 @@
#include "SkString.h"
#include "Test.h"
#include "gm.h"
+#include "CrashHandler.h"
#include "DMBenchTask.h"
#include "DMCpuGMTask.h"
@@ -215,6 +216,7 @@ static void append_matching_factories(Registry* head, SkTDArray<typename Registr
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+ SetupCrashHandler();
SkAutoGraphics ag;
SkCommandLineFlags::Parse(argc, argv);
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 0be3454d82..42aed548d1 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -17,6 +17,7 @@
#include "gm_error.h"
#include "gm_expectations.h"
#include "system_preferences.h"
+#include "CrashHandler.h"
#include "SkBitmap.h"
#include "SkColorPriv.h"
#include "SkCommandLineFlags.h"
@@ -2219,6 +2220,7 @@ static bool parse_flags_jpeg_quality() {
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+ SetupCrashHandler();
SkString usage;
usage.printf("Run the golden master tests.\n");
diff --git a/gyp/bench.gyp b/gyp/bench.gyp
index 8c8199167f..a5e0cd6918 100644
--- a/gyp/bench.gyp
+++ b/gyp/bench.gyp
@@ -9,11 +9,12 @@
'target_name': 'bench',
'type': 'executable',
'dependencies': [
- 'skia_lib.gyp:skia_lib',
'bench_timer',
+ 'crash_handler.gyp:CrashHandler',
+ 'etc1.gyp:libetc1',
'flags.gyp:flags',
'jsoncpp.gyp:jsoncpp',
- 'etc1.gyp:libetc1',
+ 'skia_lib.gyp:skia_lib',
],
'sources': [
'../bench/ResultsWriter.cpp',
diff --git a/gyp/crash_handler.gyp b/gyp/crash_handler.gyp
new file mode 100644
index 0000000000..aa5ad94720
--- /dev/null
+++ b/gyp/crash_handler.gyp
@@ -0,0 +1,11 @@
+{
+ 'targets': [{
+ 'target_name': 'CrashHandler',
+ 'type': 'static_library',
+ 'sources': [ '../tools/CrashHandler.cpp' ],
+ 'dependencies': [ 'skia_lib.gyp:skia_lib' ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [ '../tools' ],
+ },
+ }]
+}
diff --git a/gyp/dm.gyp b/gyp/dm.gyp
index a849e5433c..f69ffe5f4b 100644
--- a/gyp/dm.gyp
+++ b/gyp/dm.gyp
@@ -55,11 +55,12 @@
'../src/utils/debugger/SkObjectParser.cpp',
],
'dependencies': [
- 'skia_lib.gyp:skia_lib',
+ 'crash_handler.gyp:CrashHandler',
+ 'etc1.gyp:libetc1',
'flags.gyp:flags',
- 'jsoncpp.gyp:jsoncpp',
'gputest.gyp:skgputest',
- 'etc1.gyp:libetc1',
+ 'jsoncpp.gyp:jsoncpp',
+ 'skia_lib.gyp:skia_lib',
],
'conditions': [
['skia_android_framework', {
diff --git a/gyp/gm.gyp b/gyp/gm.gyp
index 9b74e74669..fd8f74d621 100644
--- a/gyp/gm.gyp
+++ b/gyp/gm.gyp
@@ -16,8 +16,9 @@
'../tools/sk_tool_utils.cpp',
],
'dependencies': [
- 'skia_lib.gyp:skia_lib',
+ 'crash_handler.gyp:CrashHandler',
'jsoncpp.gyp:jsoncpp',
+ 'skia_lib.gyp:skia_lib',
],
'direct_dependent_settings': {
'include_dirs': [
diff --git a/gyp/tests.gyp b/gyp/tests.gyp
index 9210bf60b1..80768efa35 100644
--- a/gyp/tests.gyp
+++ b/gyp/tests.gyp
@@ -11,6 +11,7 @@
'pathops_unittest.gypi',
'tests.gypi',
],
+ 'dependencies': [ 'crash_handler.gyp:CrashHandler' ],
'sources': [
'../tests/skia_test.cpp',
],
diff --git a/gyp/tools.gyp b/gyp/tools.gyp
index 9e1cf05558..9cea4617e1 100644
--- a/gyp/tools.gyp
+++ b/gyp/tools.gyp
@@ -300,11 +300,12 @@
],
'dependencies': [
'bench.gyp:bench_timer',
+ 'crash_handler.gyp:CrashHandler',
'flags.gyp:flags',
'jsoncpp.gyp:jsoncpp',
'skia_lib.gyp:skia_lib',
- 'tools.gyp:picture_utils',
'tools.gyp:picture_renderer',
+ 'tools.gyp:picture_utils',
'tools.gyp:timer_data',
],
},
diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp
index b7fbfc627b..f70a7fab62 100644
--- a/tests/skia_test.cpp
+++ b/tests/skia_test.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "CrashHandler.h"
#include "OverwriteLine.h"
#include "SkCommandLineFlags.h"
#include "SkGraphics.h"
@@ -132,6 +133,7 @@ static bool should_run(const char* testName, bool isGPUTest) {
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+ SetupCrashHandler();
SkCommandLineFlags::SetUsage("");
SkCommandLineFlags::Parse(argc, argv);
Test::SetResourcePath(FLAGS_resourcePath[0]);
diff --git a/tools/CrashHandler.cpp b/tools/CrashHandler.cpp
new file mode 100644
index 0000000000..193e1af0b2
--- /dev/null
+++ b/tools/CrashHandler.cpp
@@ -0,0 +1,88 @@
+#include "CrashHandler.h"
+
+#include "SkTypes.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#if defined(SK_BUILD_FOR_MAC)
+
+// We only use local unwinding, so we can define this to select a faster implementation.
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#include <cxxabi.h>
+
+static void handler(int sig) {
+ unw_context_t context;
+ unw_getcontext(&context);
+
+ unw_cursor_t cursor;
+ unw_init_local(&cursor, &context);
+
+ fprintf(stderr, "\nSignal %d:\n", sig);
+ while (unw_step(&cursor) > 0) {
+ static const size_t kMax = 256;
+ char mangled[kMax], demangled[kMax];
+ unw_word_t offset;
+ unw_get_proc_name(&cursor, mangled, kMax, &offset);
+
+ int ok;
+ size_t len = kMax;
+ abi::__cxa_demangle(mangled, demangled, &len, &ok);
+
+ fprintf(stderr, "%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
+ }
+ fprintf(stderr, "\n");
+
+ // Exit NOW. Don't notify other threads, don't call anything registered with atexit().
+ _Exit(sig);
+}
+
+#elif defined(SK_BUILD_FOR_UNIX)
+
+// We'd use libunwind here too, but it's a pain to get installed for both 32 and 64 bit on bots.
+// Doesn't matter much: catchsegv is best anyway.
+#include <execinfo.h>
+
+static void handler(int sig) {
+ static const int kMax = 64;
+ void* stack[kMax];
+ const int count = backtrace(stack, kMax);
+
+ fprintf(stderr, "\nSignal %d:\n", sig);
+ backtrace_symbols_fd(stack, count, 2/*stderr*/);
+
+ // Exit NOW. Don't notify other threads, don't call anything registered with atexit().
+ _Exit(sig);
+}
+
+#endif
+
+#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC)
+
+void SetupCrashHandler() {
+ static const int kSignals[] = {
+ SIGABRT,
+ SIGBUS,
+ SIGFPE,
+ SIGILL,
+ SIGSEGV,
+ };
+
+ for (size_t i = 0; i < sizeof(kSignals) / sizeof(kSignals[0]); i++) {
+ // Register our signal handler unless something's already done so (e.g. catchsegv).
+ void (*prev)(int) = signal(kSignals[i], handler);
+ if (prev != SIG_DFL) {
+ signal(kSignals[i], prev);
+ }
+ }
+}
+
+// TODO: #elif defined(SK_BUILD_FOR_WIN) when I find a Windows machine to work from.
+
+#else
+
+void SetupCrashHandler() { }
+
+#endif
diff --git a/tools/CrashHandler.h b/tools/CrashHandler.h
new file mode 100644
index 0000000000..6c22c8ee70
--- /dev/null
+++ b/tools/CrashHandler.h
@@ -0,0 +1,9 @@
+#ifndef CrashHandler_DEFINED
+#define CrashHandler_DEFINED
+
+// If possible (and not already done) register a handler for a stack trace when we crash.
+// Currently this works on Linux and Mac, hopefully Windows soon.
+// On Linux, you will get much better results than we can deliver by running "catchsegv <program>".
+void SetupCrashHandler();
+
+#endif//CrashHandler_DEFINED
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index 6b76bfc8ef..c63ffff5b7 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -6,6 +6,7 @@
*/
#include "BenchTimer.h"
+#include "CrashHandler.h"
#include "CopyTilesRenderer.h"
#include "LazyDecodeBitmap.h"
#include "PictureBenchmark.h"
@@ -391,6 +392,7 @@ static int process_input(const char* input,
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+ SetupCrashHandler();
SkString usage;
usage.printf("Time drawing .skp files.\n"
"\tPossible arguments for --filter: [%s]\n\t\t[%s]",