Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc SOS fixes and cleanup. #3354

Merged
merged 4 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using Microsoft.Diagnostics.DebugServices;
using System;

namespace Microsoft.Diagnostics.ExtensionCommands
{
Expand All @@ -27,6 +28,8 @@ public override void Invoke()
{
Write(Target.ToString());
Write(SymbolService.ToString());
long memoryUsage = GC.GetTotalMemory(forceFullCollection: true);
WriteLine($"GC memory usage for managed SOS components: {memoryUsage:##,#} bytes");
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/Microsoft.Diagnostics.Repl/ConsoleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,9 @@ private void ClearLine()
return;
}

if (m_clearLine == null || m_clearLine.Length != Console.WindowWidth) {
m_clearLine = "\r" + new string(' ', Console.WindowWidth - 1);
int width = Console.WindowWidth;
if (m_clearLine == null || width != m_clearLine.Length) {
m_clearLine = "\r" + (width > 0 ? new string(' ', width - 1) : "");
}

Console.Write(m_clearLine);
Expand Down
26 changes: 13 additions & 13 deletions src/SOS/SOS.Extensions/HostServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public sealed unsafe class HostServices : COMCallableIUnknown, IHost
/// <param name="hostServices">The instance of the host services for the native code to use</param>
/// <returns></returns>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate HResult InitializeCallbackDelegate(
private delegate int InitializeCallbackDelegate(
IntPtr hostServices);

internal IntPtr IHostServices { get; }
Expand Down Expand Up @@ -178,7 +178,7 @@ public void DestroyTarget(ITarget target)

#region IHostServices

private HResult GetHost(
private int GetHost(
IntPtr self,
out IntPtr host)
{
Expand All @@ -187,7 +187,7 @@ private HResult GetHost(
return HResult.S_OK;
}

private HResult RegisterDebuggerServices(
private int RegisterDebuggerServices(
IntPtr self,
IntPtr iunk)
{
Expand Down Expand Up @@ -258,7 +258,7 @@ private HResult RegisterDebuggerServices(
return HResult.S_OK;
}

private HResult CreateTarget(
private int CreateTarget(
IntPtr self)
{
Trace.TraceInformation("HostServices.CreateTarget");
Expand All @@ -280,7 +280,7 @@ private HResult CreateTarget(
return HResult.S_OK;
}

private HResult UpdateTarget(
private int UpdateTarget(
IntPtr self,
uint processId)
{
Expand Down Expand Up @@ -324,7 +324,7 @@ private void DestroyTarget(
}
}

private HResult DispatchCommand(
private int DispatchCommand(
IntPtr self,
string commandName,
string commandArguments)
Expand Down Expand Up @@ -358,7 +358,7 @@ private HResult DispatchCommand(
return HResult.E_FAIL;
}

private HResult DisplayHelp(
private int DisplayHelp(
IntPtr self,
string commandName)
{
Expand Down Expand Up @@ -411,21 +411,21 @@ private void Uninitialize(
#region IHostServices delegates

[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult GetHostDelegate(
private delegate int GetHostDelegate(
[In] IntPtr self,
[Out] out IntPtr host);

[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult RegisterDebuggerServicesDelegate(
private delegate int RegisterDebuggerServicesDelegate(
[In] IntPtr self,
[In] IntPtr iunk);

[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult CreateTargetDelegate(
private delegate int CreateTargetDelegate(
[In] IntPtr self);

[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult UpdateTargetDelegate(
private delegate int UpdateTargetDelegate(
[In] IntPtr self,
[In] uint processId);

Expand All @@ -438,13 +438,13 @@ private delegate void DestroyTargetDelegate(
[In] IntPtr self);

[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult DispatchCommandDelegate(
private delegate int DispatchCommandDelegate(
[In] IntPtr self,
[In, MarshalAs(UnmanagedType.LPStr)] string commandName,
[In, MarshalAs(UnmanagedType.LPStr)] string commandArguments);

[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate HResult DisplayHelpDelegate(
private delegate int DisplayHelpDelegate(
[In] IntPtr self,
[In, MarshalAs(UnmanagedType.LPStr)] string commandName);

Expand Down
1 change: 1 addition & 0 deletions src/SOS/SOS.Hosting/Commands/SOSCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace SOS.Hosting
[Command(Name = "eeheap", DefaultOptions = "EEHeap", Help = "Displays info about process memory consumed by internal runtime data structures.")]
[Command(Name = "eeversion", DefaultOptions = "EEVersion", Help = "Displays information about the runtime version.")]
[Command(Name = "ehinfo", DefaultOptions = "EHInfo", Help = "Displays the exception handling blocks in a jitted method.")]
[Command(Name = "enummem", DefaultOptions = "enummem", Help = "ICLRDataEnumMemoryRegions.EnumMemoryRegions test command.")]
[Command(Name = "finalizequeue", DefaultOptions = "FinalizeQueue", Help = "Displays all objects registered for finalization.")]
[Command(Name = "findappdomain", DefaultOptions = "FindAppDomain", Help = "Attempts to resolve the AppDomain of a GC object.")]
[Command(Name = "gchandles", DefaultOptions = "GCHandles", Help = "Provides statistics about GCHandles in the process.")]
Expand Down
15 changes: 2 additions & 13 deletions src/SOS/Strike/eeheap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ void GCPrintSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_allocated_si
dwAddrSeg = (DWORD_PTR)heap.generation_table[GetMaxGeneration()].start_segment;
total_allocated_size = 0;
total_committed_size = 0;
// the loop below will terminate, because we retrieved at most nMaxHeapSegmentCount segments

while (dwAddrSeg != (DWORD_PTR)heap.generation_table[0].start_segment)
{
if (IsInterrupt())
Expand Down Expand Up @@ -567,7 +567,6 @@ void GCPrintLargeHeapSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_all
dwAddrSeg = (DWORD_PTR)heap.generation_table[GetMaxGeneration()+1].start_segment;

// total_size = 0;
// the loop below will terminate, because we retrieved at most nMaxHeapSegmentCount segments
while (dwAddrSeg != NULL)
{
if (IsInterrupt())
Expand Down Expand Up @@ -598,7 +597,6 @@ void GCPrintPinnedHeapSegmentInfo(const GCHeapDetails &heap, DWORD_PTR &total_al
DacpHeapSegmentData segment;
dwAddrSeg = (DWORD_PTR)heap.generation_table[GetMaxGeneration() + 2].start_segment;

// the loop below will terminate, because we retrieved at most nMaxHeapSegmentCount segments
while (dwAddrSeg != NULL)
{
if (IsInterrupt())
Expand Down Expand Up @@ -689,7 +687,6 @@ BOOL GCObjInSegment(TADDR taddrObj, const GCHeapDetails &heap,
{
taddrSeg = (TADDR)heap.generation_table[gen_num].start_segment;

// the loop below will terminate, because we retrieved at most nMaxHeapSegmentCount segments
while (taddrSeg != NULL)
{
if (IsInterrupt())
Expand All @@ -715,7 +712,7 @@ BOOL GCObjInSegment(TADDR taddrObj, const GCHeapDetails &heap,
else
{
taddrSeg = (TADDR)heap.generation_table[GetMaxGeneration()].start_segment;
// the loop below will terminate, because we retrieved at most nMaxHeapSegmentCount segments

while (taddrSeg != (TADDR)heap.generation_table[0].start_segment)
{
if (IsInterrupt())
Expand Down Expand Up @@ -765,7 +762,6 @@ BOOL GCObjInLargeSegment(TADDR taddrObj, const GCHeapDetails &heap, TADDR_SEGINF
DacpHeapSegmentData dacpSeg;
taddrSeg = (TADDR)heap.generation_table[GetMaxGeneration()+1].start_segment;

// the loop below will terminate, because we retrieved at most nMaxHeapSegmentCount segments
while (taddrSeg != NULL)
{
if (IsInterrupt())
Expand Down Expand Up @@ -798,7 +794,6 @@ BOOL GCObjInPinnedObjectSegment(TADDR taddrObj, const GCHeapDetails &heap, TADDR
DacpHeapSegmentData dacpSeg;
taddrSeg = (TADDR)heap.generation_table[GetMaxGeneration() + 2].start_segment;

// the loop below will terminate, because we retrieved at most nMaxHeapSegmentCount segments
while (taddrSeg != NULL)
{
if (IsInterrupt())
Expand Down Expand Up @@ -1921,12 +1916,6 @@ BOOL GCHeapSnapshot::AddSegments(const GCHeapDetails& details)
ExtOut("Error requesting heap segment %p\n", SOS_PTR(AddrSeg));
return FALSE;
}
if (n++ > nMaxHeapSegmentCount && !details.has_regions) // that would be insane
{
ExtOut("More than %d heap segments, there must be an error\n", nMaxHeapSegmentCount);
return FALSE;
}

// add the new segment to the array of segments. This will expand the array if necessary
if (!m_segments.AddSegment(&segment))
{
Expand Down
2 changes: 1 addition & 1 deletion src/SOS/Strike/sos.def
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ EXPORTS
EHInfo
ehinfo=EHInfo
Ehinfo=EHInfo
enummemory
enummem
ext
sos=ext
FinalizeQueue
Expand Down
2 changes: 1 addition & 1 deletion src/SOS/Strike/sos_unixexports.src
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ EEHeap
EEVersion
EEStack
EHInfo
enummemory
enummem
FinalizeQueue
FindAppDomain
FindRoots
Expand Down
94 changes: 70 additions & 24 deletions src/SOS/Strike/strike.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1448,18 +1448,29 @@ HRESULT PrintVC(TADDR taMT, TADDR taObject, BOOL bPrintFields = TRUE)
return S_OK;
}

// If this bit is set in the RuntimeType.m_handle field, the value is a TypeDesc pointer, otherwise it is a MethodTable pointer.
#define RUNTIMETYPE_HANDLE_IS_TYPEDESC 0x2

void PrintRuntimeTypeInfo(TADDR p_rtObject, const DacpObjectData & rtObjectData)
{
// Get the method table
int iOffset = GetObjFieldOffset(TO_CDADDR(p_rtObject), rtObjectData.MethodTable, W("m_handle"));
if (iOffset > 0)
{
TADDR mtPtr;
if (SUCCEEDED(GetMTOfObject(p_rtObject + iOffset, &mtPtr)))
if (MOVE(mtPtr, p_rtObject + iOffset) == S_OK)
{
sos::MethodTable mt = mtPtr;
ExtOut("Type Name: %S\n", mt.GetName());
DMLOut("Type MT: %s\n", DMLMethodTable(mtPtr));
// Check if TypeDesc
if ((mtPtr & RUNTIMETYPE_HANDLE_IS_TYPEDESC) != 0)
{
ExtOut("TypeDesc: %p\n", mtPtr & ~RUNTIMETYPE_HANDLE_IS_TYPEDESC);
}
else
{
sos::MethodTable mt = mtPtr;
ExtOut("Type Name: %S\n", mt.GetName());
DMLOut("Type MT: %s\n", DMLMethodTable(mtPtr));
}
}
}
}
Expand Down Expand Up @@ -3912,24 +3923,34 @@ void PrintRuntimeTypes(DWORD_PTR objAddr,size_t Size,DWORD_PTR methodTable,LPVOI
{
DMLOut(DMLObject(objAddr));

CLRDATA_ADDRESS appDomain = GetAppDomainForMT(mtPtr);
if (appDomain != NULL)
// Check if TypeDesc
if ((mtPtr & RUNTIMETYPE_HANDLE_IS_TYPEDESC) != 0)
{
if (appDomain == pArgs->adstore.sharedDomain)
ExtOut(" %" POINTERSIZE "s", "Shared");

else if (appDomain == pArgs->adstore.systemDomain)
ExtOut(" %" POINTERSIZE "s", "System");
else
DMLOut(" %s", DMLDomain(appDomain));
ExtOut(" %p\n", mtPtr & ~RUNTIMETYPE_HANDLE_IS_TYPEDESC);
}
else
{
ExtOut(" %" POINTERSIZE "s", "?");
}
CLRDATA_ADDRESS appDomain = GetAppDomainForMT(mtPtr);
if (appDomain != NULL)
{
if (appDomain == pArgs->adstore.sharedDomain)
ExtOut(" %" POINTERSIZE "s", "Shared");

else if (appDomain == pArgs->adstore.systemDomain)
ExtOut(" %" POINTERSIZE "s", "System");
else
DMLOut(" %s", DMLDomain(appDomain));
}
else
{
ExtOut(" %" POINTERSIZE "s", "?");
}

NameForMT_s(mtPtr, g_mdName, mdNameLen);
DMLOut(" %s %S\n", DMLMethodTable(mtPtr), g_mdName);
if (NameForMT_s(mtPtr, g_mdName, mdNameLen))
{
DMLOut(" %s %S\n", DMLMethodTable(mtPtr), g_mdName);
}
}
}
}
}
Expand Down Expand Up @@ -15711,16 +15732,18 @@ DECLARE_API(StopOnCatch)
return S_OK;
}

class EnumMemoryCallback : public ICLRDataEnumMemoryRegionsCallback, ICLRDataEnumMemoryRegionsLoggingCallback
class EnumMemoryCallback : public ICLRDataEnumMemoryRegionsCallback, ICLRDataLoggingCallback
{
private:
LONG m_ref;
bool m_log;
bool m_valid;

public:
EnumMemoryCallback(bool log) :
EnumMemoryCallback(bool log, bool valid) :
m_ref(1),
m_log(log)
m_log(log),
m_valid(valid)
{
}

Expand All @@ -15739,9 +15762,9 @@ class EnumMemoryCallback : public ICLRDataEnumMemoryRegionsCallback, ICLRDataEnu
AddRef();
return S_OK;
}
else if (InterfaceId == IID_ICLRDataEnumMemoryRegionsLoggingCallback)
else if (InterfaceId == IID_ICLRDataLoggingCallback)
{
*Interface = (ICLRDataEnumMemoryRegionsLoggingCallback*)this;
*Interface = (ICLRDataLoggingCallback*)this;
AddRef();
return S_OK;
}
Expand Down Expand Up @@ -15776,26 +15799,49 @@ class EnumMemoryCallback : public ICLRDataEnumMemoryRegionsCallback, ICLRDataEnu
{
ExtOut("%016llx %08x\n", address, size);
}
if (m_valid)
{
uint64_t start = address;
uint64_t numberPages = (size + DT_OS_PAGE_SIZE - 1) / DT_OS_PAGE_SIZE;
for (size_t p = 0; p < numberPages; p++, start += DT_OS_PAGE_SIZE)
{
BYTE buffer[1];
ULONG read;
if (FAILED(g_ExtData->ReadVirtual(start, buffer, ARRAY_SIZE(buffer), &read)))
{
ExtOut("Invalid: %016llx %08x start %016llx\n", address, size, start);
break;
}
}
}
if (IsInterrupt())
{
return COR_E_OPERATIONCANCELED;
}
return S_OK;
}

HRESULT STDMETHODCALLTYPE LogMessage(
/* [in] */ LPCSTR message)
{
ExtOut("%s", message);
if (IsInterrupt())
{
return COR_E_OPERATIONCANCELED;
}
return S_OK;
}
};

DECLARE_API(enummemory)
DECLARE_API(enummem)
{
INIT_API();

ToRelease<ICLRDataEnumMemoryRegions> enumMemoryRegions;
Status = g_clrData->QueryInterface(__uuidof(ICLRDataEnumMemoryRegions), (void**)&enumMemoryRegions);
if (SUCCEEDED(Status))
{
ToRelease<ICLRDataEnumMemoryRegionsCallback> callback = new EnumMemoryCallback(false);
ToRelease<ICLRDataEnumMemoryRegionsCallback> callback = new EnumMemoryCallback(false, true);
ULONG32 minidumpType =
(MiniDumpWithPrivateReadWriteMemory |
MiniDumpWithDataSegs |
Expand Down
Loading