Skip to content

Commit 805be36

Browse files
committed
Add clrconfig -enumScheme command to change clrma module load default behavior
1 parent 40e3628 commit 805be36

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

src/SOS/SOS.Extensions/Clrma/ClrmaServiceWrapper.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,21 @@ public ClrmaServiceWrapper(ITarget target, IServiceProvider serviceProvider, Ser
3535
builder.AddMethod(new GetThreadDelegate(GetThread));
3636
builder.AddMethod(new GetExceptionDelegate(GetException));
3737
builder.AddMethod(new GetObjectInspectionDelegate(GetObjectInspection));
38+
builder.AddMethod(new SetModuleEnumerationPolicyDelegate((self, moduleEnumerationPolicy) =>
39+
{
40+
if (moduleEnumerationPolicy < 0 || moduleEnumerationPolicy > (int)ModuleEnumerationScheme.All)
41+
{
42+
return HResult.E_INVALIDARG;
43+
}
44+
ModuleEnumerationScheme = (ModuleEnumerationScheme)moduleEnumerationPolicy;
45+
return HResult.S_OK;
46+
}));
3847
builder.Complete();
3948
// Since this wrapper is only created through a ServiceWrapper factory, no AddRef() is needed.
4049
}
4150

51+
public ModuleEnumerationScheme ModuleEnumerationScheme { get; private set; } = ModuleEnumerationScheme.None;
52+
4253
protected override void Destroy()
4354
{
4455
Trace.TraceInformation("ClrmaServiceWrapper.Destroy");
@@ -110,7 +121,7 @@ private ICrashInfoService CrashInfoService
110121
get
111122
{
112123
_crashInfoService ??= _serviceProvider.GetService<ICrashInfoService>(); // Use the default exception-based mechanism for obtaining crash info service
113-
_crashInfoService ??= _serviceProvider.GetService<ICrashInfoModuleService>()?.Create(DefaultModuleEnumerationScheme); // if the above fails, try to create a crash info service from the modules
124+
_crashInfoService ??= _serviceProvider.GetService<ICrashInfoModuleService>()?.Create(ModuleEnumerationScheme); // if the above fails, try to create a crash info service from the modules
114125
return _crashInfoService;
115126
}
116127
}
@@ -141,6 +152,11 @@ private delegate int GetObjectInspectionDelegate(
141152
[In] IntPtr self,
142153
[Out] out IntPtr objectInspection);
143154

155+
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
156+
private delegate int SetModuleEnumerationPolicyDelegate(
157+
[In] IntPtr self,
158+
[In] uint moduleEnumerationPolicy);
159+
144160
#endregion
145161
}
146162
}

src/SOS/Strike/clrma/clrma.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ HRESULT CLRMAReleaseInstance();
99

1010
ICLRManagedAnalysis* g_managedAnalysis = nullptr;
1111

12-
int g_clrmaGlobalFlags = ClrmaGlobalFlags::LoggingEnabled | ClrmaGlobalFlags::DacClrmaEnabled | ClrmaGlobalFlags::ManagedClrmaEnabled;
12+
int g_clrmaGlobalFlags = ClrmaGlobalFlags::LoggingEnabled | ClrmaGlobalFlags::DacClrmaEnabled | ClrmaGlobalFlags::ManagedClrmaEnabled | ClrmaGlobalFlags::ModuleEnumeration_EntryPointAndDllModule;
1313

1414
//
1515
// Exports
@@ -63,6 +63,7 @@ DECLARE_API(clrmaconfig)
6363
BOOL bDacClrma = FALSE;
6464
BOOL bManagedClrma = FALSE;
6565
BOOL bLogging = FALSE;
66+
SIZE_T moduleEnumerationScheme = -1; // None=0, EntryPointModule=1, EntryPointAndEntryPointDllModule=2, AllModules=3
6667

6768
CMDOption option[] =
6869
{ // name, vptr, type, hasValue
@@ -71,6 +72,7 @@ DECLARE_API(clrmaconfig)
7172
{"-dac", &bDacClrma, COBOOL, FALSE},
7273
{"-managed", &bManagedClrma, COBOOL, FALSE},
7374
{"-logging", &bLogging, COBOOL, FALSE},
75+
{"-enumScheme", &moduleEnumerationScheme, COSIZE_T, TRUE},
7476
};
7577

7678
if (!GetCMDOption(args, option, ARRAY_SIZE(option), NULL, 0, NULL))
@@ -107,11 +109,32 @@ DECLARE_API(clrmaconfig)
107109
{
108110
g_clrmaGlobalFlags &= ~ClrmaGlobalFlags::LoggingEnabled;
109111
}
112+
if (moduleEnumerationScheme != 0)
113+
{
114+
g_clrmaGlobalFlags &= ~(ClrmaGlobalFlags::ModuleEnumeration_EntryPointModule |
115+
ClrmaGlobalFlags::ModuleEnumeration_EntryPointAndDllModule |
116+
ClrmaGlobalFlags::ModuleEnumeration_AllModules);
117+
}
118+
}
119+
120+
if (moduleEnumerationScheme != -1)
121+
{
122+
g_clrmaGlobalFlags &= ~(ClrmaGlobalFlags::ModuleEnumeration_EntryPointModule |
123+
ClrmaGlobalFlags::ModuleEnumeration_EntryPointAndDllModule |
124+
ClrmaGlobalFlags::ModuleEnumeration_AllModules);
125+
g_clrmaGlobalFlags |= moduleEnumerationScheme == 1 ? ClrmaGlobalFlags::ModuleEnumeration_EntryPointModule :
126+
moduleEnumerationScheme == 2 ? ClrmaGlobalFlags::ModuleEnumeration_EntryPointAndDllModule :
127+
moduleEnumerationScheme == 3 ? ClrmaGlobalFlags::ModuleEnumeration_AllModules :
128+
0;
110129
}
111130

112131
ExtOut("CLRMA logging: %s\n", (g_clrmaGlobalFlags & ClrmaGlobalFlags::LoggingEnabled) ? "enabled (disable with '-disable -logging')" : "disabled (enable with '-enable -logging')");
113132
ExtOut("CLRMA direct DAC support: %s\n", (g_clrmaGlobalFlags & ClrmaGlobalFlags::DacClrmaEnabled) ? "enabled (disable with '-disable -dac')" : "disabled (enable with '-enable -dac')");
114133
ExtOut("CLRMA managed support: %s\n", (g_clrmaGlobalFlags & ClrmaGlobalFlags::ManagedClrmaEnabled) ? "enabled (disable with '-disable -managed')" : "disabled (enable with '-enable -managed')");
134+
ExtOut("CLRMA module enumeration: %s\n", (g_clrmaGlobalFlags & ClrmaGlobalFlags::ModuleEnumeration_EntryPointModule) ? "Search for crashinfo on EntryPoint module (-enumScheme 1)" :
135+
(g_clrmaGlobalFlags & ClrmaGlobalFlags::ModuleEnumeration_EntryPointAndDllModule) ? "Search for crash info on both EntryPoint and DLL with same name (-enumScheme 2)" :
136+
(g_clrmaGlobalFlags & ClrmaGlobalFlags::ModuleEnumeration_AllModules) ? "Search for crash info on all modules (-enumScheme 3)" :
137+
"Only read crashinfo from Exception if present (use -enumScheme 0)");
115138

116139
return Status;
117140
}

src/SOS/Strike/clrma/managedanalysis.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ ClrmaManagedAnalysis::AssociateClient(
241241
ReleaseHolder<ICLRMAService> clrmaService;
242242
if (SUCCEEDED(hr = target->GetService(__uuidof(ICLRMAService), (void**)&clrmaService)))
243243
{
244+
TraceInformation("AssociateClient got managed CLRMA service\n");
245+
clrmaService->SetModuleEnumerationPolicy(g_clrmaGlobalFlags & ClrmaGlobalFlags::ModuleEnumeration_EntryPointModule ? 1 :
246+
g_clrmaGlobalFlags & ClrmaGlobalFlags::ModuleEnumeration_EntryPointAndDllModule ? 2 :
247+
g_clrmaGlobalFlags & ClrmaGlobalFlags::ModuleEnumeration_AllModules ? 3 : 0);
244248
if (SUCCEEDED(hr = clrmaService->AssociateClient(m_debugClient)))
245249
{
246250
m_clrmaService = clrmaService.Detach();

src/SOS/Strike/clrma/managedanalysis.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ enum ClrmaGlobalFlags
2727
LoggingEnabled = 0x01, // CLRMA logging enabled
2828
DacClrmaEnabled = 0x02, // Direct DAC CLRMA code enabled
2929
ManagedClrmaEnabled = 0x04, // Native AOT managed support enabled
30+
ModuleEnumeration_EntryPointModule = 0x08, // Use entry point module enumeration scheme
31+
ModuleEnumeration_EntryPointAndDllModule = 0x10, // Use entry point and DLL module enumeration scheme
32+
ModuleEnumeration_AllModules = 0x20, // Use all modules enumeration scheme
3033
};
3134

3235
#define MAX_STACK_FRAMES 1000 // Max number of stack frames returned from thread stackwalk

src/SOS/inc/clrmaservice.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ ICLRMAService : public IUnknown
3131

3232
virtual HRESULT STDMETHODCALLTYPE GetObjectInspection(
3333
ICLRMAObjectInspection **ppObjectInspection) = 0;
34+
35+
virtual HRESULT STDMETHODCALLTYPE SetModuleEnumerationPolicy(
36+
ULONG moduleEnumerationPolicy) = 0;
3437
};
3538

3639
#ifdef __cplusplus

0 commit comments

Comments
 (0)