From af3210354fb5b56ab99fc98d311e1dc6ebacd6e1 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Fri, 22 Apr 2016 17:18:03 -0700 Subject: [PATCH] Fixes various SOS problems and issues. Fixes not printing the method names in various sos commands (clrstack, ip2md, etc). This was because a NetBSD build change caused the sos output formatting to use the linux C++ runtime _vsnprintf instead of the PAL's version which supports the %S format option for WCHAR strings. The above also fixes issue #4430 "SOS dumplog fails to print out full log content from coredump". Fixes issue #4402 "Callstack is trashed after an exception" by executing " .settings set EngineInitialization.VerifyFunctionTableCallbacks=false" during SOS initialization. Fixes issue #4432 "Missing endline when final frame is HelperMethodFrame". Worked around a bug in WinDbg DML output when displaying the IP address for a special frame by not using DML. It doesn't mean anything for special frames anyway and it is usually is a native code address so the DML !U disassemble doesn't work. I didn't leave it blank like in "clrstack -f" for compatibility with tests and it is what people are use to. --- src/ToolBox/SOS/Strike/exts.cpp | 5 +++++ src/ToolBox/SOS/Strike/strike.cpp | 8 +++++--- src/ToolBox/SOS/Strike/util.cpp | 35 +++++++---------------------------- src/ToolBox/SOS/Strike/util.h | 1 + src/ToolBox/SOS/Strike/xplat/dbgeng.h | 10 ++++++++-- src/pal/inc/pal.h | 1 + 6 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/ToolBox/SOS/Strike/exts.cpp b/src/ToolBox/SOS/Strike/exts.cpp index 804363a..0b1f976 100644 --- a/src/ToolBox/SOS/Strike/exts.cpp +++ b/src/ToolBox/SOS/Strike/exts.cpp @@ -227,6 +227,11 @@ DebugExtensionInitialize(PULONG Version, PULONG Flags) { return Hr; } + + // Fixes the "Unable to read dynamic function table entries" error messages by disabling the WinDbg security + // feature that prevents the loading of unknown out of proc tack walkers. + DebugControl->Execute(DEBUG_OUTCTL_IGNORE, ".settings set EngineInitialization.VerifyFunctionTableCallbacks=false", + DEBUG_EXECUTE_NOT_LOGGED | DEBUG_EXECUTE_NO_REPEAT); ExtQuery(DebugClient); if (IsMiniDumpFileNODAC()) diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp index dc62acd..976ffe1 100644 --- a/src/ToolBox/SOS/Strike/strike.cpp +++ b/src/ToolBox/SOS/Strike/strike.cpp @@ -12066,7 +12066,7 @@ public: if (SUCCEEDED(frameDataResult) && FrameData.frameAddr) { // Skip the instruction pointer because it doesn't really mean anything for method frames - out.WriteColumn(1, bFull ? String("") : InstructionPtr(ip)); + out.WriteColumn(1, bFull ? String("") : NativePtr(ip)); // This is a clr!Frame. out.WriteColumn(2, GetFrameFromAddress(TO_TADDR(FrameData.frameAddr), pStackWalk, bFull)); @@ -12100,8 +12100,10 @@ public: if (bParams || bLocals) PrintArgsAndLocals(pStackWalk, bParams, bLocals); } - if(bDisplayRegVals) + + if (bDisplayRegVals) PrintManagedFrameContext(pStackWalk); + } while (pStackWalk->Next() == S_OK); #ifdef _TARGET_WIN64_ @@ -12201,7 +12203,7 @@ public: ULONG64 ip = frame->InstructionOffset; out.WriteColumn(0, frame->StackOffset); - out.WriteColumn(1, InstructionPtr(ip)); + out.WriteColumn(1, NativePtr(ip)); HRESULT hr = g_ExtSymbols->GetNameByOffset(TO_CDADDR(ip), symbol, _countof(symbol), NULL, &displacement); if (SUCCEEDED(hr) && symbol[0] != '\0') diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp index 6f115b0..3285be4 100644 --- a/src/ToolBox/SOS/Strike/util.cpp +++ b/src/ToolBox/SOS/Strike/util.cpp @@ -5279,27 +5279,6 @@ void WhitespaceOut(int count) g_ExtControl->Output(DEBUG_OUTPUT_NORMAL, FixedIndentString); } -HRESULT -OutputVaList( - ULONG mask, - PCSTR format, - va_list args) -{ -#ifdef FEATURE_PAL - char str[4096]; - - // Try and format our string into a fixed buffer first and see if it fits - int length = _vsnprintf(str, sizeof(str), format, args); - if (length > 0) - { - return g_ExtControl->Output(mask, "%s", str); - } - return E_FAIL; -#else - return g_ExtControl->OutputVaList(mask, format, args); -#endif // FEATURE_PAL -} - void DMLOut(PCSTR format, ...) { if (Output::IsOutputSuppressed()) @@ -5308,7 +5287,7 @@ void DMLOut(PCSTR format, ...) va_list args; va_start(args, format); ExtOutIndent(); - + #ifndef FEATURE_PAL if (IsDMLEnabled() && !Output::IsDMLExposed()) { @@ -5317,7 +5296,7 @@ void DMLOut(PCSTR format, ...) else #endif { - OutputVaList(DEBUG_OUTPUT_NORMAL, format, args); + g_ExtControl->OutputVaList(DEBUG_OUTPUT_NORMAL, format, args); } va_end(args); @@ -5347,7 +5326,7 @@ void ExtOut(PCSTR Format, ...) va_start(Args, Format); ExtOutIndent(); - OutputVaList(DEBUG_OUTPUT_NORMAL, Format, Args); + g_ExtControl->OutputVaList(DEBUG_OUTPUT_NORMAL, Format, Args); va_end(Args); } @@ -5359,7 +5338,7 @@ void ExtWarn(PCSTR Format, ...) va_list Args; va_start(Args, Format); - OutputVaList(DEBUG_OUTPUT_WARNING, Format, Args); + g_ExtControl->OutputVaList(DEBUG_OUTPUT_WARNING, Format, Args); va_end(Args); } @@ -5368,7 +5347,7 @@ void ExtErr(PCSTR Format, ...) va_list Args; va_start(Args, Format); - OutputVaList(DEBUG_OUTPUT_ERROR, Format, Args); + g_ExtControl->OutputVaList(DEBUG_OUTPUT_ERROR, Format, Args); va_end(Args); } @@ -5379,10 +5358,10 @@ void ExtDbgOut(PCSTR Format, ...) if (Output::g_bDbgOutput) { va_list Args; - + va_start(Args, Format); ExtOutIndent(); - OutputVaList(DEBUG_OUTPUT_NORMAL, Format, Args); + g_ExtControl->OutputVaList(DEBUG_OUTPUT_NORMAL, Format, Args); va_end(Args); } #endif diff --git a/src/ToolBox/SOS/Strike/util.h b/src/ToolBox/SOS/Strike/util.h index 47025ab..230660f 100644 --- a/src/ToolBox/SOS/Strike/util.h +++ b/src/ToolBox/SOS/Strike/util.h @@ -1032,6 +1032,7 @@ DefineFormatClass(ThreadID, Formats::Hex, Output::DML_ThreadID); DefineFormatClass(RCWrapper, Formats::Pointer, Output::DML_RCWrapper); DefineFormatClass(CCWrapper, Formats::Pointer, Output::DML_CCWrapper); DefineFormatClass(InstructionPtr, Formats::Pointer, Output::DML_IP); +DefineFormatClass(NativePtr, Formats::Pointer, Output::DML_None); DefineFormatClass(Decimal, Formats::Decimal, Output::DML_None); DefineFormatClass(Pointer, Formats::Pointer, Output::DML_None); diff --git a/src/ToolBox/SOS/Strike/xplat/dbgeng.h b/src/ToolBox/SOS/Strike/xplat/dbgeng.h index fb84881..b456227 100644 --- a/src/ToolBox/SOS/Strike/xplat/dbgeng.h +++ b/src/ToolBox/SOS/Strike/xplat/dbgeng.h @@ -72,7 +72,7 @@ public: { va_list args; va_start (args, format); - HRESULT result = OutputVaList(mask, format, args); + HRESULT result = m_lldbservices->OutputVaList(mask, format, args); va_end (args); return result; } @@ -83,7 +83,13 @@ public: PCSTR format, va_list args) { - return m_lldbservices->OutputVaList(mask, format, args); + char str[4096]; + int length = PAL__vsnprintf(str, sizeof(str), format, args); + if (length > 0) + { + return Output(mask, "%s", str); + } + return E_FAIL; } // The following methods allow direct control diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index b2acc08..d001fbd 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -5921,6 +5921,7 @@ PALIMPORT WCHAR * __cdecl PAL_wcstok(WCHAR *, const WCHAR *); PALIMPORT size_t __cdecl PAL_wcscspn(const WCHAR *, const WCHAR *); PALIMPORT int __cdecl PAL_swprintf(WCHAR *, const WCHAR *, ...); PALIMPORT int __cdecl PAL_vswprintf(WCHAR *, const WCHAR *, va_list); +PALIMPORT int __cdecl PAL__vsnprintf(LPSTR Buffer, size_t Count, LPCSTR Format, va_list ap); PALIMPORT int __cdecl _snwprintf(WCHAR *, size_t, const WCHAR *, ...); PALIMPORT int __cdecl PAL_swscanf(const WCHAR *, const WCHAR *, ...); PALIMPORT LONG __cdecl PAL_wcstol(const WCHAR *, WCHAR **, int); -- 2.7.4