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

Side by Side Diff: base/process_util_win.cc

Issue 3386014: This adds some plumbing for propagating the status and error code of a (Closed)
Patch Set: Fixed Mac code to handle both SEGV and BUS Created 10 years, 3 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 | « base/process_util_unittest.cc ('k') | chrome/browser/browser_child_process_host.h » ('j') | 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process_util.h" 5 #include "base/process_util.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <io.h> 8 #include <io.h>
9 #include <windows.h> 9 #include <windows.h>
10 #include <userenv.h> 10 #include <userenv.h>
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 if (result && wait) { 376 if (result && wait) {
377 // The process may not end immediately due to pending I/O 377 // The process may not end immediately due to pending I/O
378 if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000)) 378 if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000))
379 DLOG(ERROR) << "Error waiting for process exit: " << GetLastError(); 379 DLOG(ERROR) << "Error waiting for process exit: " << GetLastError();
380 } else if (!result) { 380 } else if (!result) {
381 DLOG(ERROR) << "Unable to terminate process: " << GetLastError(); 381 DLOG(ERROR) << "Unable to terminate process: " << GetLastError();
382 } 382 }
383 return result; 383 return result;
384 } 384 }
385 385
386 bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { 386 TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
387 DWORD exitcode = 0; 387 DWORD tmp_exit_code = 0;
388 388
389 if (!::GetExitCodeProcess(handle, &exitcode)) { 389 if (!::GetExitCodeProcess(handle, &tmp_exit_code)) {
390 NOTREACHED(); 390 NOTREACHED();
391 // Assume the child has exited. 391 if (exit_code) {
392 if (child_exited) 392 // This really is a random number. We haven't received any
393 *child_exited = true; 393 // information about the exit code, presumably because this
394 return false; 394 // process doesn't have permission to get the exit code, or
395 // because of some other cause for GetExitCodeProcess to fail
396 // (MSDN docs don't give the possible failure error codes for
397 // this function, so it could be anything). But we don't want
398 // to leave exit_code uninitialized, since that could cause
399 // random interpretations of the exit code. So we assume it
400 // terminated "normally" in this case.
401 *exit_code = TERMINATION_STATUS_NORMAL_TERMINATION;
402 }
403 // Assume the child has exited normally if we can't get the exit
404 // code.
405 return TERMINATION_STATUS_NORMAL_TERMINATION;
395 } 406 }
396 if (exitcode == STILL_ACTIVE) { 407 if (tmp_exit_code == STILL_ACTIVE) {
397 DWORD wait_result = WaitForSingleObject(handle, 0); 408 DWORD wait_result = WaitForSingleObject(handle, 0);
398 if (wait_result == WAIT_TIMEOUT) { 409 if (wait_result == WAIT_TIMEOUT) {
399 if (child_exited) 410 if (exit_code)
400 *child_exited = false; 411 *exit_code = wait_result;
401 return false; 412 return TERMINATION_STATUS_STILL_RUNNING;
402 } 413 }
403 414
404 DCHECK_EQ(WAIT_OBJECT_0, wait_result); 415 DCHECK_EQ(WAIT_OBJECT_0, wait_result);
405 416
406 // Strange, the process used 0x103 (STILL_ACTIVE) as exit code. 417 // Strange, the process used 0x103 (STILL_ACTIVE) as exit code.
407 NOTREACHED(); 418 NOTREACHED();
408 419
409 return false; 420 return TERMINATION_STATUS_ABNORMAL_TERMINATION;
410 } 421 }
411 422
412 // We're sure the child has exited. 423 if (exit_code)
413 if (child_exited) 424 *exit_code = tmp_exit_code;
414 *child_exited = true;
415 425
416 // Warning, this is not generic code; it heavily depends on the way 426 // Warning, this is not generic code; it heavily depends on the way
417 // the rest of the code kills a process. 427 // the rest of the code kills a process.
418 428
419 if (exitcode == PROCESS_END_NORMAL_TERMINATION || 429 switch (tmp_exit_code) {
420 exitcode == PROCESS_END_KILLED_BY_USER || 430 case PROCESS_END_NORMAL_TERMINATION:
421 exitcode == PROCESS_END_PROCESS_WAS_HUNG || 431 return TERMINATION_STATUS_NORMAL_TERMINATION;
422 exitcode == 0xC0000354 || // STATUS_DEBUGGER_INACTIVE. 432 case 0xC0000354: // STATUS_DEBUGGER_INACTIVE.
423 exitcode == 0xC000013A || // Control-C/end session. 433 case 0xC000013A: // Control-C/end session.
424 exitcode == 0x40010004) { // Debugger terminated process/end session. 434 case 0x40010004: // Debugger terminated process/end session.
425 return false; 435 case PROCESS_END_PROCESS_WAS_KILLED: // Task manager kill.
436 return TERMINATION_STATUS_PROCESS_WAS_KILLED;
437 case PROCESS_END_PROCESS_WAS_HUNG:
438 return TERMINATION_STATUS_PROCESS_WAS_HUNG;
439 default:
440 // All other exit codes indicate crashes.
441 return TERMINATION_STATUS_PROCESS_CRASHED;
426 } 442 }
427
428 // All other exit codes indicate crashes.
429 return true;
430 } 443 }
431 444
432 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { 445 bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
433 bool success = WaitForExitCodeWithTimeout(handle, exit_code, INFINITE); 446 bool success = WaitForExitCodeWithTimeout(handle, exit_code, INFINITE);
434 if (!success) 447 if (!success)
435 CloseProcessHandle(handle); 448 CloseProcessHandle(handle);
436 return success; 449 return success;
437 } 450 }
438 451
439 bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code, 452 bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 889
877 PERFORMANCE_INFORMATION info; 890 PERFORMANCE_INFORMATION info;
878 if (!InternalGetPerformanceInfo(&info, sizeof(info))) { 891 if (!InternalGetPerformanceInfo(&info, sizeof(info))) {
879 LOG(ERROR) << "Failed to fetch internal performance info."; 892 LOG(ERROR) << "Failed to fetch internal performance info.";
880 return 0; 893 return 0;
881 } 894 }
882 return (info.CommitTotal * system_info.dwPageSize) / 1024; 895 return (info.CommitTotal * system_info.dwPageSize) / 1024;
883 } 896 }
884 897
885 } // namespace base 898 } // namespace base
OLDNEW
« no previous file with comments | « base/process_util_unittest.cc ('k') | chrome/browser/browser_child_process_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698