utils: properly collect process name on Windows

Summary:
This allows `edenfsctl debug processfetch` to display what processes triggered
some IO in EdenFS which will be useful to debug rogue processes walking the
entire repo.

Reviewed By: chadaustin

Differential Revision: D23997665

fbshipit-source-id: 7d92755d0068a4b1819eb0c84b30cbdaa24296f7
This commit is contained in:
Xavier Deguillard 2020-10-05 15:44:27 -07:00 committed by Facebook GitHub Bot
parent d8d841ae80
commit 41e1078dd3
2 changed files with 41 additions and 1 deletions

View File

@ -125,7 +125,22 @@ struct TokenHandleTraits {
}
};
/*
* Process Handle traits. nullptr is defined as an invalid one.
*/
struct ProcessHandleTraits {
using Type = HANDLE;
static Type invalidHandleValue() noexcept {
return nullptr;
}
static void close(Type handle) noexcept {
CloseHandle(handle);
}
};
using TokenHandle = HandleBase<TokenHandleTraits>;
using ProcessHandle = HandleBase<ProcessHandleTraits>;
} // namespace eden
} // namespace facebook

View File

@ -10,6 +10,7 @@
#include <optional>
#include <vector>
#include <fmt/format.h>
#include <folly/FileUtil.h>
#include <folly/MapUtil.h>
#include <folly/system/ThreadName.h>
@ -21,6 +22,11 @@
#include <sys/sysctl.h> // @manual
#endif
#ifdef _WIN32
#include "eden/fs/utils/Handle.h"
#include "eden/fs/utils/StringConv.h"
#endif
namespace facebook::eden::detail {
ProcPidCmdLine getProcPidCmdLine(pid_t pid) {
@ -162,7 +168,26 @@ std::string readPidName(pid_t pid) {
return extractCommandLineFromProcArgs(procargs, len).str();
#elif _WIN32
return "<NOT IMPLEMENTED>";
ProcessHandle handle{
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid)};
if (!handle) {
auto err = GetLastError();
return fmt::format(FMT_STRING("<err:{}>"), win32ErrorToString(err));
}
// MAX_PATH on Windows is only 260 characters, but on recent Windows, this
// constant doesn't represent the actual maximum length of a path, since
// there is no exact value for it, and QueryFullProcessImageName doesn't
// appear to be helpful in giving us the actual size of the path, we just
// use a large enough value.
wchar_t path[SHRT_MAX];
DWORD size = SHRT_MAX;
if (QueryFullProcessImageNameW(handle.get(), 0, path, &size) == 0) {
auto err = GetLastError();
return fmt::format(FMT_STRING("<err:{}>"), win32ErrorToString(err));
}
return wideToMultibyteString<std::string>(path);
#else
char target[1024];
const auto fd =