From: Mike McLaughlin Date: Wed, 2 Oct 2019 17:25:39 +0000 (-0700) Subject: Display internal SOS status with sosstatus command (#519) X-Git-Tag: submit/tizen/20200402.013218~14^2^2~41 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=667723e07372492b89ab8b711bd5953f9529e94b;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git Display internal SOS status with sosstatus command (#519) Display internal SOS status with sosstatus command Add dumpvc to dotnet-dump/lldb commands. Remove reductant dotnet-dump error message when SOS command fails. Fixes issues: https://github.com/dotnet/diagnostics/issues/511 https://github.com/dotnet/diagnostics/issues/508 https://github.com/dotnet/diagnostics/issues/509 Change SyncBlk test not to run on xplat. --- diff --git a/src/SOS/SOS.Hosting/SOSHost.cs b/src/SOS/SOS.Hosting/SOSHost.cs index d3a7d8277..0f26ec112 100644 --- a/src/SOS/SOS.Hosting/SOSHost.cs +++ b/src/SOS/SOS.Hosting/SOSHost.cs @@ -318,7 +318,7 @@ namespace SOS int result = commandFunc(_interface, arguments ?? ""); if (result != 0) { - throw new InvalidOperationException($"SOS command FAILED 0x{result:X8}"); + Trace.TraceError($"SOS command FAILED 0x{result:X8}"); } } diff --git a/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script b/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script index 85e37b577..87fa292f7 100644 --- a/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script +++ b/src/SOS/SOS.UnitTests/Scripts/OtherCommands.script @@ -76,11 +76,10 @@ VERIFY:(\s*\s+\s+\s+.*)? VERIFY:\s*Total\s+\s+objects\s+ SOSCOMMAND:SyncBlk -!IFDEF:LINUX +# On Linux/MacOS we sometimes get "Error requesting SyncBlk data" error from the DAC. +IFDEF:WINDOWS VERIFY:\s*Index\s+SyncBlock\s+MonitorHeld\s+Recursion\s+Owning\s+Thread\s+Info\s+SyncBlock\s+Owner\s+ VERIFY:\s*Total\s+ -IFDEF:WINDOWS VERIFY:\s*CCW\s+ VERIFY:\s*RCW\s+ ENDIF:WINDOWS -ENDIF:LINUX \ No newline at end of file diff --git a/src/SOS/Strike/hostcoreclr.cpp b/src/SOS/Strike/hostcoreclr.cpp index 863a337c2..3f1318d3c 100644 --- a/src/SOS/Strike/hostcoreclr.cpp +++ b/src/SOS/Strike/hostcoreclr.cpp @@ -30,7 +30,6 @@ #include #include -#include #if defined(__APPLE__) #include @@ -231,7 +230,7 @@ static bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutabl /**********************************************************************\ * Returns the coreclr module/runtime directory of the target. \**********************************************************************/ -static HRESULT GetCoreClrDirectory(std::string& coreClrDirectory) +HRESULT GetCoreClrDirectory(std::string& coreClrDirectory) { #ifdef FEATURE_PAL LPCSTR directory = g_ExtServices->GetCoreClrDirectory(); diff --git a/src/SOS/Strike/hostcoreclr.h b/src/SOS/Strike/hostcoreclr.h index ef260a399..075e4ed1f 100644 --- a/src/SOS/Strike/hostcoreclr.h +++ b/src/SOS/Strike/hostcoreclr.h @@ -60,9 +60,13 @@ static const char *MetadataHelperClassName = "SOS.MetadataHelper"; extern HMODULE g_hInstance; extern LPCSTR g_hostRuntimeDirectory; +extern LPCSTR g_dacFilePath; +extern LPCSTR g_dbiFilePath; +extern LPCSTR g_tmpPath; extern SOSNetCoreCallbacks g_SOSNetCoreCallbacks; extern HRESULT GetCoreClrDirectory(LPWSTR modulePath, int modulePathSize); +extern HRESULT GetCoreClrDirectory(std::string& coreClrDirectory); extern LPCSTR GetDacFilePath(); extern LPCSTR GetDbiFilePath(); extern BOOL IsHostingInitialized(); diff --git a/src/SOS/Strike/sos.def b/src/SOS/Strike/sos.def index 8bbfcf171..2d983d59e 100644 --- a/src/SOS/Strike/sos.def +++ b/src/SOS/Strike/sos.def @@ -211,6 +211,8 @@ EXPORTS pathto=PathTo ProcInfo procinfo=ProcInfo + SOSStatus + sosstatus=SOSStatus VerifyStackTrace WatsonBuckets diff --git a/src/SOS/Strike/sos_unixexports.src b/src/SOS/Strike/sos_unixexports.src index b5c066d59..a9afa599c 100644 --- a/src/SOS/Strike/sos_unixexports.src +++ b/src/SOS/Strike/sos_unixexports.src @@ -49,6 +49,7 @@ StopOnCatch SetHostRuntime SetSymbolServer SOSFlush +SOSStatus SyncBlk Threads ThreadState diff --git a/src/SOS/Strike/strike.cpp b/src/SOS/Strike/strike.cpp index 8c452f234..2942af788 100644 --- a/src/SOS/Strike/strike.cpp +++ b/src/SOS/Strike/strike.cpp @@ -10240,10 +10240,10 @@ DECLARE_API(DumpGCData) * Routine Description: * * * * This function is called to dump the build number and type of the * -* mscoree.dll * +* runtime and SOS. * * * \**********************************************************************/ -DECLARE_API (EEVersion) +DECLARE_API(EEVersion) { INIT_API(); @@ -10257,23 +10257,27 @@ DECLARE_API (EEVersion) VS_FIXEDFILEINFO version; BOOL ret = GetEEVersion(&version, fileVersionBuffer.GetPtr(), fileVersionBufferSize); - if (ret) + if (ret) { if (version.dwFileVersionMS != (DWORD)-1) { ExtOut("%u.%u.%u.%u", - HIWORD(version.dwFileVersionMS), - LOWORD(version.dwFileVersionMS), - HIWORD(version.dwFileVersionLS), - LOWORD(version.dwFileVersionLS)); + HIWORD(version.dwFileVersionMS), + LOWORD(version.dwFileVersionMS), + HIWORD(version.dwFileVersionLS), + LOWORD(version.dwFileVersionLS)); + + if (IsRuntimeVersion(version, 3)) { + ExtOut(" (3.x runtime)"); + } + #ifndef FEATURE_PAL - if (version.dwFileFlags & VS_FF_DEBUG) - { + if (version.dwFileFlags & VS_FF_DEBUG) { ExtOut(" checked or debug build"); } else - { - BOOL fRet = IsRetailBuild ((size_t)g_moduleInfo[eef].baseAddr); + { + BOOL fRet = IsRetailBuild((size_t)g_moduleInfo[eef].baseAddr); if (fRet) ExtOut(" retail"); else @@ -10282,22 +10286,20 @@ DECLARE_API (EEVersion) #endif ExtOut("\n"); - if (fileVersionBuffer[0] != '\0') - { + if (fileVersionBuffer[0] != '\0') { ExtOut("%s\n", fileVersionBuffer.GetPtr()); } } } - - if (!InitializeHeapData ()) + + if (!InitializeHeapData()) ExtOut("GC Heap not initialized, so GC mode is not determined yet.\n"); - else if (IsServerBuild()) - ExtOut("Server mode with %d gc heaps\n", GetGcHeapCount()); + else if (IsServerBuild()) + ExtOut("Server mode with %d gc heaps\n", GetGcHeapCount()); else ExtOut("Workstation mode\n"); - if (!GetGcStructuresValid()) - { + if (!GetGcStructuresValid()) { ExtOut("In plan phase of garbage collection\n"); } @@ -10309,18 +10311,16 @@ DECLARE_API (EEVersion) if (sosVersion.dwFileVersionMS != (DWORD)-1) { ExtOut("SOS Version: %u.%u.%u.%u", - HIWORD(sosVersion.dwFileVersionMS), - LOWORD(sosVersion.dwFileVersionMS), - HIWORD(sosVersion.dwFileVersionLS), - LOWORD(sosVersion.dwFileVersionLS)); + HIWORD(sosVersion.dwFileVersionMS), + LOWORD(sosVersion.dwFileVersionMS), + HIWORD(sosVersion.dwFileVersionLS), + LOWORD(sosVersion.dwFileVersionLS)); - if (sosVersion.dwFileFlags & VS_FF_DEBUG) - { - ExtOut(" debug build"); + if (sosVersion.dwFileFlags & VS_FF_DEBUG) { + ExtOut(" debug build"); } - else - { - ExtOut(" retail build"); + else { + ExtOut(" retail build"); } ExtOut("\n"); } @@ -10329,6 +10329,40 @@ DECLARE_API (EEVersion) return Status; } +/**********************************************************************\ +* Routine Description: * +* * +* This function the global SOS status * +* * +\**********************************************************************/ +DECLARE_API(SOSStatus) +{ + INIT_API_NOEE(); + + if (g_targetMachine != nullptr) { + ExtOut("Target platform: %04x Context size %04x\n", g_targetMachine->GetPlatform(), g_targetMachine->GetContextSize()); + } + if (g_tmpPath != nullptr) { + ExtOut("Temp path: %s\n", g_tmpPath); + } + if (g_dacFilePath != nullptr) { + ExtOut("DAC file path: %s\n", g_dacFilePath); + } + if (g_dbiFilePath != nullptr) { + ExtOut("DBI file path: %s\n", g_dbiFilePath); + } + if (g_hostRuntimeDirectory != nullptr) { + ExtOut("Host runtime path: %s\n", g_hostRuntimeDirectory); + } + std::string coreclrDirectory; + if (SUCCEEDED(GetCoreClrDirectory(coreclrDirectory))) { + ExtOut("Runtime path: %s\n", coreclrDirectory.c_str()); + } + DisplaySymbolStore(); + + return Status; +} + #ifndef FEATURE_PAL /**********************************************************************\ * Routine Description: * diff --git a/src/SOS/Strike/util.cpp b/src/SOS/Strike/util.cpp index a550da79a..1d7a79bc5 100644 --- a/src/SOS/Strike/util.cpp +++ b/src/SOS/Strike/util.cpp @@ -63,6 +63,7 @@ const char * const CorElementTypeNamespace[ELEMENT_TYPE_MAX]= IXCLRDataProcess *g_clrData = NULL; ISOSDacInterface *g_sos = NULL; +IXCLRDataProcess *g_clrDataProcess = NULL; ICorDebugProcess *g_pCorDebugProcess = NULL; #ifndef IfFailRet @@ -3315,16 +3316,22 @@ bool IsRuntimeVersion(DWORD major) VS_FIXEDFILEINFO fileInfo; if (GetEEVersion(&fileInfo, nullptr, 0)) { - switch (major) - { - case 5: - return HIWORD(fileInfo.dwFileVersionMS) == 5; - case 3: - return HIWORD(fileInfo.dwFileVersionMS) == 4 && LOWORD(fileInfo.dwFileVersionMS) == 700; - default: - _ASSERTE(FALSE); - break; - } + return IsRuntimeVersion(fileInfo, major); + } + return false; +} + +bool IsRuntimeVersion(VS_FIXEDFILEINFO& fileInfo, DWORD major) +{ + switch (major) + { + case 5: + return HIWORD(fileInfo.dwFileVersionMS) == 5; + case 3: + return HIWORD(fileInfo.dwFileVersionMS) == 4 && LOWORD(fileInfo.dwFileVersionMS) == 700; + default: + _ASSERTE(FALSE); + break; } return false; } @@ -3872,10 +3879,9 @@ void ResetGlobals(void) static HRESULT GetClrDataProcess() { - static IXCLRDataProcess* clrDataProcess = NULL; HRESULT hr = S_OK; - if (clrDataProcess == NULL) + if (g_clrDataProcess == NULL) { LPCSTR dacFilePath = GetDacFilePath(); if (dacFilePath == nullptr) @@ -3894,18 +3900,18 @@ static HRESULT GetClrDataProcess() return CORDBG_E_MISSING_DEBUGGER_EXPORTS; } ICLRDataTarget *target = new DataTarget(); - hr = pfnCLRDataCreateInstance(__uuidof(IXCLRDataProcess), target, (void**)&clrDataProcess); + hr = pfnCLRDataCreateInstance(__uuidof(IXCLRDataProcess), target, (void**)&g_clrDataProcess); if (FAILED(hr)) { - clrDataProcess = NULL; + g_clrDataProcess = NULL; return hr; } ULONG32 flags = 0; - clrDataProcess->GetOtherNotificationFlags(&flags); + g_clrDataProcess->GetOtherNotificationFlags(&flags); flags |= (CLRDATA_NOTIFY_ON_MODULE_LOAD | CLRDATA_NOTIFY_ON_MODULE_UNLOAD | CLRDATA_NOTIFY_ON_EXCEPTION); - clrDataProcess->SetOtherNotificationFlags(flags); + g_clrDataProcess->SetOtherNotificationFlags(flags); } - g_clrData = clrDataProcess; + g_clrData = g_clrDataProcess; g_clrData->AddRef(); g_clrData->Flush(); @@ -3921,7 +3927,6 @@ static HRESULT GetClrDataProcess() // HRESULT LoadClrDebugDll(void) { - static IXCLRDataProcess* clrDataProcess = NULL; HRESULT hr = GetClrDataProcess(); if (FAILED(hr)) { @@ -3929,23 +3934,20 @@ HRESULT LoadClrDebugDll(void) return hr; #else // Fail if ExtensionApis wasn't initialized because we are hosted under dotnet-dump - if (Ioctl == nullptr) - { + if (Ioctl == nullptr) { return hr; } // Try getting the DAC interface from dbgeng if the above fails on Windows WDBGEXTS_CLR_DATA_INTERFACE Query; Query.Iid = &__uuidof(IXCLRDataProcess); - if (!Ioctl(IG_GET_CLR_DATA_INTERFACE, &Query, sizeof(Query))) - { + if (!Ioctl(IG_GET_CLR_DATA_INTERFACE, &Query, sizeof(Query))) { return hr; } g_clrData = (IXCLRDataProcess*)Query.Iface; g_clrData->Flush(); #endif } - hr = g_clrData->QueryInterface(__uuidof(ISOSDacInterface), (void**)&g_sos); if (FAILED(hr)) { diff --git a/src/SOS/Strike/util.h b/src/SOS/Strike/util.h index 2ff025788..d1a811572 100644 --- a/src/SOS/Strike/util.h +++ b/src/SOS/Strike/util.h @@ -37,6 +37,7 @@ inline void RestoreSOToleranceState() {} #include "cordebug.h" #include "static_assert.h" +#include #include "hostcoreclr.h" typedef LPCSTR LPCUTF8; @@ -1561,6 +1562,7 @@ HRESULT InitCorDebugInterface(); VOID UninitCorDebugInterface(); BOOL GetEEVersion(VS_FIXEDFILEINFO* pFileInfo, char* fileVersionBuffer, int fileVersionBufferSizeInBytes); bool IsRuntimeVersion(DWORD major); +bool IsRuntimeVersion(VS_FIXEDFILEINFO& fileInfo, DWORD major); #ifndef FEATURE_PAL BOOL IsRetailBuild (size_t base); BOOL GetSOSVersion(VS_FIXEDFILEINFO *pFileInfo); diff --git a/src/SOS/lldbplugin/soscommand.cpp b/src/SOS/lldbplugin/soscommand.cpp index f63befb64..487c62d56 100644 --- a/src/SOS/lldbplugin/soscommand.cpp +++ b/src/SOS/lldbplugin/soscommand.cpp @@ -148,6 +148,7 @@ sosCommandInitialize(lldb::SBDebugger debugger) interpreter.AddCommand("dumpmodule", new sosCommand("DumpModule"), "Displays information about a EE module structure at the specified address."); interpreter.AddCommand("dumpmt", new sosCommand("DumpMT"), "Displays information about a method table at the specified address."); interpreter.AddCommand("dumpobj", new sosCommand("DumpObj"), "Displays info about an object at the specified address."); + interpreter.AddCommand("dumpvc", new sosCommand("DumpVC"), "Displays info about the fields of a value class."); interpreter.AddCommand("dumpstack", new sosCommand("DumpStack"), "Displays a native and managed stack trace."); interpreter.AddCommand("dso", new sosCommand("DumpStackObjects"), "Displays all managed objects found within the bounds of the current stack."); interpreter.AddCommand("eeheap", new sosCommand("EEHeap"), "Displays info about process memory consumed by internal runtime data structures."); @@ -170,5 +171,6 @@ sosCommandInitialize(lldb::SBDebugger debugger) interpreter.AddCommand("setsymbolserver", new sosCommand("SetSymbolServer"), "Enables the symbol server support "); interpreter.AddCommand("sympath", new sosCommand("SetSymbolServer", "-sympath"), "Add server, cache and directory paths in the Windows symbol path format."); interpreter.AddCommand("soshelp", new sosCommand("Help"), "Displays all available commands when no parameter is specified, or displays detailed help information about the specified command. soshelp "); + interpreter.AddCommand("sosstatus", new sosCommand("SOSStatus"), "Displays the global SOS status."); return true; } diff --git a/src/Tools/dotnet-dump/Commands/SOSCommand.cs b/src/Tools/dotnet-dump/Commands/SOSCommand.cs index e6d6311ca..bc258de37 100644 --- a/src/Tools/dotnet-dump/Commands/SOSCommand.cs +++ b/src/Tools/dotnet-dump/Commands/SOSCommand.cs @@ -28,6 +28,7 @@ namespace Microsoft.Diagnostics.Tools.Dump [Command(Name = "dumpmodule", AliasExpansion = "DumpModule", Help = "Displays information about a EE module structure at the specified address.")] [Command(Name = "dumpmt", AliasExpansion = "DumpMT", Help = "Displays information about a method table at the specified address.")] [Command(Name = "dumpobj", AliasExpansion = "DumpObj", Help = "Displays info about an object at the specified address.")] + [Command(Name = "dumpvc", AliasExpansion = "DumpVC", Help = "Displays info about the fields of a value class.")] [Command(Name = "dumpstackobjects", AliasExpansion = "DumpStackObjects", Help = "Displays all managed objects found within the bounds of the current stack.")] [CommandAlias(Name = "dso")] [Command(Name = "eeheap", AliasExpansion = "EEHeap", Help = "Displays info about process memory consumed by internal runtime data structures.")] @@ -39,6 +40,7 @@ namespace Microsoft.Diagnostics.Tools.Dump [Command(Name = "name2ee", AliasExpansion = "Name2EE", Help = "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module.")] [Command(Name = "printexception", AliasExpansion = "PrintException", Help = "Displays and formats fields of any object derived from the Exception class at the specified address.")] [CommandAlias(Name = "pe")] + [Command(Name = "sosstatus", AliasExpansion = "SOSStatus", Help = "Displays the global SOS status.")] [Command(Name = "syncblk", AliasExpansion = "SyncBlk", Help = "Displays the SyncBlock holder info.")] [Command(Name = "histclear", AliasExpansion = "HistClear", Help = "Releases any resources used by the family of Hist commands.")] [Command(Name = "histinit", AliasExpansion = "HistInit", Help = "Initializes the SOS structures from the stress log saved in the debuggee.")]