diff --git a/src/AsyncDebugTools/AsyncDebugTools.def b/src/AsyncDebugTools/AsyncDebugTools.def index 299ae6cba..9b3793a3c 100644 --- a/src/AsyncDebugTools/AsyncDebugTools.def +++ b/src/AsyncDebugTools/AsyncDebugTools.def @@ -1,7 +1,5 @@ EXPORTS - cpsnfeanalyze dumpasync - dumpversions DebugExtensionNotify DebugExtensionInitialize DebugExtensionUninitialize diff --git a/src/AsyncDebugTools/AsyncDebugTools.vcxproj b/src/AsyncDebugTools/AsyncDebugTools.vcxproj index 57ed74fef..4551e53f9 100644 --- a/src/AsyncDebugTools/AsyncDebugTools.vcxproj +++ b/src/AsyncDebugTools/AsyncDebugTools.vcxproj @@ -188,7 +188,6 @@ - @@ -197,7 +196,6 @@ Create Create - diff --git a/src/AsyncDebugTools/AsyncDebugTools.vcxproj.filters b/src/AsyncDebugTools/AsyncDebugTools.vcxproj.filters index 81515b8a3..ef5b43a29 100644 --- a/src/AsyncDebugTools/AsyncDebugTools.vcxproj.filters +++ b/src/AsyncDebugTools/AsyncDebugTools.vcxproj.filters @@ -56,9 +56,6 @@ Source Files - - Source Files - Source Files @@ -68,9 +65,6 @@ Source Files - - Source Files - diff --git a/src/AsyncDebugTools/CpsNfeAnalyzer.cpp b/src/AsyncDebugTools/CpsNfeAnalyzer.cpp deleted file mode 100644 index 43b296018..000000000 --- a/src/AsyncDebugTools/CpsNfeAnalyzer.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "stdafx.h" -#include "dbgexts.h" -#include "Helpers.h" -#include "ThreadPoolExhausted.h" - -bool DetectHangFailureID( - PDEBUG_CLIENT pDebugClient, - const std::string &strSOS, - std::string &strFailureID); - -HRESULT CALLBACK -cpsnfeanalyze(PDEBUG_CLIENT pDebugClient, PCSTR args) -{ - UNREFERENCED_PARAMETER(args); - - CComQIPtr srpControl(pDebugClient); - - std::string strSOS; - std::string strOutput; - if (!EnsureLoadSOS(pDebugClient, strSOS, strOutput)) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Failed to load SOS.dll: %s\n", strOutput.c_str()); - return E_FAIL; - } - - if (IsThreadPoolExhausted(pDebugClient, strSOS)) - { - return OnThreadPoolExhausted(pDebugClient, strSOS); - } - - // !Threads - HRESULT hr = Execute(pDebugClient, GetFullCommand(strSOS, "Threads"), strOutput); - if (FAILED(hr)) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Failed to run !Threads: %s\n", strOutput.c_str()); - return hr; - } - - std::vector exceptionInfos; - ExtractExceptionInfosFromThreadsOutput(strOutput, exceptionInfos); - if (exceptionInfos.empty()) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Not found any exception objects.\n"); - return E_FAIL; - } - - ExceptionInfo blamedException; - std::string strBlamedThreadClrStack; - for (const ExceptionInfo &ex : exceptionInfos) - { - // It is not common but possible to find more than one exceptions. - // To blame the correct exception, we will dump the CLR stacks on each thread and find 'WatsonErrorReport.Submit'. - if (SUCCEEDED(Execute(pDebugClient, "~" + ex.m_strThreadId + "e " + GetFullCommand(strSOS, "ClrStack"), strOutput))) - { - if (strOutput.find("WatsonErrorReport.Submit") != std::string::npos) - { - blamedException = ex; - strBlamedThreadClrStack = strOutput; - break; - } - } - } - - if (blamedException.m_strThreadId.empty()) - { - // Fallback to the first exception which is usually correct. - blamedException = exceptionInfos.front(); - Execute(pDebugClient, "~" + blamedException.m_strThreadId + "e " + GetFullCommand(strSOS, "ClrStack"), strBlamedThreadClrStack); - } - - std::string strBlamedThreadMixedStack; - Execute(pDebugClient, "~" + blamedException.m_strThreadId + "k", strBlamedThreadMixedStack); - - std::vector exceptionDetails; - CollectExceptionDetails(pDebugClient, strSOS, blamedException.m_strExceptionObject, exceptionDetails); - if (exceptionDetails.empty()) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Failed to parse the details of exception: %s\n", blamedException.m_strExceptionObject.c_str()); - return E_FAIL; - } - - std::string strFailureID; - - // Special logic: if the exception was thrown by OnHangDetected, then it is a hang, so that switch to a different code path to generate the failure id. - if (exceptionDetails.size() == 1 && IsDueToHangDetected(exceptionDetails.front())) - { - if (!DetectHangFailureID(pDebugClient, strSOS, strFailureID)) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Failed to detect the frame that is blocking the main thread."); - return E_FAIL; - } - - // Always blame main thread. - Execute(pDebugClient, "~0e " + GetFullCommand(strSOS, "ClrStack"), strBlamedThreadClrStack); - Execute(pDebugClient, "~0k", strBlamedThreadMixedStack); - } - else - { - const ExceptionDetail &finalInnerException = exceptionDetails.back(); - std::string strBlamedSymbol = GuessBlamedSymbol(finalInnerException); - strFailureID = finalInnerException.m_strExceptionType + "_" + finalInnerException.m_strHResult + "_" + strBlamedSymbol; - } - - // Print Failure ID - srpControl->Output(DEBUG_OUTPUT_NORMAL, "FAILURE_BUCKET_ID: %s\n\n", strFailureID.c_str()); - - // Print the exceptions from the inner to outer - for (auto riter = exceptionDetails.crbegin(); riter != exceptionDetails.crend(); ++riter) - { - // Print long string similar to the style in Perl. - // - // <m_strExceptionObject; - srpControl->Output(DEBUG_OUTPUT_NORMAL, "<<%s\n%s%s\n\n", strAnchor.c_str(), riter->m_strRawText.c_str(), strAnchor.c_str()); - } - - // Print CLR stack - { - std::string strAnchor = "ClrStack"; - srpControl->Output(DEBUG_OUTPUT_NORMAL, "<<%s\n%s%s\n\n", strAnchor.c_str(), strBlamedThreadClrStack.c_str(), strAnchor.c_str()); - } - - // Print Mixed stack - { - std::string strAnchor = "MixedStack"; - srpControl->Output(DEBUG_OUTPUT_NORMAL, "<<%s\n%s%s\n\n", strAnchor.c_str(), strBlamedThreadMixedStack.c_str(), strAnchor.c_str()); - } - - return S_OK; -} - -bool DetectHangFailureID( - PDEBUG_CLIENT pDebugClient, - const std::string &strSOS, - std::string &strFailureID) -{ - strFailureID.clear(); - - std::string strMainThreadClrStack; - Execute(pDebugClient, "~0e " + GetFullCommand(strSOS, "ClrStack"), strMainThreadClrStack); - - std::string strLine; - std::stringstream ss(strMainThreadClrStack); - bool foundOnHangDetected = false; - while (std::getline(ss, strLine)) - { - if (!foundOnHangDetected) - { - if (strLine.find("OnHangDetected") != std::string::npos) - { - foundOnHangDetected = true; - } - - continue; - } - - std::string strFunc; - if (ParseClrStackFrame(strLine, strFunc) && !IsImmunized(strFunc)) - { - strFailureID = GetSymbolFromFrame(strFunc); - break; - } - } - - return !strFailureID.empty(); -} diff --git a/src/AsyncDebugTools/dumpversions.cpp b/src/AsyncDebugTools/dumpversions.cpp deleted file mode 100644 index ff60a5b4d..000000000 --- a/src/AsyncDebugTools/dumpversions.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include "stdafx.h" -#include "dbgexts.h" -#include "Helpers.h" -#include "ThreadPoolExhausted.h" -#include "DML.h" -#include - -HRESULT DumpNode( - _In_ PDEBUG_CLIENT pDebugClient, - _In_ const std::string &strSOS, - _In_ const ObjectInfo &node); - -HRESULT CALLBACK -dumpversions(PDEBUG_CLIENT pDebugClient, PCSTR args) -{ - CComQIPtr srpControl(pDebugClient); - - std::string strSOS; - std::string strOutput; - if (!EnsureLoadSOS(pDebugClient, strSOS, strOutput)) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Failed to load SOS.dll: %s\n", strOutput.c_str()); - return E_FAIL; - } - - std::string strObject(args, strlen(args)); - ObjectInfo objectInfo{}; - - HRESULT hr = Execute(pDebugClient, GetFullCommand(strSOS, "do " + strObject), strOutput); - if (FAILED(hr)) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Failed to run !do: %s\n", strOutput.c_str()); - return hr; - } - - if (!ParseDumpObjectOutput(strOutput, objectInfo)) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "Failed to parse the output of !do: %s\n", strOutput.c_str()); - return E_FAIL; - } - - ObjectInfo node{}; - if (FindFieldAndGetObjectInfo(pDebugClient, strSOS, objectInfo, "_root", node)) - { - srpControl->Output(DEBUG_OUTPUT_NORMAL, "Id\tValue\tRequire\tName\n"); - hr = DumpNode(pDebugClient, strSOS, node); - if (FAILED(hr)) - { - return hr; - } - } - - return S_OK; -} - -HRESULT DumpNode( - _In_ PDEBUG_CLIENT pDebugClient, - _In_ const std::string &strSOS, - _In_ const ObjectInfo &node) -{ - HRESULT hr = S_OK; - FieldInfo heightInfo{}; - - CComQIPtr srpControl(pDebugClient); - - if (!GetFieldInfo(node, "_height", heightInfo)) - { - srpControl->Output(DEBUG_OUTPUT_ERROR, "No _height\n"); - return E_FAIL; - } - - int height = atoi(heightInfo.m_strValue.c_str()); - if (height == 0) - { - return S_OK; - } - - if (height > 1) - { - ObjectInfo left{}; - if (FindFieldAndGetObjectInfo(pDebugClient, strSOS, node, "_left", left)) - { - hr = DumpNode(pDebugClient, strSOS, left); - if (FAILED(hr)) - { - return hr; - } - } - } - - ObjectInfo valueInfo{}; - ObjectInfo firstValueInfo{}; - ObjectInfo keyInfo{}; - FieldInfo idInfo{}; - ObjectInfo nameInfo{}; - if (FindFieldAndGetObjectInfo(pDebugClient, strSOS, node, "_value", valueInfo) && - FindFieldAndGetObjectInfo(pDebugClient, strSOS, valueInfo, "_firstValue", firstValueInfo) && - FindFieldAndGetObjectInfo(pDebugClient, strSOS, firstValueInfo, "key", keyInfo) && - GetFieldInfo(keyInfo, "k__BackingField", idInfo) && - FindFieldAndGetObjectInfo(pDebugClient, strSOS, keyInfo, "k__BackingField", nameInfo) && - FindFieldAndGetObjectInfo(pDebugClient, strSOS, firstValueInfo, "value", valueInfo)) - { - FieldInfo intValueInfo{}; - ObjectInfo versionInfo{}; - FieldInfo allowMissingValueInfo{}; - ObjectInfo innerVersionInfo{}; - - if (GetFieldInfo(valueInfo, "m_value", intValueInfo)) - { - hr = srpControl->Output(DEBUG_OUTPUT_NORMAL, "%s\t%s\t\t\t%s\n", idInfo.m_strValue.c_str(), intValueInfo.m_strValue.c_str(), nameInfo.m_string.c_str()); - } - else if (GetFieldInfo(valueInfo, "k__BackingField", allowMissingValueInfo) && - FindFieldAndGetObjectInfo(pDebugClient, strSOS, valueInfo, "k__BackingField", innerVersionInfo) && - GetFieldInfo(innerVersionInfo, "m_value", intValueInfo)) - { - hr = srpControl->Output(DEBUG_OUTPUT_NORMAL, "%s\t%s\t%s\t\t%s\n", idInfo.m_strValue.c_str(), intValueInfo.m_strValue.c_str(), allowMissingValueInfo.m_strValue.c_str(), nameInfo.m_string.c_str()); - } - else - { - return E_FAIL; - } - - if (FAILED(hr)) - { - return hr; - } - } - - if (height > 1) - { - ObjectInfo right{}; - if (FindFieldAndGetObjectInfo(pDebugClient, strSOS, node, "_right", right)) - { - hr = DumpNode(pDebugClient, strSOS, right); - if (FAILED(hr)) - { - return hr; - } - } - } - - return hr; -}