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}");
}
}
VERIFY:\s*Total\s+<DECVAL>\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+<DECVAL>
-IFDEF:WINDOWS
VERIFY:\s*CCW\s+<DECVAL>
VERIFY:\s*RCW\s+<DECVAL>
ENDIF:WINDOWS
-ENDIF:LINUX
\ No newline at end of file
#include <coreclrhost.h>
#include <set>
-#include <string>
#if defined(__APPLE__)
#include <mach-o/dyld.h>
/**********************************************************************\
* 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();
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();
pathto=PathTo
ProcInfo
procinfo=ProcInfo
+ SOSStatus
+ sosstatus=SOSStatus
VerifyStackTrace
WatsonBuckets
SetHostRuntime
SetSymbolServer
SOSFlush
+SOSStatus
SyncBlk
Threads
ThreadState
* 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();
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
#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");
}
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");
}
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: *
IXCLRDataProcess *g_clrData = NULL;
ISOSDacInterface *g_sos = NULL;
+IXCLRDataProcess *g_clrDataProcess = NULL;
ICorDebugProcess *g_pCorDebugProcess = NULL;
#ifndef IfFailRet
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;
}
static HRESULT GetClrDataProcess()
{
- static IXCLRDataProcess* clrDataProcess = NULL;
HRESULT hr = S_OK;
- if (clrDataProcess == NULL)
+ if (g_clrDataProcess == NULL)
{
LPCSTR dacFilePath = GetDacFilePath();
if (dacFilePath == nullptr)
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();
//
HRESULT LoadClrDebugDll(void)
{
- static IXCLRDataProcess* clrDataProcess = NULL;
HRESULT hr = GetClrDataProcess();
if (FAILED(hr))
{
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))
{
#include "cordebug.h"
#include "static_assert.h"
+#include <string>
#include "hostcoreclr.h"
typedef LPCSTR LPCUTF8;
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);
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.");
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 <command>");
+ interpreter.AddCommand("sosstatus", new sosCommand("SOSStatus"), "Displays the global SOS status.");
return true;
}
[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.")]
[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.")]