Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit ac5dee5

Browse files
author
Mike McLaughlin
authored
Fix dbgshim's > 1000 module bug (issue #19538) (#19553) (#19570)
Fix dbgshim's > 1000 module bug (issue #19538) Cap cbNeeded on second EnumProcessModules call. Change the allocations to HMODULE to make sure they are aligned properly.
1 parent 7813233 commit ac5dee5

File tree

1 file changed

+60
-10
lines changed

1 file changed

+60
-10
lines changed

src/dlls/dbgshim/dbgshim.cpp

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <pedecoder.h>
2525
#include <getproductversionnumber.h>
2626
#include <dbgenginemetrics.h>
27+
#include <arrayholder.h>
2728

2829
#ifndef FEATURE_PAL
2930
#define PSAPI_VERSION 2
@@ -1052,6 +1053,57 @@ IsCoreClrWithGoodHeader(
10521053
return false;
10531054
}
10541055

1056+
static
1057+
HMODULE*
1058+
EnumProcessModulesInternal(
1059+
HANDLE hProcess,
1060+
DWORD *pCountModules)
1061+
{
1062+
*pCountModules = 0;
1063+
1064+
// Start with 1024 modules
1065+
DWORD cbNeeded = sizeof(HMODULE) * 1024;
1066+
1067+
ArrayHolder<HMODULE> modules = new (nothrow) HMODULE[cbNeeded / sizeof(HMODULE)];
1068+
if (modules == nullptr)
1069+
{
1070+
SetLastError(ERROR_OUTOFMEMORY);
1071+
return nullptr;
1072+
}
1073+
1074+
if(!EnumProcessModules(hProcess, modules, cbNeeded, &cbNeeded))
1075+
{
1076+
return nullptr;
1077+
}
1078+
1079+
// If 1024 isn't enough, try the modules array size returned (cbNeeded)
1080+
if (cbNeeded > (sizeof(HMODULE) * 1024))
1081+
{
1082+
modules = new (nothrow) HMODULE[cbNeeded / sizeof(HMODULE)];
1083+
if (modules == nullptr)
1084+
{
1085+
SetLastError(ERROR_OUTOFMEMORY);
1086+
return nullptr;
1087+
}
1088+
1089+
DWORD cbNeeded2;
1090+
if(!EnumProcessModules(hProcess, modules, cbNeeded, &cbNeeded2))
1091+
{
1092+
return nullptr;
1093+
}
1094+
1095+
// The only way cbNeeded2 could change on the second call is if number of
1096+
// modules loaded by the process changed in the small window between the
1097+
// above EnumProcessModules calls. If this actually happens, then give
1098+
// up on trying to get the whole module list and risk missing the coreclr
1099+
// module.
1100+
cbNeeded = min(cbNeeded, cbNeeded2);
1101+
}
1102+
1103+
*pCountModules = cbNeeded / sizeof(HMODULE);
1104+
return modules.Detach();
1105+
}
1106+
10551107
//-----------------------------------------------------------------------------
10561108
// Public API.
10571109
//
@@ -1089,10 +1141,10 @@ EnumerateCLRs(
10891141
if (NULL == hProcess)
10901142
return E_FAIL;
10911143

1092-
// These shouldn't be freed
1093-
HMODULE modules[1000];
1094-
DWORD cbNeeded;
1095-
if(!EnumProcessModules(hProcess, modules, sizeof(modules), &cbNeeded))
1144+
// The modules in the array returned don't need to be closed
1145+
DWORD countModules;
1146+
ArrayHolder<HMODULE> modules = EnumProcessModulesInternal(hProcess, &countModules);
1147+
if (modules == nullptr)
10961148
{
10971149
return HRESULT_FROM_WIN32(GetLastError());
10981150
}
@@ -1101,7 +1153,6 @@ EnumerateCLRs(
11011153
// count the number of coreclr.dll entries
11021154
//
11031155
DWORD count = 0;
1104-
DWORD countModules = cbNeeded/sizeof(HMODULE);
11051156
for(DWORD i = 0; i < countModules; i++)
11061157
{
11071158
if (IsCoreClrWithGoodHeader(hProcess, modules[i]))
@@ -1268,15 +1319,14 @@ GetRemoteModuleBaseAddress(
12681319
ThrowHR(E_FAIL);
12691320
}
12701321

1271-
// These shouldn't be freed
1272-
HMODULE modules[1000];
1273-
DWORD cbNeeded;
1274-
if(!EnumProcessModules(hProcess, modules, sizeof(modules), &cbNeeded))
1322+
// The modules in the array returned don't need to be closed
1323+
DWORD countModules;
1324+
ArrayHolder<HMODULE> modules = EnumProcessModulesInternal(hProcess, &countModules);
1325+
if (modules == nullptr)
12751326
{
12761327
ThrowHR(HRESULT_FROM_WIN32(GetLastError()));
12771328
}
12781329

1279-
DWORD countModules = min(cbNeeded, sizeof(modules)) / sizeof(HMODULE);
12801330
for(DWORD i = 0; i < countModules; i++)
12811331
{
12821332
WCHAR modulePath[MAX_LONGPATH];

0 commit comments

Comments
 (0)