浏览代码

Improved callstack handling with inlined methods

Brian Fiete 3 年之前
父节点
当前提交
f29a74888c

+ 8 - 0
BeefLibs/corlib/src/System.bf

@@ -47,6 +47,14 @@ namespace System
 
 	}
 
+#if BF_ENABLE_OBJECT_DEBUG_FLAGS
+	[AlwaysInclude]
+#endif
+	struct CallStackList : int
+	{
+
+	}
+
 	interface IDisposable
 	{
 	    void Dispose() mut;

+ 7 - 2
IDE/dist/BeefDbgVis.toml

@@ -2,8 +2,13 @@
 
 [[Type]]
 Name = "System.CallStackAddr"
-DisplayString = "{__funcName(this), ne}"
-Action = "ShowCodeAddr {(int)this,X}"
+DisplayString = "{__funcName(this - 1), ne}"
+Action = "ShowCodeAddr {(int)this - 1,X}"
+
+[[Type]]
+Name = "System.CallStackList"
+DisplayString = "{__funcName(((int*)(int)this)[0] - 1), ne}"
+[Type.Expand.CallStackList]
 
 [[Type]]
 Name = "System.DeferredCall"

+ 3 - 3
IDE/src/Debugger/DebugManager.bf

@@ -260,7 +260,7 @@ namespace IDE.Debugger
 		static extern int32 CallStack_GetBreakStackFrameIdx();
 
 		[CallingConvention(.Stdcall),CLink]
-		static extern char8* Debugger_GetCodeAddrInfo(int addr, out int32 hotIdx, out int32 defLineStart, out int32 defLineEnd, out int32 line, out int32 column);
+		static extern char8* Debugger_GetCodeAddrInfo(int addr, int inlineCallAddr, out int32 hotIdx, out int32 defLineStart, out int32 defLineEnd, out int32 line, out int32 column);
 
 		[CallingConvention(.Stdcall),CLink]
 		static extern void Debugger_GetStackAllocInfo(int addr, out int threadId, int32* outStackIdx);
@@ -940,14 +940,14 @@ namespace IDE.Debugger
 			return Debugger_GetStackFrameCalleeAddr(stackFrameIdx);
 		}
 
-		public void GetCodeAddrInfo(int addr, String outFile, out int hotIdx, out int defLineStart, out int defLineEnd, out int line, out int column)
+		public void GetCodeAddrInfo(int addr, int inlineCallAddr, String outFile, out int hotIdx, out int defLineStart, out int defLineEnd, out int line, out int column)
 		{
 			int32 hotIdxOut;
 			int32 lineOut;
 			int32 columnOut;
 			int32 defLineStartOut = -1;
 			int32 defLineEndOut = -1;
-			char8* locationStr = Debugger_GetCodeAddrInfo(addr, out hotIdxOut, out defLineStartOut, out defLineEndOut, out lineOut, out columnOut);
+			char8* locationStr = Debugger_GetCodeAddrInfo(addr, inlineCallAddr, out hotIdxOut, out defLineStartOut, out defLineEndOut, out lineOut, out columnOut);
 			hotIdx = hotIdxOut;
 			defLineStart = defLineStartOut;
 			defLineEnd = defLineEndOut;

+ 5 - 1
IDE/src/IDEApp.bf

@@ -1127,13 +1127,17 @@ namespace IDE
 					sourceViewPanel.RecordHistoryLocation();
 
 				int64 addr = int64.Parse(cmds[1], System.Globalization.NumberStyles.HexNumber).GetValueOrDefault();
+				int64 inlineCallAddr = 0;
+				if (cmds.Count >= 2)
+					inlineCallAddr = int64.Parse(cmds[2], System.Globalization.NumberStyles.HexNumber).GetValueOrDefault();
+
 				String fileName = scope String();
 				int lineNum = 0;
 				int column;
 				int hotIdx;
 				int defLineStart;
 				int defLineEnd;
-				mDebugger.GetCodeAddrInfo((int)addr, fileName, out hotIdx, out defLineStart, out defLineEnd, out lineNum, out column);
+				mDebugger.GetCodeAddrInfo((int)addr, (int)inlineCallAddr, fileName, out hotIdx, out defLineStart, out defLineEnd, out lineNum, out column);
 				if (fileName.Length > 0)
 				{
 					int showHotIdx = -1;

+ 1 - 1
IDEHelper/Compiler/CeDebugger.cpp

@@ -4498,7 +4498,7 @@ void CeDebugger::UpdateCallStackMethod(int stackFrameIdx)
 {
 }
 
-void CeDebugger::GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn)
+void CeDebugger::GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn)
 {
 }
 

+ 1 - 1
IDEHelper/Compiler/CeDebugger.h

@@ -374,7 +374,7 @@ public:
 	virtual DbgMemoryFlags GetMemoryFlags(intptr address) override;
 	virtual void UpdateRegisterUsage(int stackFrameIdx) override;
 	virtual void UpdateCallStackMethod(int stackFrameIdx) override;
-	virtual void GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) override;
+	virtual void GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) override;
 	virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) override;
 	virtual String GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd, int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags) override;
 	virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) override;

+ 1 - 0
IDEHelper/DbgExprEvaluator.h

@@ -203,6 +203,7 @@ struct DwFormatInfo
 	DbgTypedValue mExplicitThis;
 	int mTotalSummaryLength;
 	String mReferenceId;
+	String mAction;
 	String mSubjectExpr;
 	String mExpectedType;
 	String mNamespaceSearch;

+ 2 - 2
IDEHelper/DebugManager.cpp

@@ -1428,11 +1428,11 @@ BF_EXPORT intptr BF_CALLTYPE Debugger_GetStackFrameCalleeAddr(int stackFrameIdx)
 	return gDebugger->GetStackFrameCalleeAddr(stackFrameIdx);
 }
 
-BF_EXPORT const char* BF_CALLTYPE Debugger_GetCodeAddrInfo(intptr addr, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn)
+BF_EXPORT const char* BF_CALLTYPE Debugger_GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn)
 {
 	String& outString = *gTLStrReturn.Get();
 	outString.clear();
-	gDebugger->GetCodeAddrInfo(addr, &outString, outHotIdx, outDefLineStart, outDefLineEnd, outLine, outColumn);
+	gDebugger->GetCodeAddrInfo(addr, inlineCallAddr, &outString, outHotIdx, outDefLineStart, outDefLineEnd, outLine, outColumn);
 	return outString.c_str();
 }
 

+ 4 - 0
IDEHelper/DebugVisualizers.cpp

@@ -325,6 +325,10 @@ bool DebugVisualizers::ReadFileTOML(const StringImpl& fileName)
 										Fail("Unexpected entry", value);
 								}
 							}
+							else if (name == "CallStackList")
+							{
+								entry->mCollectionType = DebugVisualizerEntry::CollectionType_CallStackList;
+							}
 							else
 								Fail("Unexpected entry", value);
 						}

+ 2 - 1
IDEHelper/DebugVisualizers.h

@@ -35,7 +35,8 @@ public:
 		CollectionType_LinkedList,
 		CollectionType_Delegate,
 		CollectionType_Dictionary,
-		CollectionType_ExpandedItem
+		CollectionType_ExpandedItem,
+		CollectionType_CallStackList
 	};
 
 public:

+ 1 - 1
IDEHelper/Debugger.h

@@ -326,7 +326,7 @@ public:
 	virtual DbgMemoryFlags GetMemoryFlags(intptr address) = 0;
 	virtual void UpdateRegisterUsage(int stackFrameIdx) = 0;	
 	virtual void UpdateCallStackMethod(int stackFrameIdx) = 0;	
-	virtual void GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) = 0;
+	virtual void GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) = 0;
 	virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) = 0;
 	virtual String GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int32* outHotIdx, int32* outDefLineStart, int32* outDefLineEnd, int32* outLine, int32* outColumn, int32* outLanguage, int32* outStackSize, int8* outFlags) = 0;
 	virtual String GetStackFrameId(int stackFrameIdx) { return ""; }

+ 115 - 15
IDEHelper/WinDebugger.cpp

@@ -5653,25 +5653,31 @@ bool WinDebugger::ParseFormatInfo(DbgModule* dbgModule, const StringImpl& format
 			else if (strncmp(formatCmd.c_str(), "refid=", 6) == 0)
 			{
 				formatInfo->mReferenceId = formatCmd.Substring(6);
-				if (formatInfo->mReferenceId[0] == '\"')
+				if ((formatInfo->mReferenceId.mLength >= 2) && (formatInfo->mReferenceId[0] == '\"'))
 					formatInfo->mReferenceId = formatInfo->mReferenceId.Substring(1, formatInfo->mReferenceId.length() - 2);
 			}
+			else if (strncmp(formatCmd.c_str(), "action=", 7) == 0)
+			{
+				formatInfo->mAction = formatCmd.Substring(7);
+				if ((formatInfo->mAction.mLength >= 2) && (formatInfo->mAction[0] == '\"'))
+					formatInfo->mAction = formatInfo->mReferenceId.Substring(1, formatInfo->mReferenceId.length() - 2);
+			}
 			else if (strncmp(formatCmd.c_str(), "_=", 2) == 0)
 			{
 				formatInfo->mSubjectExpr = formatCmd.Substring(2);
-				if (formatInfo->mSubjectExpr[0] == '\"')
+				if ((formatInfo->mSubjectExpr.mLength >= 2) && (formatInfo->mSubjectExpr[0] == '\"'))
 					formatInfo->mSubjectExpr = formatInfo->mSubjectExpr.Substring(1, formatInfo->mSubjectExpr.length() - 2);
 			}
 			else if (strncmp(formatCmd.c_str(), "expectedType=", 13) == 0)
 			{
 				formatInfo->mExpectedType = formatCmd.Substring(13);
-				if (formatInfo->mExpectedType[0] == '\"')
+				if ((formatInfo->mExpectedType.mLength >= 2) && (formatInfo->mExpectedType[0] == '\"'))
 					formatInfo->mExpectedType = formatInfo->mExpectedType.Substring(1, formatInfo->mExpectedType.length() - 2);
 			}
 			else if (strncmp(formatCmd.c_str(), "namespaceSearch=", 16) == 0)
 			{
 				formatInfo->mNamespaceSearch = formatCmd.Substring(16);
-				if (formatInfo->mNamespaceSearch[0] == '\"')
+				if ((formatInfo->mNamespaceSearch.mLength >= 2) && (formatInfo->mNamespaceSearch[0] == '\"'))
 					formatInfo->mNamespaceSearch = formatInfo->mNamespaceSearch.Substring(1, formatInfo->mNamespaceSearch.length() - 2);
 			}
 			else if (formatCmd == "d")
@@ -6088,7 +6094,6 @@ String WinDebugger::GetTreeItems(DbgCompileUnit* dbgCompileUnit, DebugVisualizer
 			}			
 		}
 
-
 		DbgTypedValue val = valueEvaluationContext.EvaluateInContext(readNode);
 		if (valueType == NULL)
 			valueType = val.mType;
@@ -6185,7 +6190,7 @@ String WinDebugger::GetCollectionContinuation(const StringImpl& continuationData
 		retVal += "\n" + newContinuationData;
 		return retVal;
 	}
-	
+		
 	return "";
 }
 
@@ -8307,14 +8312,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c
 				stackTraceAddr = ptrVal + (dbgAllocInfo >> 16);
 			}
 
-			if (stackTraceLen == 1)
-			{
-				retVal += StrFormat("\n[AllocStackTrace]\t*(System.CallStackAddr*)%s, nm", EncodeDataPtr(stackTraceAddr, true).c_str());
-			}
-			else if (stackTraceLen > 0)
-			{
-				retVal += StrFormat("\n[AllocStackTrace]\t(System.CallStackAddr*)%s, %d, na", EncodeDataPtr(stackTraceAddr, true).c_str(), stackTraceLen);
-			}
+			retVal += StrFormat("\n[AllocStackTrace]\t(System.CallStackList)%s, count=%d, na", EncodeDataPtr(stackTraceAddr, true).c_str(), stackTraceLen);
 		}
 
 		retVal += StrFormat("\n:language\t%d", language);
@@ -8350,6 +8348,12 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c
 		if (isDeletedBfObject)
 			retVal += "\n:deleted";
 
+		if (!formatInfo.mAction.IsEmpty())
+		{
+			retVal += "\n:action\t";
+			retVal += formatInfo.mAction;
+		}
+		else
 		if ((debugVis != NULL) && (!debugVis->mAction.empty()))
 		{
 			String rawActionStr = mDebugManager->mDebugVisualizers->DoStringReplace(debugVis->mAction, dbgVisWildcardCaptures);
@@ -8771,6 +8775,58 @@ void WinDebugger::HandleCustomExpandedItems(String& retVal, DbgCompileUnit* dbgC
 			}					
 		}
 	}
+	else if (debugVis->mCollectionType == DebugVisualizerEntry::CollectionType_CallStackList)
+	{	
+		int size = 0;
+
+		String addrs;
+		String firstVal;		
+		auto ptr = useTypedValue.mPtr;
+
+		for (int i = 0; i < formatInfo.mOverrideCount; i++)
+		{
+			auto funcAddr = ReadMemory<addr_target>(ptr + i * sizeof(addr_target));
+			auto srcFuncAddr = funcAddr;
+
+			addrs += EncodeDataPtr(funcAddr - 1, false);
+			if (i == 0)
+				firstVal = addrs;
+			addrs += EncodeDataPtr((addr_target)0, false);
+			size++;
+			
+			int inlineIdx = 0;
+
+			auto subProgram = mDebugTarget->FindSubProgram(funcAddr - 1, DbgOnDemandKind_LocalOnly);
+			while (subProgram != NULL)
+			{
+				if (subProgram->mInlineeInfo == NULL)
+					break;
+				
+				auto prevFuncAddr = subProgram->mBlock.mLowPC;
+
+				subProgram = subProgram->mInlineeInfo->mInlineParent;
+				addrs += EncodeDataPtr(subProgram->mBlock.mLowPC + 1, false);
+				addrs += EncodeDataPtr(prevFuncAddr, false);
+				size++;
+
+				inlineIdx++;
+			}
+		}
+
+		String evalStr = "(CallStackAddr)0x{1}";
+
+		if (!debugVis->mShowElementAddrs)
+			evalStr.Insert(0, "*");
+		
+		evalStr += ", refid=\"" + referenceId + ".[]\"";		
+		evalStr += ", ne";
+		retVal += "\n:repeat" + StrFormat("\t%d\t%d\t%d", 0, size, 10000) +
+			"\t[{0}]\t(CallStackAddr)0x{1}, action=ShowCodeAddr {1} {2}\t" + firstVal + "\t" + EncodeDataPtr((addr_target)0, false);
+				
+		retVal += "\n:addrs\t" + addrs;		
+		retVal += "\n:addrsEntrySize\t2";
+		return;
+	}
 
 	if (formatInfo.mExpandItemDepth == 0)
 	{
@@ -11232,6 +11288,8 @@ void WinDebugger::UpdateCallStackMethod(int stackFrameIdx)
 			mDebugTarget->FindSymbolAt(pcAddress, &symbolName, &offset, &dbgModule);
 		}
 
+		auto prevStackFrame = wdStackFrame;
+
 		// Insert inlines
 		int insertIdx = checkFrameIdx + 1;
 		while ((dwSubprogram != NULL) && (dwSubprogram->mInlineeInfo != NULL))
@@ -11245,18 +11303,57 @@ void WinDebugger::UpdateCallStackMethod(int stackFrameIdx)
 			dwSubprogram = dwSubprogram->mInlineeInfo->mInlineParent;
 			insertIdx++;
 			checkFrameIdx++;
+
+			prevStackFrame = inlineStackFrame;
 		}
 	}
 }
 
-void WinDebugger::GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn)
+void WinDebugger::GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn)
 {
 	AutoCrit autoCrit(mDebugManager->mCritSect);
 
 	DbgSubprogram* subProgram = NULL;
 	DbgLineData* callingLineData = FindLineDataAtAddress((addr_target)addr, &subProgram);	
+
+	if (inlineCallAddr != 0)
+	{
+		auto inlinedSubProgram = mDebugTarget->FindSubProgram(inlineCallAddr);
+		if (inlinedSubProgram != 0)
+		{
+			FixupLineDataForSubprogram(inlinedSubProgram->mInlineeInfo->mRootInliner);
+			DbgSubprogram* parentSubprogram = inlinedSubProgram->mInlineeInfo->mInlineParent; // Require it be in the inline parent
+			auto foundLine = parentSubprogram->FindClosestLine(inlinedSubProgram->mBlock.mLowPC, &parentSubprogram);
+			if (foundLine != NULL)
+			{
+				auto srcFile = parentSubprogram->GetLineSrcFile(*foundLine);
+				*outFile = srcFile->GetLocalPath();
+				*outLine = foundLine->mLine;
+			}
+
+			*outHotIdx = inlinedSubProgram->mCompileUnit->mDbgModule->mHotIdx;
+			*outColumn = -1;
+
+			DbgSubprogram* callingSubProgram = NULL;
+			DbgLineData* callingLineData = FindLineDataAtAddress(inlinedSubProgram->mBlock.mLowPC - 1, &callingSubProgram);
+			if ((callingLineData != NULL) && (callingSubProgram == subProgram))
+			{
+				auto callingSrcFile = callingSubProgram->GetLineSrcFile(*callingLineData);
+				auto srcFile = callingSrcFile;
+				*outFile = srcFile->GetLocalPath();
+
+				if (*outLine == callingLineData->mLine)
+					*outColumn = callingLineData->mColumn;
+			}
+			return;
+		}		
+	}
+
 	if (subProgram != NULL)
 	{
+		if ((subProgram->mInlineeInfo != NULL) && ((addr_target)addr >= subProgram->mBlock.mHighPC))
+			callingLineData = &subProgram->mInlineeInfo->mLastLineData;
+
 		*outHotIdx = subProgram->mCompileUnit->mDbgModule->mHotIdx;
 		*outFile = subProgram->GetLineSrcFile(*callingLineData)->GetLocalPath();
 		*outLine = callingLineData->mLine;		
@@ -11500,6 +11597,9 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
 		DbgSubprogram* specificSubprogram = dwSubprogram;
 		dwLineData = dwSubprogram->FindClosestLine(findAddress, &specificSubprogram);
 
+		if ((dwLineData == NULL) && (dwSubprogram->mInlineeInfo != NULL) && (findAddress >= dwSubprogram->mBlock.mHighPC))
+			dwLineData = &dwSubprogram->mInlineeInfo->mLastLineData;
+
 		if (dwLineData != NULL)		
 			dwSrcFile = dwSubprogram->GetLineSrcFile(*dwLineData);
 

+ 1 - 1
IDEHelper/WinDebugger.h

@@ -632,7 +632,7 @@ public:
 	addr_target GetTLSOffset(int tlsIndex);
 	virtual void UpdateRegisterUsage(int stackFrameIdx) override;
 	virtual void UpdateCallStackMethod(int stackFrameIdx) override;
-	virtual void GetCodeAddrInfo(intptr addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) override;
+	virtual void GetCodeAddrInfo(intptr addr, intptr inlineCallAddr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn) override;
 	virtual void GetStackAllocInfo(intptr addr, int* outThreadId, int* outStackIdx) override;
 	virtual String GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* outFile, int* outHotIdx, int* outDefLineStart, int* outDefLineEnd, int* outLine, int* outColumn, int* outLanguage, int* outStackSize, int8* outFlags) override;
 	virtual String GetStackFrameId(int stackFrameIdx) override;