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

Unified Diff: tools/win/ShowThreadNames/ShowThreadNames.cc

Issue 2713773002: ShowThreadNames tool to get thread ID/name pairs in a Chrome process (Closed)
Patch Set: Address CR feedback. Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/win/ShowThreadNames/ReadMe.txt ('k') | tools/win/ShowThreadNames/ShowThreadNames.sln » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/win/ShowThreadNames/ShowThreadNames.cc
diff --git a/tools/win/ShowThreadNames/ShowThreadNames.cc b/tools/win/ShowThreadNames/ShowThreadNames.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1627ede5800d8a7e9ee8cce50e73c8be735347ab
--- /dev/null
+++ b/tools/win/ShowThreadNames/ShowThreadNames.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <windows.h>
+
+#include <stdio.h>
+#include <tchar.h>
+#include <tlhelp32.h>
+
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <map>
+#include <sstream>
+#include <string>
+
+// List all thread names in a process specified.
+BOOL ListProcessThreadNames(DWORD dwOwnerPID);
+
+// The GetThreadDescription API is available since Windows 10, version 1607.
+// The reason why this API is binded in this way rather than just using the
+// Windows SDK, is to make it consistent with the bind of SetThreadDescription
+// in Chrome. Binding SetThreadDescription API in Chrome can only be done via
stanisc 2017/02/23 19:19:44 You could just say that this API isn't yet availab
chengx 2017/02/23 20:45:06 Done.
+// the system dll, rather than SDK.
+typedef HRESULT(WINAPI* GETTHREADDESCRIPTION)(HANDLE hThread,
+ PWSTR* threadDescription);
+
+int main(void) {
+ unsigned int processId;
+ std::string user_input;
+ while (true) {
+ std::cout
+ << "\nPlease enter the process Id, or \"quit\" to end the program : ";
+ std::getline(std::cin, user_input);
+ std::cout << std::endl;
+ if (user_input == "quit")
+ break;
+ std::stringstream ss(user_input);
+ if (ss >> processId) {
+ ListProcessThreadNames(processId);
+ } else {
+ std::cout << "input is invalid" << std::endl;
+ }
+ std::cout << std::endl;
+ }
+ return 0;
+}
+
+BOOL ListProcessThreadNames(DWORD dwOwnerPID) {
+ auto get_thread_description_func =
+ reinterpret_cast<GETTHREADDESCRIPTION>(::GetProcAddress(
+ ::GetModuleHandle(L"Kernel32.dll"), "GetThreadDescription"));
+
+ if (!get_thread_description_func) {
+ std::cout << "GetThreadDescription API is not available in current OS"
+ << std::endl;
+ return (FALSE);
+ }
+
+ HANDLE threadSnap = INVALID_HANDLE_VALUE;
stanisc 2017/02/23 19:19:44 How about thread_snapshot?
chengx 2017/02/23 20:45:06 Done.
+ // Take a snapshot of all running threads.
+ threadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ if (threadSnap == INVALID_HANDLE_VALUE)
+ return (FALSE);
+
+ THREADENTRY32 te32;
+ te32.dwSize = sizeof(THREADENTRY32);
+
+ // Retrieve information about the first thread, and exit if unsuccessful.
+ if (!Thread32First(threadSnap, &te32)) {
+ std::cout << "Thread32First() call failed" << std::endl;
+ CloseHandle(threadSnap);
+ return (FALSE);
+ }
+
+ // Walk the thread list of the system, and display ID and name about each
+ // thread associated with the process specified.
+ std::cout << "thread_ID thread_name" << std::endl;
+ std::multimap<std::wstring, DWORD> name_id_map;
+ do {
+ if (te32.th32OwnerProcessID == dwOwnerPID) {
stanisc 2017/02/23 19:19:44 Use chrome code naming convention for this as well
chengx 2017/02/23 20:45:06 Done.
+ HANDLE threadHandle =
+ OpenThread(THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID);
+ if (threadHandle) {
+ PWSTR data;
+ HRESULT hr = get_thread_description_func(threadHandle, &data);
+ if (SUCCEEDED(hr)) {
+ std::wstring data_w(data);
stanisc 2017/02/23 19:19:44 Could you use a more descriptive name such as thre
chengx 2017/02/23 20:45:06 Done.
+ name_id_map.insert(std::make_pair(data_w, te32.th32ThreadID));
+ } else {
+ std::cout << "GetThreadDescription API call failed" << std::endl;
+ }
+ CloseHandle(threadHandle);
+ }
+ }
+ } while (Thread32Next(threadSnap, &te32));
+
+ // Clean up the snapshot object.
+ CloseHandle(threadSnap);
+
+ // Show all thread ID/name pairs.
+ for (auto it = name_id_map.begin(); it != name_id_map.end(); ++it) {
stanisc 2017/02/23 19:19:44 Nit: you could use C++ 11 foreach loop here - for
chengx 2017/02/23 20:45:06 Done.
+ std::cout << it->second << "\t";
+ std::wcout << it->first << std::endl;
+ }
+
+ return (TRUE);
+}
« no previous file with comments | « tools/win/ShowThreadNames/ReadMe.txt ('k') | tools/win/ShowThreadNames/ShowThreadNames.sln » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698