[Lldb-commits] [lldb] r212510 - Implment "platform process list" for Windows.
Zachary Turner
zturner at google.com
Mon Jul 7 21:52:15 PDT 2014
Author: zturner
Date: Mon Jul 7 23:52:15 2014
New Revision: 212510
URL: http://llvm.org/viewvc/llvm-project?rev=212510&view=rev
Log:
Implment "platform process list" for Windows.
This patch implements basic functionality of the "platform process
list" command for Windows. Currently this has the following
limitations.
* Certain types of filtering are not enabled (e.g. filtering by
architecture with -a), although most filters work.
* The username of the process is not yet obtained.
* Using -v to list verbose information generates an error.
* The architecture column displays the entire triple, leading to
misaligned formatting of the printed table.
Reviewed by: Greg Clayton
Differential Revision: http://reviews.llvm.org/D4413
Added:
lldb/trunk/include/lldb/Host/windows/AutoHandle.h
Modified:
lldb/trunk/source/Host/common/Host.cpp
lldb/trunk/source/Host/windows/Host.cpp
Added: lldb/trunk/include/lldb/Host/windows/AutoHandle.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/windows/AutoHandle.h?rev=212510&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/windows/AutoHandle.h (added)
+++ lldb/trunk/include/lldb/Host/windows/AutoHandle.h Mon Jul 7 23:52:15 2014
@@ -0,0 +1,40 @@
+//===-- AutoHandle.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_lldb_Host_windows_AutoHandle_h_
+#define LLDB_lldb_Host_windows_AutoHandle_h_
+
+namespace lldb_private {
+
+class AutoHandle {
+public:
+ AutoHandle(HANDLE handle, HANDLE invalid_value = INVALID_HANDLE_VALUE)
+ : m_handle(handle)
+ , m_invalid_value(invalid_value)
+ {
+ }
+
+ ~AutoHandle()
+ {
+ if (m_handle != m_invalid_value)
+ ::CloseHandle(m_handle);
+ }
+
+ bool IsValid() const { return m_handle != m_invalid_value; }
+
+ HANDLE get() const { return m_handle; }
+private:
+ HANDLE m_handle;
+ HANDLE m_invalid_value;
+};
+
+}
+
+#endif
+
Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=212510&r1=212509&r2=212510&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Mon Jul 7 23:52:15 2014
@@ -1443,7 +1443,8 @@ Host::GetOSKernelDescription (std::strin
}
#endif
-#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__)
+#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) \
+ && !defined(__linux__) && !defined(_WIN32)
uint32_t
Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
{
Modified: lldb/trunk/source/Host/windows/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/Host.cpp?rev=212510&r1=212509&r2=212510&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/Host.cpp (original)
+++ lldb/trunk/source/Host/windows/Host.cpp Mon Jul 7 23:52:15 2014
@@ -10,6 +10,7 @@
// C Includes
#include <stdio.h>
#include "lldb/Host/windows/windows.h"
+#include "lldb/Host/windows/AutoHandle.h"
// C++ Includes
// Other libraries and framework includes
@@ -21,10 +22,80 @@
#include "lldb/Host/Host.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/StreamFile.h"
+
+// Windows includes
+#include <TlHelp32.h>
using namespace lldb;
using namespace lldb_private;
+namespace
+{
+ bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple)
+ {
+ // Open the PE File as a binary file, and parse just enough information to determine the
+ // machine type.
+ File imageBinary(
+ executable.GetPath().c_str(),
+ File::eOpenOptionRead,
+ lldb::eFilePermissionsUserRead);
+ imageBinary.SeekFromStart(0x3c);
+ int32_t peOffset = 0;
+ uint32_t peHead = 0;
+ uint16_t machineType = 0;
+ size_t readSize = sizeof(peOffset);
+ imageBinary.Read(&peOffset, readSize);
+ imageBinary.SeekFromStart(peOffset);
+ imageBinary.Read(&peHead, readSize);
+ if (peHead != 0x00004550) // "PE\0\0", little-endian
+ return false; // Error: Can't find PE header
+ readSize = 2;
+ imageBinary.Read(&machineType, readSize);
+ triple.setVendor(llvm::Triple::PC);
+ triple.setOS(llvm::Triple::Win32);
+ triple.setArch(llvm::Triple::UnknownArch);
+ if (machineType == 0x8664)
+ triple.setArch(llvm::Triple::x86_64);
+ else if (machineType == 0x14c)
+ triple.setArch(llvm::Triple::x86);
+
+ return true;
+ }
+
+ bool GetExecutableForProcess(const AutoHandle &handle, std::string &path)
+ {
+ // Get the process image path. MAX_PATH isn't long enough, paths can actually be up to 32KB.
+ std::vector<char> buffer(32768);
+ DWORD dwSize = buffer.size();
+ if (!::QueryFullProcessImageNameA(handle.get(), 0, &buffer[0], &dwSize))
+ return false;
+ path.assign(&buffer[0]);
+ return true;
+ }
+
+ void GetProcessExecutableAndTriple(const AutoHandle &handle, ProcessInstanceInfo &process)
+ {
+ // We may not have permissions to read the path from the process. So start off by
+ // setting the executable file to whatever Toolhelp32 gives us, and then try to
+ // enhance this with more detailed information, but fail gracefully.
+ std::string executable;
+ llvm::Triple triple;
+ triple.setVendor(llvm::Triple::PC);
+ triple.setOS(llvm::Triple::Win32);
+ triple.setArch(llvm::Triple::UnknownArch);
+ if (GetExecutableForProcess(handle, executable))
+ {
+ FileSpec executableFile(executable.c_str(), false);
+ process.SetExecutableFile(executableFile, true);
+ GetTripleForProcess(executableFile, triple);
+ }
+ process.SetArchitecture(ArchSpec(triple));
+
+ // TODO(zturner): Add the ability to get the process user name.
+ }
+}
+
bool
Host::GetOSVersion(uint32_t &major,
uint32_t &minor,
@@ -210,33 +281,84 @@ Host::GetUserName (uint32_t uid, std::st
const char *
Host::GetGroupName (uint32_t gid, std::string &group_name)
{
+ llvm_unreachable("Windows does not support group name");
return NULL;
}
uint32_t
Host::GetUserID ()
{
- return 0;
+ llvm_unreachable("Windows does not support uid");
}
uint32_t
Host::GetGroupID ()
{
+ llvm_unreachable("Windows does not support gid");
return 0;
}
uint32_t
Host::GetEffectiveUserID ()
{
+ llvm_unreachable("Windows does not support euid");
return 0;
}
uint32_t
Host::GetEffectiveGroupID ()
{
+ llvm_unreachable("Windows does not support egid");
return 0;
}
+uint32_t
+Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
+{
+ process_infos.Clear();
+
+ AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
+ if (!snapshot.IsValid())
+ return 0;
+
+ PROCESSENTRY32 pe = {0};
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ if (Process32First(snapshot.get(), &pe))
+ {
+ do
+ {
+ AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID), nullptr);
+
+ ProcessInstanceInfo process;
+ process.SetExecutableFile(FileSpec(pe.szExeFile, false), true);
+ process.SetProcessID(pe.th32ProcessID);
+ process.SetParentProcessID(pe.th32ParentProcessID);
+ GetProcessExecutableAndTriple(handle, process);
+
+ if (match_info.MatchAllProcesses() || match_info.Matches(process))
+ process_infos.Append(process);
+ } while (Process32Next(snapshot.get(), &pe));
+ }
+ return process_infos.GetSize();
+}
+
+bool
+Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
+{
+ process_info.Clear();
+
+ AutoHandle handle(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid),
+ nullptr);
+ if (!handle.IsValid())
+ return false;
+
+ process_info.SetProcessID(pid);
+ GetProcessExecutableAndTriple(handle, process_info);
+
+ // Need to read the PEB to get parent process and command line arguments.
+ return true;
+}
+
lldb::thread_t
Host::StartMonitoringChildProcess
(
More information about the lldb-commits
mailing list