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

Side by Side Diff: client/windows/handler/exception_handler.cc

Issue 13065: Protect the exception handler against failure to create semaphores & a thread... (Closed) Base URL: http://google-breakpad.googlecode.com/svn/trunk/src/
Patch Set: Created 12 years 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 | Annotate | Revision Log
« 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 // Copyright (c) 2006, Google Inc. 1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 // or registration with the server process failed. In either case, 133 // or registration with the server process failed. In either case,
134 // setup to do in-process crash generation. 134 // setup to do in-process crash generation.
135 135
136 // Set synchronization primitives and the handler thread. Each 136 // Set synchronization primitives and the handler thread. Each
137 // ExceptionHandler object gets its own handler thread because that's the 137 // ExceptionHandler object gets its own handler thread because that's the
138 // only way to reliably guarantee sufficient stack space in an exception, 138 // only way to reliably guarantee sufficient stack space in an exception,
139 // and it allows an easy way to get a snapshot of the requesting thread's 139 // and it allows an easy way to get a snapshot of the requesting thread's
140 // context outside of an exception. 140 // context outside of an exception.
141 InitializeCriticalSection(&handler_critical_section_); 141 InitializeCriticalSection(&handler_critical_section_);
142 handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL); 142 handler_start_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
143 assert(handler_start_semaphore_ != NULL);
144
143 handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL); 145 handler_finish_semaphore_ = CreateSemaphore(NULL, 0, 1, NULL);
146 assert(handler_finish_semaphore_ != NULL);
144 147
145 DWORD thread_id; 148 // Don't attempt to create the thread if we could not create the semaphores.
146 handler_thread_ = CreateThread(NULL, // lpThreadAttributes 149 if (handler_finish_semaphore_ != NULL && handler_start_semaphore_ != NULL) {
147 kExceptionHandlerThreadInitialStackSize, 150 DWORD thread_id;
148 ExceptionHandlerThreadMain, 151 handler_thread_ = CreateThread(NULL, // lpThreadAttributes
149 this, // lpParameter 152 kExceptionHandlerThreadInitialStackSize,
150 0, // dwCreationFlags 153 ExceptionHandlerThreadMain,
151 &thread_id); 154 this, // lpParameter
155 0, // dwCreationFlags
156 &thread_id);
157 assert(handler_thread_ != NULL);
158 }
152 159
153 dbghelp_module_ = LoadLibrary(L"dbghelp.dll"); 160 dbghelp_module_ = LoadLibrary(L"dbghelp.dll");
154 if (dbghelp_module_) { 161 if (dbghelp_module_) {
155 minidump_write_dump_ = reinterpret_cast<MiniDumpWriteDump_type>( 162 minidump_write_dump_ = reinterpret_cast<MiniDumpWriteDump_type>(
156 GetProcAddress(dbghelp_module_, "MiniDumpWriteDump")); 163 GetProcAddress(dbghelp_module_, "MiniDumpWriteDump"));
157 } 164 }
158 165
159 // Load this library dynamically to not affect existing projects. Most 166 // Load this library dynamically to not affect existing projects. Most
160 // projects don't link against this directly, it's usually dynamically 167 // projects don't link against this directly, it's usually dynamically
161 // loaded by dependent code. 168 // loaded by dependent code.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 DeleteCriticalSection(&handler_critical_section_); 264 DeleteCriticalSection(&handler_critical_section_);
258 CloseHandle(handler_start_semaphore_); 265 CloseHandle(handler_start_semaphore_);
259 CloseHandle(handler_finish_semaphore_); 266 CloseHandle(handler_finish_semaphore_);
260 } 267 }
261 } 268 }
262 269
263 // static 270 // static
264 DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) { 271 DWORD ExceptionHandler::ExceptionHandlerThreadMain(void* lpParameter) {
265 ExceptionHandler* self = reinterpret_cast<ExceptionHandler *>(lpParameter); 272 ExceptionHandler* self = reinterpret_cast<ExceptionHandler *>(lpParameter);
266 assert(self); 273 assert(self);
274 assert(self->handler_start_semaphore_ != NULL);
275 assert(self->handler_finish_semaphore_ != NULL);
267 276
268 while (true) { 277 while (true) {
269 if (WaitForSingleObject(self->handler_start_semaphore_, INFINITE) == 278 if (WaitForSingleObject(self->handler_start_semaphore_, INFINITE) ==
270 WAIT_OBJECT_0) { 279 WAIT_OBJECT_0) {
271 // Perform the requested action. 280 // Perform the requested action.
272 self->handler_return_value_ = self->WriteMinidumpWithException( 281 self->handler_return_value_ = self->WriteMinidumpWithException(
273 self->requesting_thread_id_, self->exception_info_, self->assertion_); 282 self->requesting_thread_id_, self->exception_info_, self->assertion_);
274 283
275 // Allow the requesting thread to proceed. 284 // Allow the requesting thread to proceed.
276 ReleaseSemaphore(self->handler_finish_semaphore_, 1, NULL); 285 ReleaseSemaphore(self->handler_finish_semaphore_, 1, NULL);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 // The handler either took care of the invalid parameter problem itself, 521 // The handler either took care of the invalid parameter problem itself,
513 // or passed it on to another handler. "Swallow" it by exiting, paralleling 522 // or passed it on to another handler. "Swallow" it by exiting, paralleling
514 // the behavior of "swallowing" exceptions. 523 // the behavior of "swallowing" exceptions.
515 exit(0); 524 exit(0);
516 } 525 }
517 526
518 bool ExceptionHandler::WriteMinidumpOnHandlerThread( 527 bool ExceptionHandler::WriteMinidumpOnHandlerThread(
519 EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion) { 528 EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion) {
520 EnterCriticalSection(&handler_critical_section_); 529 EnterCriticalSection(&handler_critical_section_);
521 530
531 // There isn't much we can do if the handler thread
532 // was not successfully created.
533 if (handler_thread_ == NULL) {
534 LeaveCriticalSection(&handler_critical_section_);
535 return false;
536 }
537
538 // The handler thread should only be created when the semaphores are valid.
539 assert(handler_start_semaphore_ != NULL);
540 assert(handler_finish_semaphore_ != NULL);
541
522 // Set up data to be passed in to the handler thread. 542 // Set up data to be passed in to the handler thread.
523 requesting_thread_id_ = GetCurrentThreadId(); 543 requesting_thread_id_ = GetCurrentThreadId();
524 exception_info_ = exinfo; 544 exception_info_ = exinfo;
525 assertion_ = assertion; 545 assertion_ = assertion;
526 546
527 // This causes the handler thread to call WriteMinidumpWithException. 547 // This causes the handler thread to call WriteMinidumpWithException.
528 ReleaseSemaphore(handler_start_semaphore_, 1, NULL); 548 ReleaseSemaphore(handler_start_semaphore_, 1, NULL);
529 549
530 // Wait until WriteMinidumpWithException is done and collect its return value. 550 // Wait until WriteMinidumpWithException is done and collect its return value.
531 WaitForSingleObject(handler_finish_semaphore_, INFINITE); 551 WaitForSingleObject(handler_finish_semaphore_, INFINITE);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 dump_path_c_, next_minidump_id_c_); 695 dump_path_c_, next_minidump_id_c_);
676 696
677 // remove when VC++7.1 is no longer supported 697 // remove when VC++7.1 is no longer supported
678 minidump_path[MAX_PATH - 1] = L'\0'; 698 minidump_path[MAX_PATH - 1] = L'\0';
679 699
680 next_minidump_path_ = minidump_path; 700 next_minidump_path_ = minidump_path;
681 next_minidump_path_c_ = next_minidump_path_.c_str(); 701 next_minidump_path_c_ = next_minidump_path_.c_str();
682 } 702 }
683 703
684 } // namespace google_breakpad 704 } // namespace google_breakpad
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