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 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |