mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Added watch lock, watch stack offsets (ie: {1}, {Func^2})
This commit is contained in:
parent
6833c12fc8
commit
56cc35f266
10 changed files with 558 additions and 35 deletions
|
@ -761,8 +761,9 @@ DbgExprEvaluator::DbgExprEvaluator(WinDebugger* winDebugger, DbgModule* dbgModul
|
|||
mBlockedSideEffects = false;
|
||||
mReferenceId = NULL;
|
||||
mIsComplexExpression = false;
|
||||
mHadMemberReference = false;
|
||||
mHadMemberReference = false;
|
||||
mCreatedPendingCall = false;
|
||||
mStackSearch = NULL;
|
||||
mValidateOnly = false;
|
||||
mReceivingValue = NULL;
|
||||
mCallResults = NULL;
|
||||
|
@ -770,11 +771,12 @@ DbgExprEvaluator::DbgExprEvaluator(WinDebugger* winDebugger, DbgModule* dbgModul
|
|||
mCallStackPreservePos = 0;
|
||||
mPropGet = NULL;
|
||||
mPropSet = NULL;
|
||||
mPropSrc = NULL;
|
||||
mPropSrc = NULL;
|
||||
}
|
||||
|
||||
DbgExprEvaluator::~DbgExprEvaluator()
|
||||
{
|
||||
delete mStackSearch;
|
||||
}
|
||||
|
||||
DbgTypedValue DbgExprEvaluator::GetInt(int value)
|
||||
|
@ -2526,6 +2528,15 @@ bool DbgExprEvaluator::HasField(DbgType* curCheckType, const StringImpl& fieldNa
|
|||
|
||||
DbgTypedValue DbgExprEvaluator::DoLookupField(BfAstNode* targetSrc, DbgTypedValue target, DbgType* curCheckType, const StringImpl& fieldName, CPUStackFrame* stackFrame, bool allowImplicitThis)
|
||||
{
|
||||
if (mStackSearch != NULL)
|
||||
{
|
||||
if (mStackSearch->mIdentifier == targetSrc)
|
||||
{
|
||||
if (!mStackSearch->mSearchedTypes.Add(curCheckType))
|
||||
return DbgTypedValue();
|
||||
}
|
||||
}
|
||||
|
||||
bool wantsStatic = (!target) || (target.mHasNoValue);
|
||||
auto flavor = GetFlavor();
|
||||
auto language = GetLanguage();
|
||||
|
@ -3548,7 +3559,7 @@ void DbgExprEvaluator::AutocompleteAddTopLevelTypes(const StringImpl& filter)
|
|||
}*/
|
||||
}
|
||||
|
||||
DbgTypedValue DbgExprEvaluator::LookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError, bool* hadError)
|
||||
DbgTypedValue DbgExprEvaluator::DoLookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError, bool* hadError)
|
||||
{
|
||||
if (!mDebugger->mIsRunning)
|
||||
return DbgTypedValue();
|
||||
|
@ -3963,6 +3974,92 @@ DbgTypedValue DbgExprEvaluator::LookupIdentifier(BfAstNode* identifierNode, bool
|
|||
return DbgTypedValue();
|
||||
}
|
||||
|
||||
DbgTypedValue DbgExprEvaluator::LookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError, bool* hadError)
|
||||
{
|
||||
if ((mStackSearch != NULL) && (mStackSearch->mIdentifier == NULL))
|
||||
{
|
||||
mStackSearch->mIdentifier = identifierNode;
|
||||
mStackSearch->mStartingStackIdx = mCallStackIdx;
|
||||
|
||||
int skipCount = 0;
|
||||
|
||||
StringT<256> findStr;
|
||||
for (int i = 0; i < mStackSearch->mSearchStr.mLength; i++)
|
||||
{
|
||||
char c = mStackSearch->mSearchStr[i];
|
||||
|
||||
if (c == '^')
|
||||
{
|
||||
skipCount = atoi(mStackSearch->mSearchStr.c_str() + i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '.')
|
||||
{
|
||||
findStr += ':';
|
||||
findStr += ':';
|
||||
}
|
||||
else
|
||||
findStr += c;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto stackFrame = GetStackFrame();
|
||||
bool matches = true;
|
||||
|
||||
if (mStackSearch->mSearchStr != "*")
|
||||
{
|
||||
mDebugger->UpdateCallStackMethod(mCallStackIdx);
|
||||
if (stackFrame->mSubProgram != NULL)
|
||||
{
|
||||
int strLen = strlen(stackFrame->mSubProgram->mName);
|
||||
if (strLen >= findStr.mLength)
|
||||
{
|
||||
if (strncmp(stackFrame->mSubProgram->mName + strLen - findStr.mLength, findStr.c_str(), findStr.mLength) == 0)
|
||||
{
|
||||
if (strLen > findStr.mLength)
|
||||
{
|
||||
char endC = stackFrame->mSubProgram->mName[strLen - findStr.mLength - 1];
|
||||
if (endC != ':')
|
||||
matches = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
matches = false;
|
||||
}
|
||||
else
|
||||
matches = false;
|
||||
}
|
||||
else
|
||||
matches = false;
|
||||
}
|
||||
|
||||
if (matches)
|
||||
{
|
||||
if (skipCount > 0)
|
||||
{
|
||||
skipCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto result = DoLookupIdentifier(identifierNode, ignoreInitialError, hadError);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
mCallStackIdx++;
|
||||
if (mCallStackIdx >= mDebugger->mCallStack.mSize)
|
||||
mDebugger->UpdateCallStack();
|
||||
if (mCallStackIdx >= mDebugger->mCallStack.mSize)
|
||||
return DbgTypedValue();
|
||||
}
|
||||
}
|
||||
|
||||
return DoLookupIdentifier(identifierNode, ignoreInitialError, hadError);
|
||||
}
|
||||
|
||||
void DbgExprEvaluator::Visit(BfAssignmentExpression* assignExpr)
|
||||
{
|
||||
mHadSideEffects = true;
|
||||
|
@ -4295,6 +4392,12 @@ void DbgExprEvaluator::AutocompleteAddMethod(const char* methodName, const Strin
|
|||
|
||||
void DbgExprEvaluator::AutocompleteAddMembers(DbgType* dbgType, bool wantsStatic, bool wantsNonStatic, const StringImpl& filter, bool isCapture)
|
||||
{
|
||||
if (mStackSearch != NULL)
|
||||
{
|
||||
if (!mStackSearch->mAutocompleteSearchedTypes.Add(dbgType))
|
||||
return;
|
||||
}
|
||||
|
||||
DbgLanguage language = GetLanguage();
|
||||
DbgFlavor flavor = GetFlavor();
|
||||
if ((mDbgCompileUnit != NULL) && (dbgType->mLanguage != DbgLanguage_Unknown) && (dbgType->mLanguage != language))
|
||||
|
@ -7609,7 +7712,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
|
|||
}
|
||||
else if (mDebugTarget->FindSymbolAt(funcPtr, &symbolName, &offset, &dwarf))
|
||||
{
|
||||
demangledName = BfDemangler::Demangle(symbolName, DbgLanguage_Beef);
|
||||
demangledName = BfDemangler::Demangle(symbolName, GetLanguage());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7634,7 +7737,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
|
|||
DbgModule* dwarf;
|
||||
if (mDebugTarget->FindSymbolAt(funcPtr, &symbolName, &offset, &dwarf))
|
||||
{
|
||||
String firstParamType = BfDemangler::Demangle(symbolName, DbgLanguage_Beef, BfDemangler::Flag_CaptureTargetType);
|
||||
String firstParamType = BfDemangler::Demangle(symbolName, GetLanguage(), BfDemangler::Flag_CaptureTargetType);
|
||||
auto targetType = mDbgModule->FindType(firstParamType, NULL, DbgLanguage_BeefUnfixed);
|
||||
if (targetType)
|
||||
{
|
||||
|
|
|
@ -194,6 +194,7 @@ struct DwFormatInfo
|
|||
bool mRawString;
|
||||
bool mAllowStringView;
|
||||
bool mNoEdit;
|
||||
String mStackSearchStr;
|
||||
DbgTypeKindFlags mTypeKindFlags;
|
||||
intptr mArrayLength;
|
||||
intptr mOverrideCount;
|
||||
|
@ -283,6 +284,23 @@ public:
|
|||
Array<uint8> mSRetData;
|
||||
};
|
||||
|
||||
class DbgStackSearch
|
||||
{
|
||||
public:
|
||||
String mSearchStr;
|
||||
BfAstNode* mIdentifier;
|
||||
HashSet<DbgType*> mSearchedTypes;
|
||||
HashSet<DbgType*> mAutocompleteSearchedTypes;
|
||||
int mStartingStackIdx;
|
||||
|
||||
public:
|
||||
DbgStackSearch()
|
||||
{
|
||||
mIdentifier = NULL;
|
||||
mStartingStackIdx = -1;
|
||||
}
|
||||
};
|
||||
|
||||
class DbgExprEvaluator : public BfStructuralVisitor
|
||||
{
|
||||
public:
|
||||
|
@ -351,11 +369,12 @@ public:
|
|||
bool mBlockedSideEffects;
|
||||
bool mIgnoreErrors;
|
||||
bool mCreatedPendingCall;
|
||||
bool mValidateOnly;
|
||||
bool mValidateOnly;
|
||||
int mCallStackIdx;
|
||||
int mCursorPos;
|
||||
|
||||
DwAutoComplete* mAutoComplete;
|
||||
DbgStackSearch* mStackSearch;
|
||||
|
||||
Array<Array<uint8>> mTempStorage;
|
||||
Array<NodeReplaceRecord> mDeferredInsertExplicitThisVector;
|
||||
|
@ -431,6 +450,7 @@ public:
|
|||
bool HasField(DbgType* type, const StringImpl& fieldName);
|
||||
DbgTypedValue DoLookupField(BfAstNode* targetSrc, DbgTypedValue target, DbgType* curCheckType, const StringImpl& fieldName, CPUStackFrame* stackFrame, bool allowImplicitThis);
|
||||
DbgTypedValue LookupField(BfAstNode* targetSrc, DbgTypedValue target, const StringImpl& fieldName);
|
||||
DbgTypedValue DoLookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError, bool* hadError);
|
||||
DbgTypedValue LookupIdentifier(BfAstNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL);
|
||||
void LookupSplatMember(const DbgTypedValue& target, const StringImpl& fieldName);
|
||||
void LookupSplatMember(BfAstNode* srcNode, BfAstNode* lookupNode, const DbgTypedValue& target, const StringImpl& fieldName, String* outFindName = NULL, bool* outIsConst = NULL, StringImpl* forceName = NULL);
|
||||
|
|
|
@ -1403,6 +1403,13 @@ BF_EXPORT const char* BF_CALLTYPE CallStack_GetStackFrameInfo(int stackFrameIdx,
|
|||
return outString.c_str();
|
||||
}
|
||||
|
||||
BF_EXPORT const char* BF_CALLTYPE CallStack_GetStackFrameId(int stackFrameIdx)
|
||||
{
|
||||
String& outString = *gTLStrReturn.Get();
|
||||
outString = gDebugger->GetStackFrameId(stackFrameIdx);
|
||||
return outString.c_str();
|
||||
}
|
||||
|
||||
BF_EXPORT const char* BF_CALLTYPE Callstack_GetStackFrameOldFileInfo(int stackFrameIdx)
|
||||
{
|
||||
String& outString = *gTLStrReturn.Get();
|
||||
|
|
|
@ -329,6 +329,7 @@ public:
|
|||
virtual void GetCodeAddrInfo(intptr addr, 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 ""; }
|
||||
virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) = 0;
|
||||
virtual int GetJmpState(int stackFrameIdx) = 0;
|
||||
virtual intptr GetStackFrameCalleeAddr(int stackFrameIdx) = 0;
|
||||
|
|
|
@ -6371,12 +6371,7 @@ String WinDebugger::ReadString(DbgTypeCode charType, intptr addr, bool isLocalAd
|
|||
bool wasTerminated = false;
|
||||
String valString;
|
||||
intptr maxShowSize = 255;
|
||||
|
||||
if (wantStringView)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
|
||||
if (maxLength == -1)
|
||||
maxLength = formatInfo.mOverrideCount;
|
||||
else if (formatInfo.mOverrideCount != -1)
|
||||
|
@ -6771,7 +6766,7 @@ String WinDebugger::DbgTypedValueToString(const DbgTypedValue& origTypedValue, c
|
|||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (dwValueType->mTypeCode)
|
||||
{
|
||||
case DbgType_Void:
|
||||
|
@ -9239,6 +9234,11 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance
|
|||
}
|
||||
|
||||
DbgExprEvaluator dbgExprEvaluator(this, dbgModule, &bfPassInstance, pendingExpr->mCallStackIdx, pendingExpr->mCursorPos);
|
||||
if (!pendingExpr->mFormatInfo.mStackSearchStr.IsEmpty())
|
||||
{
|
||||
dbgExprEvaluator.mStackSearch = new DbgStackSearch();
|
||||
dbgExprEvaluator.mStackSearch->mSearchStr = pendingExpr->mFormatInfo.mStackSearchStr;
|
||||
}
|
||||
dbgExprEvaluator.mLanguage = pendingExpr->mFormatInfo.mLanguage;
|
||||
dbgExprEvaluator.mReferenceId = &pendingExpr->mReferenceId;
|
||||
dbgExprEvaluator.mExpressionFlags = pendingExpr->mExpressionFlags;
|
||||
|
@ -9446,6 +9446,8 @@ String WinDebugger::EvaluateContinue(DbgPendingExpr* pendingExpr, BfPassInstance
|
|||
|
||||
if (dbgExprEvaluator.mHadSideEffects)
|
||||
val += "\n:sideeffects";
|
||||
if ((dbgExprEvaluator.mStackSearch != NULL) && (dbgExprEvaluator.mStackSearch->mStartingStackIdx != dbgExprEvaluator.mCallStackIdx))
|
||||
val += StrFormat("\n:stackIdx\t%d", dbgExprEvaluator.mCallStackIdx);
|
||||
|
||||
auto underlyingType = exprResult.mType->RemoveModifiers();
|
||||
bool canEdit = true;
|
||||
|
@ -9625,13 +9627,172 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
|
|||
formatInfo.mAllowStringView = true;
|
||||
}
|
||||
|
||||
auto terminatedExpr = expr + ";";
|
||||
|
||||
auto prevActiveThread = mActiveThread;
|
||||
bool restoreActiveThread = false;
|
||||
defer(
|
||||
{
|
||||
if (restoreActiveThread)
|
||||
SetActiveThread(prevActiveThread->mThreadId);
|
||||
});
|
||||
|
||||
bool usedSpecifiedLock = false;
|
||||
int stackIdxOverride = -1;
|
||||
|
||||
if (terminatedExpr.StartsWith('{'))
|
||||
{
|
||||
int closeIdx = terminatedExpr.IndexOf('}');
|
||||
String locString = terminatedExpr.Substring(1, closeIdx - 1);
|
||||
|
||||
for (int i = 0; i <= closeIdx; i++)
|
||||
terminatedExpr[i] = ' ';
|
||||
|
||||
locString.Trim();
|
||||
if (locString.StartsWith("Thread:", StringImpl::CompareKind_OrdinalIgnoreCase))
|
||||
{
|
||||
bool foundLockMatch = true;
|
||||
|
||||
locString.Remove(0, 7);
|
||||
char* endPtr = NULL;
|
||||
int64 threadId = (int64)strtoll(locString.c_str(), &endPtr, 10);
|
||||
|
||||
if (endPtr != NULL)
|
||||
{
|
||||
locString.Remove(0, endPtr - locString.c_str());
|
||||
locString.Trim();
|
||||
|
||||
if (locString.StartsWith("SP:", StringImpl::CompareKind_OrdinalIgnoreCase))
|
||||
{
|
||||
locString.Remove(0, 3);
|
||||
char* endPtr = NULL;
|
||||
uint64 sp = (uint64)strtoll(locString.c_str(), &endPtr, 16);
|
||||
|
||||
if (endPtr != NULL)
|
||||
{
|
||||
locString.Remove(0, endPtr - locString.c_str());
|
||||
locString.Trim();
|
||||
|
||||
if (locString.StartsWith("Func:", StringImpl::CompareKind_OrdinalIgnoreCase))
|
||||
{
|
||||
locString.Remove(0, 5);
|
||||
char* endPtr = NULL;
|
||||
int64 funcAddr = (int64)strtoll(locString.c_str(), &endPtr, 16);
|
||||
|
||||
if (endPtr != NULL)
|
||||
{
|
||||
// Actually do it
|
||||
|
||||
if ((mActiveThread != NULL) && (mActiveThread->mThreadId != threadId))
|
||||
restoreActiveThread = true;
|
||||
if ((mActiveThread == NULL) || (mActiveThread->mThreadId != threadId))
|
||||
SetActiveThread(threadId);
|
||||
if ((mActiveThread != NULL) && (mActiveThread->mThreadId == threadId))
|
||||
{
|
||||
int foundStackIdx = -1;
|
||||
|
||||
int checkStackIdx = 0;
|
||||
while (true)
|
||||
{
|
||||
if (checkStackIdx >= mCallStack.mSize)
|
||||
UpdateCallStack();
|
||||
if (checkStackIdx >= mCallStack.mSize)
|
||||
break;
|
||||
|
||||
auto stackFrame = mCallStack[checkStackIdx];
|
||||
if (stackFrame->mRegisters.GetSP() == sp)
|
||||
{
|
||||
foundStackIdx = checkStackIdx;
|
||||
break;
|
||||
}
|
||||
|
||||
if (stackFrame->mRegisters.GetSP() > sp)
|
||||
{
|
||||
foundStackIdx = checkStackIdx - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
checkStackIdx++;
|
||||
}
|
||||
|
||||
if (foundStackIdx != -1)
|
||||
{
|
||||
UpdateCallStackMethod(foundStackIdx);
|
||||
auto stackFrame = mCallStack[foundStackIdx];
|
||||
|
||||
if ((stackFrame->mSubProgram != NULL) && ((int64)stackFrame->mSubProgram->mBlock.mLowPC == funcAddr))
|
||||
{
|
||||
if ((callStackIdx != foundStackIdx) || (mActiveThread != prevActiveThread))
|
||||
usedSpecifiedLock = true;
|
||||
callStackIdx = foundStackIdx;
|
||||
foundLockMatch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundLockMatch)
|
||||
return "!Locked stack frame not found";
|
||||
|
||||
bool doClear = false;
|
||||
for (int i = closeIdx; i < terminatedExpr.mLength; i++)
|
||||
{
|
||||
char c = terminatedExpr[i];
|
||||
if (doClear)
|
||||
{
|
||||
terminatedExpr[i] = ' ';
|
||||
if (c == '}')
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c == '{')
|
||||
{
|
||||
int endIdx = terminatedExpr.IndexOf('}');
|
||||
if (endIdx == -1)
|
||||
break;
|
||||
terminatedExpr[i] = ' ';
|
||||
doClear = true;
|
||||
}
|
||||
else if (!::isspace((uint8)c))
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (!locString.IsEmpty())
|
||||
{
|
||||
const char* checkPtr = locString.c_str();
|
||||
if ((*checkPtr == '^') || (*checkPtr == '@'))
|
||||
checkPtr++;
|
||||
|
||||
char* endPtr = NULL;
|
||||
int useCallStackIdx = strtol(checkPtr, &endPtr, 10);
|
||||
if (endPtr == locString.c_str() + locString.length())
|
||||
{
|
||||
if (locString[0] == '@')
|
||||
callStackIdx = useCallStackIdx;
|
||||
else
|
||||
callStackIdx += useCallStackIdx;
|
||||
stackIdxOverride = callStackIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
formatInfo.mStackSearchStr = locString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto dbgModule = GetCallStackDbgModule(callStackIdx);
|
||||
auto dbgSubprogram = GetCallStackSubprogram(callStackIdx);
|
||||
DbgCompileUnit* dbgCompileUnit = NULL;
|
||||
if (dbgSubprogram != NULL)
|
||||
dbgCompileUnit = dbgSubprogram->mCompileUnit;
|
||||
|
||||
auto terminatedExpr = expr + ";";
|
||||
|
||||
if ((expr.length() > 0) && (expr[0] == '!'))
|
||||
{
|
||||
if (expr.StartsWith("!step "))
|
||||
|
@ -9688,7 +9849,7 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
|
|||
parser->mCompatMode = true;
|
||||
|
||||
BfPassInstance bfPassInstance(mBfSystem);
|
||||
|
||||
|
||||
if ((terminatedExpr.length() > 2) && (terminatedExpr[0] == '@'))
|
||||
{
|
||||
if (terminatedExpr[1] == '!') // Return string as error
|
||||
|
@ -9852,6 +10013,13 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
|
|||
}
|
||||
else
|
||||
delete pendingExpr;
|
||||
|
||||
if ((!formatInfo.mRawString) && (usedSpecifiedLock))
|
||||
result += "\n:usedLock";
|
||||
|
||||
if ((!formatInfo.mRawString) && (stackIdxOverride != -1))
|
||||
result += StrFormat("\n:stackIdx\t%d", stackIdxOverride);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -10663,10 +10831,33 @@ void WinDebugger::SetActiveThread(int threadId)
|
|||
{
|
||||
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||
|
||||
if ((mActiveThread != NULL) && (mActiveThread->mThreadId == threadId))
|
||||
return;
|
||||
|
||||
auto prevThread = mActiveThread;
|
||||
|
||||
if (mThreadMap.TryGetValue(threadId, &mActiveThread))
|
||||
{
|
||||
BfLogDbg("SetActiveThread %d\n", threadId);
|
||||
ClearCallStack();
|
||||
|
||||
if (prevThread != NULL)
|
||||
{
|
||||
Array<WdStackFrame*>* prevFrameArray = NULL;
|
||||
mSavedCallStacks.TryAdd(prevThread, NULL, &prevFrameArray);
|
||||
for (auto frameInfo : *prevFrameArray)
|
||||
delete frameInfo;
|
||||
*prevFrameArray = mCallStack;
|
||||
mCallStack.Clear();
|
||||
}
|
||||
|
||||
DoClearCallStack(false);
|
||||
|
||||
Array<WdStackFrame*>* newFrameArray = NULL;
|
||||
if (mSavedCallStacks.TryGetValue(mActiveThread, &newFrameArray))
|
||||
{
|
||||
mCallStack = *newFrameArray;
|
||||
newFrameArray->Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10718,8 +10909,8 @@ bool WinDebugger::IsActiveThreadWaiting()
|
|||
return mActiveThread == mDebuggerWaitingThread;
|
||||
}
|
||||
|
||||
void WinDebugger::ClearCallStack()
|
||||
{
|
||||
void WinDebugger::DoClearCallStack(bool clearSavedStacks)
|
||||
{
|
||||
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||
|
||||
BfLogDbg("ClearCallstack\n");
|
||||
|
@ -10728,10 +10919,25 @@ void WinDebugger::ClearCallStack()
|
|||
for (auto wdStackFrame : mCallStack)
|
||||
delete wdStackFrame;
|
||||
|
||||
if (clearSavedStacks)
|
||||
{
|
||||
for (auto& kv : mSavedCallStacks)
|
||||
{
|
||||
for (auto wdStackFrame : kv.mValue)
|
||||
delete wdStackFrame;
|
||||
}
|
||||
mSavedCallStacks.Clear();
|
||||
}
|
||||
|
||||
mCallStack.Clear();
|
||||
mIsPartialCallStack = true;
|
||||
}
|
||||
|
||||
void WinDebugger::ClearCallStack()
|
||||
{
|
||||
DoClearCallStack(true);
|
||||
}
|
||||
|
||||
void WinDebugger::UpdateCallStack(bool slowEarlyOut)
|
||||
{
|
||||
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||
|
@ -11356,6 +11562,27 @@ String WinDebugger::GetStackFrameInfo(int stackFrameIdx, intptr* addr, String* o
|
|||
return outName;
|
||||
}
|
||||
|
||||
String WinDebugger::GetStackFrameId(int stackFrameIdx)
|
||||
{
|
||||
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||
|
||||
if (!FixCallStackIdx(stackFrameIdx))
|
||||
return "";
|
||||
|
||||
int actualStackFrameIdx = BF_MAX(0, stackFrameIdx);
|
||||
UpdateCallStackMethod(actualStackFrameIdx);
|
||||
WdStackFrame* wdStackFrame = mCallStack[actualStackFrameIdx];
|
||||
|
||||
intptr addr = 0;
|
||||
if (wdStackFrame->mSubProgram != NULL)
|
||||
addr = wdStackFrame->mSubProgram->mBlock.mLowPC;
|
||||
else
|
||||
addr = wdStackFrame->mRegisters.GetPC();
|
||||
|
||||
String str = StrFormat("Thread:%d SP:%llX Func:%llX", mActiveThread->mThreadId, wdStackFrame->mRegisters.GetSP(), addr);
|
||||
return str;
|
||||
}
|
||||
|
||||
String WinDebugger::Callstack_GetStackFrameOldFileInfo(int stackFrameIdx)
|
||||
{
|
||||
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||
|
@ -11550,6 +11777,10 @@ String WinDebugger::GetAddressSourceLocation(intptr address)
|
|||
|
||||
String WinDebugger::GetAddressSymbolName(intptr address, bool demangle)
|
||||
{
|
||||
auto subProgram = mDebugTarget->FindSubProgram(address);
|
||||
if (subProgram != NULL)
|
||||
return subProgram->ToString();
|
||||
|
||||
String outSymbol;
|
||||
addr_target offset = 0;
|
||||
DbgModule* dbgModule;
|
||||
|
|
|
@ -416,6 +416,7 @@ public:
|
|||
Dictionary<addr_target, WdBreakpoint*> mBreakpointAddrMap;
|
||||
Array<int> mFreeMemoryBreakIndices;
|
||||
Array<WdStackFrame*> mCallStack;
|
||||
Dictionary<WdThreadInfo*, Array<WdStackFrame*>> mSavedCallStacks;
|
||||
bool mIsPartialCallStack;
|
||||
int mRequestedStackFrameIdx; // -1 means to show mShowPCOverride, -2 means "auto" stop, -3 means breakpoint - normally 0 but during inlining the address can be ambiguous
|
||||
int mBreakStackFrameIdx;
|
||||
|
@ -560,6 +561,7 @@ public:
|
|||
bool CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubprogram* dbgSubprogram, addr_target pcAddress);
|
||||
void CleanupDebugEval(bool restoreRegisters = true);
|
||||
bool FixCallStackIdx(int& callStackIdx);
|
||||
void DoClearCallStack(bool clearSavedStacks);
|
||||
|
||||
int LoadDebugInfoForModule(DbgModule* dbgModule);
|
||||
|
||||
|
@ -631,6 +633,7 @@ public:
|
|||
virtual void GetCodeAddrInfo(intptr addr, 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;
|
||||
virtual String Callstack_GetStackFrameOldFileInfo(int stackFrameIdx) override;
|
||||
virtual int GetJmpState(int stackFrameIdx) override;
|
||||
virtual intptr GetStackFrameCalleeAddr(int stackFrameIdx) override;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue