OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <windows.h> |
| 6 #include <stdlib.h> |
| 7 |
| 8 #include "base/at_exit.h" |
| 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" |
| 11 #include "base/win/scoped_handle.h" |
| 12 |
| 13 namespace { |
| 14 |
| 15 // "--help" or "--?" prints the usage message. |
| 16 const char kHelpSwitchName[] = "help"; |
| 17 const char kQuestionSwitchName[] = "?"; |
| 18 |
| 19 const char kUsageMessage[] = |
| 20 "\n" |
| 21 "Usage: %s <pid>\n" |
| 22 "\n" |
| 23 " pid - PID of the process to be crashed.\n"; |
| 24 |
| 25 // Exit codes: |
| 26 const int kSuccessExitCode = 0; |
| 27 const int kUsageExitCode = 1; |
| 28 const int kErrorExitCode = 2; |
| 29 |
| 30 void usage(const char* program_name) { |
| 31 fprintf(stderr, kUsageMessage, program_name); |
| 32 } |
| 33 |
| 34 } // namespace |
| 35 |
| 36 int main(int argc, char** argv) { |
| 37 CommandLine::Init(argc, argv); |
| 38 |
| 39 base::AtExitManager exit_manager; |
| 40 |
| 41 InitLogging(NULL, |
| 42 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, |
| 43 logging::DONT_LOCK_LOG_FILE, |
| 44 logging::APPEND_TO_OLD_LOG_FILE, |
| 45 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); |
| 46 |
| 47 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 48 if (command_line->HasSwitch(kHelpSwitchName) || |
| 49 command_line->HasSwitch(kQuestionSwitchName)) { |
| 50 usage(argv[0]); |
| 51 return kSuccessExitCode; |
| 52 } |
| 53 |
| 54 CommandLine::StringVector args = command_line->GetArgs(); |
| 55 if (args.size() != 1) { |
| 56 usage(argv[0]); |
| 57 return kUsageExitCode; |
| 58 } |
| 59 |
| 60 int pid = _wtoi(args[0].c_str()); |
| 61 if (pid == 0) { |
| 62 LOG(ERROR) << "Invalid process PID: " << args[0]; |
| 63 return kErrorExitCode; |
| 64 } |
| 65 |
| 66 DWORD desired_access = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | |
| 67 PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ; |
| 68 base::win::ScopedHandle process; |
| 69 process.Set(OpenProcess(desired_access, FALSE, pid)); |
| 70 if (!process.IsValid()) { |
| 71 LOG_GETLASTERROR(ERROR) << "Failed to open the process " << pid; |
| 72 return kErrorExitCode; |
| 73 } |
| 74 |
| 75 DWORD thread_id; |
| 76 base::win::ScopedHandle thread; |
| 77 thread.Set(CreateRemoteThread(process.Get(), NULL, 0, NULL, NULL, 0, |
| 78 &thread_id)); |
| 79 if (!thread.IsValid()) { |
| 80 LOG_GETLASTERROR(ERROR) << "Failed to create a remote thread in " << pid; |
| 81 return kErrorExitCode; |
| 82 } |
| 83 |
| 84 return kSuccessExitCode; |
| 85 } |
OLD | NEW |