Bug 1702086 - Part1: Introduce EnumerateProcessModules. r=gerald
This patch introduces `EnumerateProcessModules` to enumerate all loaded modules in the local process so that Gecko profiler and baseprofiler can use it. Differential Revision: https://phabricator.services.mozilla.com/D115252
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "mozilla/glue/WindowsUnicode.h"
|
#include "mozilla/glue/WindowsUnicode.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
#include "mozilla/WindowsEnumProcessModules.h"
|
||||||
#include "mozilla/WindowsVersion.h"
|
#include "mozilla/WindowsVersion.h"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@@ -114,7 +115,7 @@ static bool GetPdbInfo(uintptr_t aStart, std::string& aSignature,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetVersion(wchar_t* dllPath) {
|
static std::string GetVersion(const wchar_t* dllPath) {
|
||||||
DWORD infoSize = GetFileVersionInfoSizeW(dllPath, nullptr);
|
DWORD infoSize = GetFileVersionInfoSizeW(dllPath, nullptr);
|
||||||
if (infoSize == 0) {
|
if (infoSize == 0) {
|
||||||
return {};
|
return {};
|
||||||
@@ -144,42 +145,19 @@ static std::string GetVersion(wchar_t* dllPath) {
|
|||||||
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||||
SharedLibraryInfo sharedLibraryInfo;
|
SharedLibraryInfo sharedLibraryInfo;
|
||||||
|
|
||||||
HANDLE hProcess = GetCurrentProcess();
|
auto addSharedLibraryFromModuleInfo = [&sharedLibraryInfo](
|
||||||
mozilla::UniquePtr<HMODULE[]> hMods;
|
const wchar_t* aModulePath,
|
||||||
size_t modulesNum = 0;
|
HMODULE aModule) {
|
||||||
if (hProcess != NULL) {
|
|
||||||
DWORD modulesSize;
|
|
||||||
if (!EnumProcessModules(hProcess, nullptr, 0, &modulesSize)) {
|
|
||||||
return sharedLibraryInfo;
|
|
||||||
}
|
|
||||||
modulesNum = modulesSize / sizeof(HMODULE);
|
|
||||||
hMods = mozilla::MakeUnique<HMODULE[]>(modulesNum);
|
|
||||||
if (!EnumProcessModules(hProcess, hMods.get(), modulesNum * sizeof(HMODULE),
|
|
||||||
&modulesSize)) {
|
|
||||||
return sharedLibraryInfo;
|
|
||||||
}
|
|
||||||
// The list may have shrunk between calls
|
|
||||||
if (modulesSize / sizeof(HMODULE) < modulesNum) {
|
|
||||||
modulesNum = modulesSize / sizeof(HMODULE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < modulesNum; i++) {
|
|
||||||
wchar_t modulePath[MAX_PATH + 1];
|
|
||||||
if (!GetModuleFileNameExW(hProcess, hMods[i], modulePath,
|
|
||||||
std::size(modulePath))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mozilla::UniquePtr<char[]> utf8ModulePath(
|
mozilla::UniquePtr<char[]> utf8ModulePath(
|
||||||
mozilla::glue::WideToUTF8(modulePath));
|
mozilla::glue::WideToUTF8(aModulePath));
|
||||||
if (!utf8ModulePath) {
|
if (!utf8ModulePath) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULEINFO module = {0};
|
MODULEINFO module = {0};
|
||||||
if (!GetModuleInformation(hProcess, hMods[i], &module,
|
if (!GetModuleInformation(mozilla::nt::kCurrentProcess, aModule, &module,
|
||||||
sizeof(MODULEINFO))) {
|
sizeof(MODULEINFO))) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string modulePathStr(utf8ModulePath.get());
|
std::string modulePathStr(utf8ModulePath.get());
|
||||||
@@ -220,7 +198,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
|||||||
"000000000000000000000000000000000", moduleNameStr,
|
"000000000000000000000000000000000", moduleNameStr,
|
||||||
modulePathStr, pdbNameStr, pdbNameStr, "", "");
|
modulePathStr, pdbNameStr, pdbNameStr, "", "");
|
||||||
sharedLibraryInfo.AddSharedLibrary(shlib);
|
sharedLibraryInfo.AddSharedLibrary(shlib);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
#endif // !defined(_M_ARM64)
|
#endif // !defined(_M_ARM64)
|
||||||
|
|
||||||
@@ -238,7 +216,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
|||||||
// can read the memory mapped at the base address before we can safely
|
// can read the memory mapped at the base address before we can safely
|
||||||
// proceed to actually access those pages.
|
// proceed to actually access those pages.
|
||||||
HMODULE handleLock =
|
HMODULE handleLock =
|
||||||
LoadLibraryExW(modulePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
LoadLibraryExW(aModulePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||||
MEMORY_BASIC_INFORMATION vmemInfo = {0};
|
MEMORY_BASIC_INFORMATION vmemInfo = {0};
|
||||||
std::string pdbSig;
|
std::string pdbSig;
|
||||||
uint32_t pdbAge;
|
uint32_t pdbAge;
|
||||||
@@ -264,12 +242,13 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
|||||||
(uintptr_t)module.lpBaseOfDll + module.SizeOfImage,
|
(uintptr_t)module.lpBaseOfDll + module.SizeOfImage,
|
||||||
0, // DLLs are always mapped at offset 0 on Windows
|
0, // DLLs are always mapped at offset 0 on Windows
|
||||||
breakpadId, moduleNameStr, modulePathStr, pdbNameStr,
|
breakpadId, moduleNameStr, modulePathStr, pdbNameStr,
|
||||||
pdbPathStr, GetVersion(modulePath), "");
|
pdbPathStr, GetVersion(aModulePath), "");
|
||||||
sharedLibraryInfo.AddSharedLibrary(shlib);
|
sharedLibraryInfo.AddSharedLibrary(shlib);
|
||||||
|
|
||||||
FreeLibrary(handleLock); // ok to free null handles
|
FreeLibrary(handleLock); // ok to free null handles
|
||||||
}
|
};
|
||||||
|
|
||||||
|
mozilla::EnumerateProcessModules(addSharedLibraryFromModuleInfo);
|
||||||
return sharedLibraryInfo;
|
return sharedLibraryInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
61
mozglue/misc/WindowsEnumProcessModules.h
Normal file
61
mozglue/misc/WindowsEnumProcessModules.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_WindowsEnumProcessModules_h
|
||||||
|
#define mozilla_WindowsEnumProcessModules_h
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <psapi.h>
|
||||||
|
|
||||||
|
#include "mozilla/FunctionRef.h"
|
||||||
|
#include "mozilla/NativeNt.h"
|
||||||
|
#include "mozilla/UniquePtr.h"
|
||||||
|
#include "mozilla/WinHeaderOnlyUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
// Why don't we use CreateToolhelp32Snapshot instead of EnumProcessModules?
|
||||||
|
// CreateToolhelp32Snapshot gets the ANSI versions of module path strings
|
||||||
|
// via ntdll!RtlQueryProcessDebugInformation and stores them into a snapshot.
|
||||||
|
// Module32FirstW/Module32NextW re-converts ANSI into Unicode, but it cannot
|
||||||
|
// restore lost information. This means we still need GetModuleFileNameEx
|
||||||
|
// even when we use CreateToolhelp32Snapshot, but EnumProcessModules is faster.
|
||||||
|
inline bool EnumerateProcessModules(
|
||||||
|
const FunctionRef<void(const wchar_t*, HMODULE)>& aCallback) {
|
||||||
|
DWORD modulesSize;
|
||||||
|
if (!::EnumProcessModules(nt::kCurrentProcess, nullptr, 0, &modulesSize)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD modulesNum = modulesSize / sizeof(HMODULE);
|
||||||
|
UniquePtr<HMODULE[]> modules = MakeUnique<HMODULE[]>(modulesNum);
|
||||||
|
if (!::EnumProcessModules(nt::kCurrentProcess, modules.get(),
|
||||||
|
modulesNum * sizeof(HMODULE), &modulesSize)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The list may have shrunk between calls
|
||||||
|
if (modulesSize / sizeof(HMODULE) < modulesNum) {
|
||||||
|
modulesNum = modulesSize / sizeof(HMODULE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < modulesNum; ++i) {
|
||||||
|
UniquePtr<wchar_t[]> modulePath = GetFullModulePath(modules[i]);
|
||||||
|
if (!modulePath) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Please note that modules[i] could be invalid if the module
|
||||||
|
// was unloaded after GetFullModulePath succeeded.
|
||||||
|
aCallback(modulePath.get(), modules[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_WindowsEnumProcessModules_h
|
||||||
@@ -59,6 +59,7 @@ if CONFIG["OS_ARCH"] == "WINNT":
|
|||||||
"DynamicallyLinkedFunctionPtr.h",
|
"DynamicallyLinkedFunctionPtr.h",
|
||||||
"ImportDir.h",
|
"ImportDir.h",
|
||||||
"NativeNt.h",
|
"NativeNt.h",
|
||||||
|
"WindowsEnumProcessModules.h",
|
||||||
"WindowsMapRemoteView.h",
|
"WindowsMapRemoteView.h",
|
||||||
"WindowsProcessMitigations.h",
|
"WindowsProcessMitigations.h",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -8,9 +8,11 @@
|
|||||||
#include "mozilla/NativeNt.h"
|
#include "mozilla/NativeNt.h"
|
||||||
#include "mozilla/ThreadLocal.h"
|
#include "mozilla/ThreadLocal.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
|
#include "mozilla/WindowsEnumProcessModules.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
const wchar_t kNormal[] = L"Foo.dll";
|
const wchar_t kNormal[] = L"Foo.dll";
|
||||||
const wchar_t kHex12[] = L"Foo.ABCDEF012345.dll";
|
const wchar_t kHex12[] = L"Foo.ABCDEF012345.dll";
|
||||||
@@ -65,6 +67,127 @@ bool TestVirtualQuery(HANDLE aProcess, LPCVOID aAddress) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This class copies the self executable file to the %temp%\<outer>\<inner>
|
||||||
|
// folder. The length of its path is longer than MAX_PATH.
|
||||||
|
class LongNameModule {
|
||||||
|
wchar_t mOuterDirBuffer[MAX_PATH];
|
||||||
|
wchar_t mInnerDirBuffer[MAX_PATH * 2];
|
||||||
|
wchar_t mTargetFileBuffer[MAX_PATH * 2];
|
||||||
|
|
||||||
|
const wchar_t* mOuterDir;
|
||||||
|
const wchar_t* mInnerDir;
|
||||||
|
const wchar_t* mTargetFile;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LongNameModule(const wchar_t* aNewLeafNameAfterCopy)
|
||||||
|
: mOuterDir(nullptr), mInnerDir(nullptr), mTargetFile(nullptr) {
|
||||||
|
const wchar_t kFolderName160Chars[] =
|
||||||
|
L"0123456789ABCDEF0123456789ABCDEF"
|
||||||
|
L"0123456789ABCDEF0123456789ABCDEF"
|
||||||
|
L"0123456789ABCDEF0123456789ABCDEF"
|
||||||
|
L"0123456789ABCDEF0123456789ABCDEF"
|
||||||
|
L"0123456789ABCDEF0123456789ABCDEF";
|
||||||
|
UniquePtr<wchar_t[]> thisExe = GetFullBinaryPath();
|
||||||
|
if (!thisExe) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the buffer is too small, GetTempPathW returns the required
|
||||||
|
// length including a null character, while on a successful case
|
||||||
|
// it returns the number of copied characters which does not include
|
||||||
|
// a null character. This means len == MAX_PATH should never happen
|
||||||
|
// and len > MAX_PATH means GetTempPathW failed.
|
||||||
|
wchar_t tempDir[MAX_PATH];
|
||||||
|
DWORD len = ::GetTempPathW(MAX_PATH, tempDir);
|
||||||
|
if (!len || len >= MAX_PATH) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(::StringCbPrintfW(mOuterDirBuffer, sizeof(mOuterDirBuffer),
|
||||||
|
L"\\\\?\\%s%s", tempDir,
|
||||||
|
kFolderName160Chars)) ||
|
||||||
|
!::CreateDirectoryW(mOuterDirBuffer, nullptr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mOuterDir = mOuterDirBuffer;
|
||||||
|
|
||||||
|
if (FAILED(::StringCbPrintfW(mInnerDirBuffer, sizeof(mInnerDirBuffer),
|
||||||
|
L"\\\\?\\%s%s\\%s", tempDir,
|
||||||
|
kFolderName160Chars, kFolderName160Chars)) ||
|
||||||
|
!::CreateDirectoryW(mInnerDirBuffer, nullptr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mInnerDir = mInnerDirBuffer;
|
||||||
|
|
||||||
|
if (FAILED(::StringCbPrintfW(mTargetFileBuffer, sizeof(mTargetFileBuffer),
|
||||||
|
L"\\\\?\\%s%s\\%s\\%s", tempDir,
|
||||||
|
kFolderName160Chars, kFolderName160Chars,
|
||||||
|
aNewLeafNameAfterCopy)) ||
|
||||||
|
!::CopyFileW(thisExe.get(), mTargetFileBuffer,
|
||||||
|
/*bFailIfExists*/ TRUE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mTargetFile = mTargetFileBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
~LongNameModule() {
|
||||||
|
if (mTargetFile) {
|
||||||
|
::DeleteFileW(mTargetFile);
|
||||||
|
}
|
||||||
|
if (mInnerDir) {
|
||||||
|
::RemoveDirectoryW(mInnerDir);
|
||||||
|
}
|
||||||
|
if (mOuterDir) {
|
||||||
|
::RemoveDirectoryW(mOuterDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const wchar_t*() const { return mTargetFile; }
|
||||||
|
};
|
||||||
|
|
||||||
|
bool TestModuleInfo() {
|
||||||
|
UNICODE_STRING newLeafName;
|
||||||
|
::RtlInitUnicodeString(&newLeafName,
|
||||||
|
L"\u672D\u5E4C\u5473\u564C.\u30E9\u30FC\u30E1\u30F3");
|
||||||
|
|
||||||
|
LongNameModule longNameModule(newLeafName.Buffer);
|
||||||
|
if (!longNameModule) {
|
||||||
|
printf(
|
||||||
|
"TEST-FAILED | NativeNt | "
|
||||||
|
"Failed to copy the executable to a long directory path\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
nsModuleHandle module(::LoadLibraryW(longNameModule));
|
||||||
|
|
||||||
|
bool detectedTarget = false;
|
||||||
|
auto moduleCallback = [&](const wchar_t* aModulePath, HMODULE aModule) {
|
||||||
|
UNICODE_STRING modulePath, moduleName;
|
||||||
|
::RtlInitUnicodeString(&modulePath, aModulePath);
|
||||||
|
GetLeafName(&moduleName, &modulePath);
|
||||||
|
if (::RtlEqualUnicodeString(&moduleName, &newLeafName,
|
||||||
|
/*aCaseInsensitive*/ TRUE)) {
|
||||||
|
detectedTarget = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!mozilla::EnumerateProcessModules(moduleCallback)) {
|
||||||
|
printf("TEST-FAILED | NativeNt | EnumerateProcessModules failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!detectedTarget) {
|
||||||
|
printf(
|
||||||
|
"TEST-FAILED | NativeNt | "
|
||||||
|
"EnumerateProcessModules missed the target file\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
LauncherResult<HMODULE> GetModuleHandleFromLeafName(const wchar_t* aName) {
|
LauncherResult<HMODULE> GetModuleHandleFromLeafName(const wchar_t* aName) {
|
||||||
UNICODE_STRING name;
|
UNICODE_STRING name;
|
||||||
::RtlInitUnicodeString(&name, aName);
|
::RtlInitUnicodeString(&name, aName);
|
||||||
@@ -290,6 +413,10 @@ int wmain(int argc, wchar_t* argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!TestModuleInfo()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
printf("TEST-PASS | NativeNt | All tests ran successfully\n");
|
printf("TEST-PASS | NativeNt | All tests ran successfully\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "nsWindowsHelpers.h"
|
#include "nsWindowsHelpers.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
#include "mozilla/WindowsEnumProcessModules.h"
|
||||||
#include "mozilla/WindowsProcessMitigations.h"
|
#include "mozilla/WindowsProcessMitigations.h"
|
||||||
#include "mozilla/WindowsVersion.h"
|
#include "mozilla/WindowsVersion.h"
|
||||||
#include "nsNativeCharsetUtils.h"
|
#include "nsNativeCharsetUtils.h"
|
||||||
@@ -79,7 +80,7 @@ static bool GetPdbInfo(uintptr_t aStart, nsID& aSignature, uint32_t& aAge,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsCString GetVersion(WCHAR* dllPath) {
|
static nsCString GetVersion(const WCHAR* dllPath) {
|
||||||
DWORD infoSize = GetFileVersionInfoSizeW(dllPath, nullptr);
|
DWORD infoSize = GetFileVersionInfoSizeW(dllPath, nullptr);
|
||||||
if (infoSize == 0) {
|
if (infoSize == 0) {
|
||||||
return ""_ns;
|
return ""_ns;
|
||||||
@@ -110,40 +111,16 @@ static nsCString GetVersion(WCHAR* dllPath) {
|
|||||||
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||||
SharedLibraryInfo sharedLibraryInfo;
|
SharedLibraryInfo sharedLibraryInfo;
|
||||||
|
|
||||||
HANDLE hProcess = GetCurrentProcess();
|
auto addSharedLibraryFromModuleInfo = [&sharedLibraryInfo](
|
||||||
mozilla::UniquePtr<HMODULE[]> hMods;
|
const wchar_t* aModulePath,
|
||||||
size_t modulesNum = 0;
|
HMODULE aModule) {
|
||||||
if (hProcess != NULL) {
|
|
||||||
DWORD modulesSize;
|
|
||||||
if (!EnumProcessModules(hProcess, nullptr, 0, &modulesSize)) {
|
|
||||||
return sharedLibraryInfo;
|
|
||||||
}
|
|
||||||
modulesNum = modulesSize / sizeof(HMODULE);
|
|
||||||
hMods = mozilla::MakeUnique<HMODULE[]>(modulesNum);
|
|
||||||
if (!EnumProcessModules(hProcess, hMods.get(), modulesNum * sizeof(HMODULE),
|
|
||||||
&modulesSize)) {
|
|
||||||
return sharedLibraryInfo;
|
|
||||||
}
|
|
||||||
// The list may have shrunk between calls
|
|
||||||
if (modulesSize / sizeof(HMODULE) < modulesNum) {
|
|
||||||
modulesNum = modulesSize / sizeof(HMODULE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < modulesNum; i++) {
|
|
||||||
WCHAR modulePath[MAX_PATH + 1];
|
|
||||||
if (!GetModuleFileNameEx(hProcess, hMods[i], modulePath,
|
|
||||||
sizeof(modulePath) / sizeof(WCHAR))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULEINFO module = {0};
|
MODULEINFO module = {0};
|
||||||
if (!GetModuleInformation(hProcess, hMods[i], &module,
|
if (!GetModuleInformation(mozilla::nt::kCurrentProcess, aModule, &module,
|
||||||
sizeof(MODULEINFO))) {
|
sizeof(MODULEINFO))) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString modulePathStr(modulePath);
|
nsAutoString modulePathStr(aModulePath);
|
||||||
nsAutoString moduleNameStr = modulePathStr;
|
nsAutoString moduleNameStr = modulePathStr;
|
||||||
int32_t pos = moduleNameStr.RFindCharInSet(u"\\/");
|
int32_t pos = moduleNameStr.RFindCharInSet(u"\\/");
|
||||||
if (pos != kNotFound) {
|
if (pos != kNotFound) {
|
||||||
@@ -177,7 +154,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
|||||||
"000000000000000000000000000000000"_ns, moduleNameStr,
|
"000000000000000000000000000000000"_ns, moduleNameStr,
|
||||||
modulePathStr, pdbNameStr, pdbNameStr, ""_ns, "");
|
modulePathStr, pdbNameStr, pdbNameStr, ""_ns, "");
|
||||||
sharedLibraryInfo.AddSharedLibrary(shlib);
|
sharedLibraryInfo.AddSharedLibrary(shlib);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
#endif // !defined(_M_ARM64)
|
#endif // !defined(_M_ARM64)
|
||||||
|
|
||||||
@@ -199,7 +176,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
|||||||
// can read the memory mapped at the base address before we can safely
|
// can read the memory mapped at the base address before we can safely
|
||||||
// proceed to actually access those pages.
|
// proceed to actually access those pages.
|
||||||
HMODULE handleLock =
|
HMODULE handleLock =
|
||||||
LoadLibraryEx(modulePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
LoadLibraryEx(aModulePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||||
MEMORY_BASIC_INFORMATION vmemInfo = {0};
|
MEMORY_BASIC_INFORMATION vmemInfo = {0};
|
||||||
nsID pdbSig;
|
nsID pdbSig;
|
||||||
uint32_t pdbAge;
|
uint32_t pdbAge;
|
||||||
@@ -233,12 +210,13 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
|||||||
(uintptr_t)module.lpBaseOfDll + module.SizeOfImage,
|
(uintptr_t)module.lpBaseOfDll + module.SizeOfImage,
|
||||||
0, // DLLs are always mapped at offset 0 on Windows
|
0, // DLLs are always mapped at offset 0 on Windows
|
||||||
breakpadId, moduleNameStr, modulePathStr, pdbNameStr,
|
breakpadId, moduleNameStr, modulePathStr, pdbNameStr,
|
||||||
pdbPathStr, GetVersion(modulePath), "");
|
pdbPathStr, GetVersion(aModulePath), "");
|
||||||
sharedLibraryInfo.AddSharedLibrary(shlib);
|
sharedLibraryInfo.AddSharedLibrary(shlib);
|
||||||
|
|
||||||
FreeLibrary(handleLock); // ok to free null handles
|
FreeLibrary(handleLock); // ok to free null handles
|
||||||
}
|
};
|
||||||
|
|
||||||
|
mozilla::EnumerateProcessModules(addSharedLibraryFromModuleInfo);
|
||||||
return sharedLibraryInfo;
|
return sharedLibraryInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user