OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "CrashHandler.h" | 8 #include "CrashHandler.h" |
9 #include "DMJsonWriter.h" | 9 #include "DMJsonWriter.h" |
10 #include "DMSrcSink.h" | 10 #include "DMSrcSink.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - start_ms); | 122 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - start_ms); |
123 | 123 |
124 SkAutoTAcquire<SkPODSpinlock> lock(gMutex); | 124 SkAutoTAcquire<SkPODSpinlock> lock(gMutex); |
125 SkDebugf("\n%s elapsed, %d active, %d queued, %dMB RAM, %dMB peak\n", | 125 SkDebugf("\n%s elapsed, %d active, %d queued, %dMB RAM, %dMB peak\n", |
126 elapsed.c_str(), gRunning.count(), gPending - gRunning.count(), cur
r, peak); | 126 elapsed.c_str(), gRunning.count(), gPending - gRunning.count(), cur
r, peak); |
127 for (auto& task : gRunning) { | 127 for (auto& task : gRunning) { |
128 SkDebugf("\t%s\n", task.c_str()); | 128 SkDebugf("\t%s\n", task.c_str()); |
129 } | 129 } |
130 } | 130 } |
131 | 131 |
| 132 // Yo dawg, I heard you like signals so I caught a signal in your |
| 133 // signal handler so you can handle signals while you handle signals. |
| 134 // Let's not get into that situation. Only print if we're the first ones to get
a crash signal. |
| 135 static std::atomic<bool> in_signal_handler{false}; |
| 136 |
132 #if defined(SK_BUILD_FOR_WIN32) | 137 #if defined(SK_BUILD_FOR_WIN32) |
133 static void setup_crash_handler() { | 138 static LONG WINAPI handler(EXCEPTION_POINTERS* e) { |
134 // TODO: custom crash handler like below to print out what was running | 139 static const struct { |
135 SetupCrashHandler(); | 140 const char* name; |
| 141 int code; |
| 142 } kExceptions[] = { |
| 143 #define _(E) {#E, E} |
| 144 _(EXCEPTION_ACCESS_VIOLATION), |
| 145 _(EXCEPTION_BREAKPOINT), |
| 146 _(EXCEPTION_INT_DIVIDE_BY_ZERO), |
| 147 _(EXCEPTION_STACK_OVERFLOW), |
| 148 // TODO: more? |
| 149 #undef _ |
| 150 }; |
| 151 |
| 152 if (!in_signal_handler.exchange(true)) { |
| 153 const DWORD code = e->ExceptionRecord->ExceptionCode; |
| 154 SkDebugf("\nCaught exception %u", code); |
| 155 for (const auto& exception : kExceptions) { |
| 156 if (exception.code == code) { |
| 157 SkDebugf(" %s", exception.name); |
| 158 } |
| 159 } |
| 160 SkDebugf("\n"); |
| 161 print_status(); |
| 162 } |
| 163 // Execute default exception handler... hopefully, exit. |
| 164 return EXCEPTION_EXECUTE_HANDLER; |
136 } | 165 } |
| 166 static void setup_crash_handler() { SetUnhandledExceptionFilter(handler); } |
137 | 167 |
138 #else | 168 #else |
139 #include <signal.h> | 169 #include <signal.h> |
| 170 |
140 static void setup_crash_handler() { | 171 static void setup_crash_handler() { |
141 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV }; | 172 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV }; |
142 for (int sig : kSignals) { | 173 for (int sig : kSignals) { |
143 signal(sig, [](int sig) { | 174 signal(sig, [](int sig) { |
144 SkDebugf("\nCaught signal %d [%s].\n", sig, strsignal(sig)); | 175 if (!in_signal_handler.exchange(true)) { |
145 print_status(); | 176 SkDebugf("\nCaught signal %d [%s].\n", sig, strsignal(sig)); |
| 177 print_status(); |
| 178 } |
| 179 // Reraise this signal to the default handler... hopefully, exit
. |
| 180 signal(sig, SIG_DFL); |
| 181 raise(sig); |
146 }); | 182 }); |
147 } | 183 } |
148 } | 184 } |
149 #endif | 185 #endif |
150 | 186 |
151 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 187 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
152 | 188 |
153 struct Gold : public SkString { | 189 struct Gold : public SkString { |
154 Gold() : SkString("") {} | 190 Gold() : SkString("") {} |
155 Gold(const SkString& sink, const SkString& src, | 191 Gold(const SkString& sink, const SkString& src, |
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 Reporter* reporter, | 1373 Reporter* reporter, |
1338 GrContextFactory* fac
tory); | 1374 GrContextFactory* fac
tory); |
1339 } // namespace skiatest | 1375 } // namespace skiatest |
1340 | 1376 |
1341 #if !defined(SK_BUILD_FOR_IOS) | 1377 #if !defined(SK_BUILD_FOR_IOS) |
1342 int main(int argc, char** argv) { | 1378 int main(int argc, char** argv) { |
1343 SkCommandLineFlags::Parse(argc, argv); | 1379 SkCommandLineFlags::Parse(argc, argv); |
1344 return dm_main(); | 1380 return dm_main(); |
1345 } | 1381 } |
1346 #endif | 1382 #endif |
OLD | NEW |