OLD | NEW |
1 // Copyright 2016 The Crashpad Authors. All rights reserved. | 1 // Copyright 2016 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 ScopedFileHANDLE thread_snap(thread_snap_raw); | 40 ScopedFileHANDLE thread_snap(thread_snap_raw); |
41 | 41 |
42 THREADENTRY32 te32; | 42 THREADENTRY32 te32; |
43 te32.dwSize = sizeof(THREADENTRY32); | 43 te32.dwSize = sizeof(THREADENTRY32); |
44 if (!Thread32First(thread_snap.get(), &te32)) { | 44 if (!Thread32First(thread_snap.get(), &te32)) { |
45 LOG(ERROR) << "Thread32First"; | 45 LOG(ERROR) << "Thread32First"; |
46 return false; | 46 return false; |
47 } | 47 } |
48 | 48 |
49 int thread_count = 0; | |
50 do { | 49 do { |
51 if (te32.th32OwnerProcessID == target_pid) { | 50 if (te32.th32OwnerProcessID == target_pid) { |
52 thread_count++; | 51 // We set the thread priority of "Thread1" to a non-default value before |
53 if (thread_count == 2) { | 52 // going to sleep. Dump and blame this thread. For an explanation of |
54 // Nominate this lucky thread as our blamee, and dump it. This will be | 53 // "9", see |
55 // "Thread1" in the child. | 54 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms685100.aspx. |
| 55 if (te32.tpBasePri == 9) { |
56 ScopedKernelHANDLE thread( | 56 ScopedKernelHANDLE thread( |
57 OpenThread(kXPThreadAllAccess, false, te32.th32ThreadID)); | 57 OpenThread(kXPThreadAllAccess, false, te32.th32ThreadID)); |
58 if (!client.DumpAndCrashTargetProcess( | 58 if (!client.DumpAndCrashTargetProcess( |
59 process, thread.get(), 0xdeadbea7)) { | 59 process, thread.get(), 0xdeadbea7)) { |
60 LOG(ERROR) << "DumpAndCrashTargetProcess failed"; | 60 LOG(ERROR) << "DumpAndCrashTargetProcess failed"; |
61 return false; | 61 return false; |
62 } | 62 } |
63 return true; | 63 return true; |
64 } | 64 } |
65 } | 65 } |
66 } while (Thread32Next(thread_snap.get(), &te32)); | 66 } while (Thread32Next(thread_snap.get(), &te32)); |
67 | 67 |
68 return false; | 68 return false; |
69 } | 69 } |
70 | 70 |
71 int CrashOtherProgram(int argc, wchar_t* argv[]) { | 71 int CrashOtherProgram(int argc, wchar_t* argv[]) { |
72 CrashpadClient client; | 72 CrashpadClient client; |
73 | 73 |
74 if (argc == 2 || argc == 3) { | 74 if (argc == 2 || argc == 3) { |
75 if (!client.SetHandlerIPCPipe(argv[1])) { | 75 if (!client.SetHandlerIPCPipe(argv[1])) { |
76 LOG(ERROR) << "SetHandler"; | 76 LOG(ERROR) << "SetHandler"; |
77 return EXIT_FAILURE; | 77 return EXIT_FAILURE; |
78 } | 78 } |
79 } else { | 79 } else { |
80 fprintf(stderr, "Usage: %ls <server_pipe_name> [noexception]\n", argv[0]); | 80 fprintf(stderr, "Usage: %ls <server_pipe_name> [noexception]\n", argv[0]); |
81 return EXIT_FAILURE; | 81 return EXIT_FAILURE; |
82 } | 82 } |
83 | 83 |
84 if (!client.UseHandler()) { | |
85 LOG(ERROR) << "UseHandler"; | |
86 return EXIT_FAILURE; | |
87 } | |
88 | |
89 // Launch another process that hangs. | 84 // Launch another process that hangs. |
90 base::FilePath test_executable = Paths::Executable(); | 85 base::FilePath test_executable = Paths::Executable(); |
91 std::wstring child_test_executable = | 86 std::wstring child_test_executable = |
92 test_executable.DirName().Append(L"hanging_program.exe").value(); | 87 test_executable.DirName().Append(L"hanging_program.exe").value(); |
93 ChildLauncher child(child_test_executable, argv[1]); | 88 ChildLauncher child(child_test_executable, argv[1]); |
94 child.Start(); | 89 child.Start(); |
95 | 90 |
96 // Wait until it's ready. | 91 // Wait until it's ready. |
97 char c; | 92 char c; |
98 if (!LoggingReadFile(child.stdout_read_handle(), &c, sizeof(c)) || c != ' ') { | 93 if (!LoggingReadFile(child.stdout_read_handle(), &c, sizeof(c)) || c != ' ') { |
(...skipping 12 matching lines...) Expand all Loading... |
111 return EXIT_FAILURE; | 106 return EXIT_FAILURE; |
112 } | 107 } |
113 | 108 |
114 } // namespace | 109 } // namespace |
115 } // namespace test | 110 } // namespace test |
116 } // namespace crashpad | 111 } // namespace crashpad |
117 | 112 |
118 int wmain(int argc, wchar_t* argv[]) { | 113 int wmain(int argc, wchar_t* argv[]) { |
119 return crashpad::test::CrashOtherProgram(argc, argv); | 114 return crashpad::test::CrashOtherProgram(argc, argv); |
120 } | 115 } |
OLD | NEW |