Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: dm/DM.cpp

Issue 2177843003: DM: print which task caused the crash. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: guard where used Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 109
110 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); 110 SK_DECLARE_STATIC_MUTEX(gFailuresMutex);
111 static SkTArray<SkString> gFailures; 111 static SkTArray<SkString> gFailures;
112 112
113 static void fail(const SkString& err) { 113 static void fail(const SkString& err) {
114 SkAutoMutexAcquire lock(gFailuresMutex); 114 SkAutoMutexAcquire lock(gFailuresMutex);
115 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); 115 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str());
116 gFailures.push_back(err); 116 gFailures.push_back(err);
117 } 117 }
118 118
119 struct Running {
120 SkString id;
121 SkThreadID thread;
122
123 void dump() const {
124 info("\t%s\n", id.c_str());
125 }
126 };
119 127
120 // We use a spinlock to make locking this in a signal handler _somewhat_ safe. 128 // We use a spinlock to make locking this in a signal handler _somewhat_ safe.
121 static SkSpinlock gMutex; 129 static SkSpinlock gMutex;
122 static int32_t gPending; 130 static int32_t gPending;
123 static SkTArray<SkString> gRunning; 131 static SkTArray<Running> gRunning;
124 132
125 static void done(const char* config, const char* src, const char* srcOptions, co nst char* name) { 133 static void done(const char* config, const char* src, const char* srcOptions, co nst char* name) {
126 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); 134 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name);
127 vlog("done %s\n", id.c_str()); 135 vlog("done %s\n", id.c_str());
128 int pending; 136 int pending;
129 { 137 {
130 SkAutoMutexAcquire lock(gMutex); 138 SkAutoMutexAcquire lock(gMutex);
131 for (int i = 0; i < gRunning.count(); i++) { 139 for (int i = 0; i < gRunning.count(); i++) {
132 if (gRunning[i] == id) { 140 if (gRunning[i].id == id) {
133 gRunning.removeShuffle(i); 141 gRunning.removeShuffle(i);
134 break; 142 break;
135 } 143 }
136 } 144 }
137 pending = --gPending; 145 pending = --gPending;
138 } 146 }
139 // We write our dm.json file every once in a while in case we crash. 147 // We write our dm.json file every once in a while in case we crash.
140 // Notice this also handles the final dm.json when pending == 0. 148 // Notice this also handles the final dm.json when pending == 0.
141 if (pending % 500 == 0) { 149 if (pending % 500 == 0) {
142 JsonWriter::DumpJson(); 150 JsonWriter::DumpJson();
143 } 151 }
144 } 152 }
145 153
146 static void start(const char* config, const char* src, const char* srcOptions, c onst char* name) { 154 static void start(const char* config, const char* src, const char* srcOptions, c onst char* name) {
147 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); 155 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name);
148 vlog("start %s\n", id.c_str()); 156 vlog("start %s\n", id.c_str());
149 SkAutoMutexAcquire lock(gMutex); 157 SkAutoMutexAcquire lock(gMutex);
150 gRunning.push_back(id); 158 gRunning.push_back({id,SkGetThreadID()});
151 } 159 }
152 160
153 static void print_status() { 161 static void print_status() {
154 int curr = sk_tools::getCurrResidentSetSizeMB(), 162 int curr = sk_tools::getCurrResidentSetSizeMB(),
155 peak = sk_tools::getMaxResidentSetSizeMB(); 163 peak = sk_tools::getMaxResidentSetSizeMB();
156 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - kStartMs); 164 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - kStartMs);
157 165
158 SkAutoMutexAcquire lock(gMutex); 166 SkAutoMutexAcquire lock(gMutex);
159 info("\n%s elapsed, %d active, %d queued, %dMB RAM, %dMB peak\n", 167 info("\n%s elapsed, %d active, %d queued, %dMB RAM, %dMB peak\n",
160 elapsed.c_str(), gRunning.count(), gPending - gRunning.count(), curr, p eak); 168 elapsed.c_str(), gRunning.count(), gPending - gRunning.count(), curr, p eak);
161 for (auto& task : gRunning) { 169 for (auto& task : gRunning) {
162 info("\t%s\n", task.c_str()); 170 task.dump();
163 } 171 }
164 } 172 }
165 173
174 #if !defined(SK_BUILD_FOR_ANDROID)
175 static void find_culprit() {
176 // Assumes gMutex is locked.
177 SkThreadID thisThread = SkGetThreadID();
178 for (auto& task : gRunning) {
179 if (task.thread == thisThread) {
180 info("Likely culprit:\n");
181 task.dump();
182 }
183 }
184 }
185 #endif
186
166 #if defined(SK_BUILD_FOR_WIN32) 187 #if defined(SK_BUILD_FOR_WIN32)
167 static LONG WINAPI crash_handler(EXCEPTION_POINTERS* e) { 188 static LONG WINAPI crash_handler(EXCEPTION_POINTERS* e) {
168 static const struct { 189 static const struct {
169 const char* name; 190 const char* name;
170 DWORD code; 191 DWORD code;
171 } kExceptions[] = { 192 } kExceptions[] = {
172 #define _(E) {#E, E} 193 #define _(E) {#E, E}
173 _(EXCEPTION_ACCESS_VIOLATION), 194 _(EXCEPTION_ACCESS_VIOLATION),
174 _(EXCEPTION_BREAKPOINT), 195 _(EXCEPTION_BREAKPOINT),
175 _(EXCEPTION_INT_DIVIDE_BY_ZERO), 196 _(EXCEPTION_INT_DIVIDE_BY_ZERO),
176 _(EXCEPTION_STACK_OVERFLOW), 197 _(EXCEPTION_STACK_OVERFLOW),
177 // TODO: more? 198 // TODO: more?
178 #undef _ 199 #undef _
179 }; 200 };
180 201
181 SkAutoMutexAcquire lock(gMutex); 202 SkAutoMutexAcquire lock(gMutex);
182 203
183 const DWORD code = e->ExceptionRecord->ExceptionCode; 204 const DWORD code = e->ExceptionRecord->ExceptionCode;
184 info("\nCaught exception %u", code); 205 info("\nCaught exception %u", code);
185 for (const auto& exception : kExceptions) { 206 for (const auto& exception : kExceptions) {
186 if (exception.code == code) { 207 if (exception.code == code) {
187 info(" %s", exception.name); 208 info(" %s", exception.name);
188 } 209 }
189 } 210 }
190 info(", was running:\n"); 211 info(", was running:\n");
191 for (auto& task : gRunning) { 212 for (auto& task : gRunning) {
192 info("\t%s\n", task.c_str()); 213 task.dump();
193 } 214 }
215 find_culprit();
194 fflush(stdout); 216 fflush(stdout);
195 217
196 // Execute default exception handler... hopefully, exit. 218 // Execute default exception handler... hopefully, exit.
197 return EXCEPTION_EXECUTE_HANDLER; 219 return EXCEPTION_EXECUTE_HANDLER;
198 } 220 }
199 static void setup_crash_handler() { SetUnhandledExceptionFilter(crash_handle r); } 221 static void setup_crash_handler() { SetUnhandledExceptionFilter(crash_handle r); }
200 222
201 #elif !defined(SK_BUILD_FOR_ANDROID) 223 #elif !defined(SK_BUILD_FOR_ANDROID)
202 #include <execinfo.h> 224 #include <execinfo.h>
203 #include <signal.h> 225 #include <signal.h>
204 #include <stdlib.h> 226 #include <stdlib.h>
205 227
206 static void crash_handler(int sig) { 228 static void crash_handler(int sig) {
207 SkAutoMutexAcquire lock(gMutex); 229 SkAutoMutexAcquire lock(gMutex);
208 230
209 info("\nCaught signal %d [%s], was running:\n", sig, strsignal(sig)); 231 info("\nCaught signal %d [%s], was running:\n", sig, strsignal(sig));
210 for (auto& task : gRunning) { 232 for (auto& task : gRunning) {
211 info("\t%s\n", task.c_str()); 233 task.dump();
212 } 234 }
235 find_culprit();
213 236
214 void* stack[64]; 237 void* stack[64];
215 int count = backtrace(stack, SK_ARRAY_COUNT(stack)); 238 int count = backtrace(stack, SK_ARRAY_COUNT(stack));
216 char** symbols = backtrace_symbols(stack, count); 239 char** symbols = backtrace_symbols(stack, count);
217 info("\nStack trace:\n"); 240 info("\nStack trace:\n");
218 for (int i = 0; i < count; i++) { 241 for (int i = 0; i < count; i++) {
219 info(" %s\n", symbols[i]); 242 info(" %s\n", symbols[i]);
220 } 243 }
221 fflush(stdout); 244 fflush(stdout);
222 245
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 #endif 1431 #endif
1409 } 1432 }
1410 } // namespace skiatest 1433 } // namespace skiatest
1411 1434
1412 #if !defined(SK_BUILD_FOR_IOS) 1435 #if !defined(SK_BUILD_FOR_IOS)
1413 int main(int argc, char** argv) { 1436 int main(int argc, char** argv) {
1414 SkCommandLineFlags::Parse(argc, argv); 1437 SkCommandLineFlags::Parse(argc, argv);
1415 return dm_main(); 1438 return dm_main();
1416 } 1439 }
1417 #endif 1440 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698