OLD | NEW |
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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 if (result && wait) { | 387 if (result && wait) { |
388 // The process may not end immediately due to pending I/O | 388 // The process may not end immediately due to pending I/O |
389 if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000)) | 389 if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000)) |
390 DLOG(ERROR) << "Error waiting for process exit: " << GetLastError(); | 390 DLOG(ERROR) << "Error waiting for process exit: " << GetLastError(); |
391 } else if (!result) { | 391 } else if (!result) { |
392 DLOG(ERROR) << "Unable to terminate process: " << GetLastError(); | 392 DLOG(ERROR) << "Unable to terminate process: " << GetLastError(); |
393 } | 393 } |
394 return result; | 394 return result; |
395 } | 395 } |
396 | 396 |
397 bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { | 397 TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { |
398 DWORD exitcode = 0; | 398 DWORD tmp_exit_code = 0; |
399 | 399 |
400 if (!::GetExitCodeProcess(handle, &exitcode)) { | 400 if (!::GetExitCodeProcess(handle, &tmp_exit_code)) { |
401 NOTREACHED(); | 401 NOTREACHED(); |
402 // Assume the child has exited. | 402 if (exit_code) { |
403 if (child_exited) | 403 // This really is a random number. We haven't received any |
404 *child_exited = true; | 404 // information about the exit code, presumably because this |
405 return false; | 405 // process doesn't have permission to get the exit code, or |
| 406 // because of some other cause for GetExitCodeProcess to fail |
| 407 // (MSDN docs don't give the possible failure error codes for |
| 408 // this function, so it could be anything). But we don't want |
| 409 // to leave exit_code uninitialized, since that could cause |
| 410 // random interpretations of the exit code. So we assume it |
| 411 // terminated "normally" in this case. |
| 412 *exit_code = TERMINATION_STATUS_NORMAL_TERMINATION; |
| 413 } |
| 414 // Assume the child has exited normally if we can't get the exit |
| 415 // code. |
| 416 return TERMINATION_STATUS_NORMAL_TERMINATION; |
406 } | 417 } |
407 if (exitcode == STILL_ACTIVE) { | 418 if (tmp_exit_code == STILL_ACTIVE) { |
408 DWORD wait_result = WaitForSingleObject(handle, 0); | 419 DWORD wait_result = WaitForSingleObject(handle, 0); |
409 if (wait_result == WAIT_TIMEOUT) { | 420 if (wait_result == WAIT_TIMEOUT) { |
410 if (child_exited) | 421 if (exit_code) |
411 *child_exited = false; | 422 *exit_code = wait_result; |
412 return false; | 423 return TERMINATION_STATUS_STILL_RUNNING; |
413 } | 424 } |
414 | 425 |
415 DCHECK_EQ(WAIT_OBJECT_0, wait_result); | 426 DCHECK_EQ(WAIT_OBJECT_0, wait_result); |
416 | 427 |
417 // Strange, the process used 0x103 (STILL_ACTIVE) as exit code. | 428 // Strange, the process used 0x103 (STILL_ACTIVE) as exit code. |
418 NOTREACHED(); | 429 NOTREACHED(); |
419 | 430 |
420 return false; | 431 return TERMINATION_STATUS_ABNORMAL_TERMINATION; |
421 } | 432 } |
422 | 433 |
423 // We're sure the child has exited. | 434 if (exit_code) |
424 if (child_exited) | 435 *exit_code = tmp_exit_code; |
425 *child_exited = true; | |
426 | 436 |
427 // Warning, this is not generic code; it heavily depends on the way | 437 // Warning, this is not generic code; it heavily depends on the way |
428 // the rest of the code kills a process. | 438 // the rest of the code kills a process. |
429 | 439 |
430 if (exitcode == PROCESS_END_NORMAL_TERMINATION || | 440 switch (tmp_exit_code) { |
431 exitcode == PROCESS_END_KILLED_BY_USER || | 441 case PROCESS_END_NORMAL_TERMINATION: |
432 exitcode == PROCESS_END_PROCESS_WAS_HUNG || | 442 return TERMINATION_STATUS_NORMAL_TERMINATION; |
433 exitcode == 0xC0000354 || // STATUS_DEBUGGER_INACTIVE. | 443 case 0xC0000354: // STATUS_DEBUGGER_INACTIVE. |
434 exitcode == 0xC000013A || // Control-C/end session. | 444 case 0xC000013A: // Control-C/end session. |
435 exitcode == 0x40010004) { // Debugger terminated process/end session. | 445 case 0x40010004: // Debugger terminated process/end session. |
436 return false; | 446 case PROCESS_END_PROCESS_WAS_KILLED: // Task manager kill. |
| 447 return TERMINATION_STATUS_PROCESS_WAS_KILLED; |
| 448 case PROCESS_END_PROCESS_WAS_HUNG: |
| 449 return TERMINATION_STATUS_PROCESS_WAS_HUNG; |
| 450 default: |
| 451 // All other exit codes indicate crashes. |
| 452 return TERMINATION_STATUS_PROCESS_CRASHED; |
437 } | 453 } |
438 | |
439 // All other exit codes indicate crashes. | |
440 return true; | |
441 } | 454 } |
442 | 455 |
443 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { | 456 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { |
444 bool success = WaitForExitCodeWithTimeout(handle, exit_code, INFINITE); | 457 bool success = WaitForExitCodeWithTimeout(handle, exit_code, INFINITE); |
445 if (!success) | 458 if (!success) |
446 CloseProcessHandle(handle); | 459 CloseProcessHandle(handle); |
447 return success; | 460 return success; |
448 } | 461 } |
449 | 462 |
450 bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code, | 463 bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code, |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 | 900 |
888 PERFORMANCE_INFORMATION info; | 901 PERFORMANCE_INFORMATION info; |
889 if (!InternalGetPerformanceInfo(&info, sizeof(info))) { | 902 if (!InternalGetPerformanceInfo(&info, sizeof(info))) { |
890 LOG(ERROR) << "Failed to fetch internal performance info."; | 903 LOG(ERROR) << "Failed to fetch internal performance info."; |
891 return 0; | 904 return 0; |
892 } | 905 } |
893 return (info.CommitTotal * system_info.dwPageSize) / 1024; | 906 return (info.CommitTotal * system_info.dwPageSize) / 1024; |
894 } | 907 } |
895 | 908 |
896 } // namespace base | 909 } // namespace base |
OLD | NEW |