mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Win32 debugging fixes, more work on custom compile commands
Fixed working dir for 'launch' Fixed attaching to process - stack trace wasn't updating properly Fixed more custom compile stuff, and BeefySysLib bin destination Fixed linking issues related to Bfp* and Bp* exports in both BeefRT and BeefySysLib Fixed a crash with conditional breakpoints Fixed release mode IDE issues (related to hot swap breakpoints) Fixed hotswapping type data with LLVM builds Fixed 'Pause' state processing Running_ToTempBreakpoint for ScriptManager Fixed Win32 step out when there's an ESP adjustment at the return site Made step-out skip over "unimportant" instructions at return site
This commit is contained in:
parent
09016c8dc0
commit
a367b8165f
60 changed files with 1131 additions and 1065 deletions
|
@ -687,7 +687,7 @@ int BeCOFFObject::DbgGetTypeId(BeDbgType* dbgType, bool doDefine)
|
|||
outT.Write(*(int16*)&attr);
|
||||
outT.Write(func->mCvTypeId);
|
||||
if (isVirt)
|
||||
outT.Write((int32)func->mVIndex);
|
||||
outT.Write((int32)func->mVIndex * mBeModule->mContext->mPointerSize);
|
||||
DbgEncodeString(outT, func->mName);
|
||||
memberCount++;
|
||||
DbgTAlign();
|
||||
|
|
|
@ -93,6 +93,8 @@ BePointerType* BeContext::GetPointerTo(BeType* beType)
|
|||
|
||||
void BeContext::SetStructBody(BeStructType* structType, const SizedArrayImpl<BeType*>& types, bool packed)
|
||||
{
|
||||
BF_ASSERT(structType->mMembers.IsEmpty());
|
||||
|
||||
int dataPos = 0;
|
||||
for (auto& beType : types)
|
||||
{
|
||||
|
|
|
@ -914,7 +914,7 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
}
|
||||
break;
|
||||
case BfIRCmd_StructSetBody:
|
||||
{
|
||||
{
|
||||
CMD_PARAM(BeType*, type);
|
||||
CMD_PARAM(CmdParamVec<BeType*>, members);
|
||||
CMD_PARAM(bool, isPacked);
|
||||
|
|
|
@ -2972,8 +2972,10 @@ BeFunction* BeModule::CreateFunction(BeFunctionType* funcType, BfIRLinkageType l
|
|||
func->mLinkageType = linkageType;
|
||||
func->mParams.Resize(funcType->mParams.size());
|
||||
mFunctions.push_back(func);
|
||||
|
||||
#ifdef _DEBUG
|
||||
BF_ASSERT(mFunctionMap.TryAdd(name, func));
|
||||
// It IS possible hit this, especially if we have multiple intrinsics mapping to 'malloc' for example
|
||||
//BF_ASSERT(mFunctionMap.TryAdd(name, func));
|
||||
#endif
|
||||
return func;
|
||||
}
|
||||
|
|
|
@ -1885,13 +1885,13 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
void BfIRBuilder::CreateTypeDeclaration(BfType* type)
|
||||
void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDefine)
|
||||
{
|
||||
bool wantDIData = DbgHasInfo() && (!type->IsUnspecializedType());
|
||||
|
||||
// Types that don't have a proper 'defining module' need to be defined in every module they are used
|
||||
bool isDefiningModule = (type->GetModule() == mModule) || (type->IsFunction());
|
||||
bool wantsForwardDecl = !isDefiningModule;
|
||||
bool wantsForwardDecl = !isDefiningModule && !forceDefine;
|
||||
|
||||
if (mModule->mExtensionCount != 0)
|
||||
wantsForwardDecl = true;
|
||||
|
@ -2802,7 +2802,7 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
|||
}
|
||||
}
|
||||
|
||||
void BfIRBuilder::CreateTypeDefinition(BfType* type)
|
||||
void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDefine)
|
||||
{
|
||||
// This PopulateType is generally NOT needed, but here is a scenario in which it is:
|
||||
// ClassB derives from ClassA. ClassC uses ClassB. A method inside ClassA gets modified,
|
||||
|
@ -2815,7 +2815,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type)
|
|||
bool isDefiningModule = (type->GetModule() == mModule) || (type->IsFunction());
|
||||
if (mModule->mExtensionCount != 0)
|
||||
isDefiningModule = false;
|
||||
|
||||
|
||||
// if (mModule->mModuleName == "vdata")
|
||||
// isDefiningModule = true;
|
||||
|
||||
|
@ -2827,13 +2827,13 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type)
|
|||
DbgSetTypeSize(DbgGetType(type), BF_ALIGN(type->mSize, type->mAlign) * 8, type->mAlign * 8);
|
||||
}
|
||||
|
||||
bool wantsForwardDecl = !isDefiningModule;
|
||||
bool wantsForwardDecl = !isDefiningModule && !forceDefine;
|
||||
bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive());
|
||||
|
||||
|
||||
auto typeInstance = type->ToTypeInstance();
|
||||
if (typeInstance == NULL)
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
auto typeDef = typeInstance->mTypeDef;
|
||||
if (DbgHasInfo() && (!type->IsUnspecializedType()) && (!wantsForwardDecl))
|
||||
{
|
||||
|
@ -3057,7 +3057,7 @@ void BfIRBuilder::ReplaceDITemporaryTypes()
|
|||
if (mTypeMap[typeInstance] == BfIRPopulateType_Full)
|
||||
continue;
|
||||
|
||||
CreateTypeDefinition(typeInstance);
|
||||
CreateTypeDefinition(typeInstance, false);
|
||||
}
|
||||
mDITemporaryTypes.Clear();
|
||||
}
|
||||
|
@ -3093,12 +3093,14 @@ void BfIRBuilder::PopulateType(BfType* type, BfIRPopulateType populateType)
|
|||
|
||||
if (curPopulateType >= populateType)
|
||||
return;
|
||||
if (curPopulateType == BfIRPopulateType_Full)
|
||||
return;
|
||||
|
||||
auto typeInst = type->ToTypeInstance();
|
||||
|
||||
if ((curPopulateType < BfIRPopulateType_Declaration) && (populateType >= BfIRPopulateType_Declaration))
|
||||
{
|
||||
CreateTypeDeclaration(type);
|
||||
CreateTypeDeclaration(type, populateType == BfIRPopulateType_Full_ForceDefinition);
|
||||
|
||||
mTypeMap[type] = BfIRPopulateType_Declaration;
|
||||
}
|
||||
|
@ -3106,7 +3108,7 @@ void BfIRBuilder::PopulateType(BfType* type, BfIRPopulateType populateType)
|
|||
if ((curPopulateType < populateType) && (populateType >= BfIRPopulateType_Eventually_Full))
|
||||
{
|
||||
mTypeMap[type] = BfIRPopulateType_Eventually_Full;
|
||||
CreateTypeDefinition(type);
|
||||
CreateTypeDefinition(type, populateType == BfIRPopulateType_Full_ForceDefinition);
|
||||
mTypeMap[type] = BfIRPopulateType_Full;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -836,7 +836,8 @@ enum BfIRPopulateType
|
|||
BfIRPopulateType_Identity,
|
||||
BfIRPopulateType_Declaration,
|
||||
BfIRPopulateType_Eventually_Full,
|
||||
BfIRPopulateType_Full
|
||||
BfIRPopulateType_Full,
|
||||
BfIRPopulateType_Full_ForceDefinition
|
||||
};
|
||||
|
||||
class BfIRBuilder : public BfIRConstHolder
|
||||
|
@ -934,8 +935,8 @@ public:
|
|||
BfIRMDNode CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope);
|
||||
String GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName);
|
||||
void CreateDbgTypeDefinition(BfType* type);
|
||||
void CreateTypeDeclaration(BfType* type);
|
||||
void CreateTypeDefinition(BfType* type);
|
||||
void CreateTypeDeclaration(BfType* type, bool forceDefine);
|
||||
void CreateTypeDefinition(BfType* type, bool forceDefine);
|
||||
void ReplaceDITemporaryTypes();
|
||||
void PushDbgLoc(BfTypeInstance* typeInst);
|
||||
BfIRPopulateType GetPopulateTypeState(BfType* type);
|
||||
|
|
|
@ -1118,10 +1118,10 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
|
|||
// code as we walk the AST
|
||||
//mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||
if (
|
||||
(mModuleName == "vdata")
|
||||
|| (mModuleName == "System_Result_PTR_void")
|
||||
(mModuleName == "-")
|
||||
//|| (mModuleName == "System_Internal")
|
||||
//|| (mModuleName == "vdata")
|
||||
|| (mModuleName == "Hey_Dude_Bro_TestClass")
|
||||
//|| (mModuleName == "Hey_Dude_Bro_TestClass")
|
||||
)
|
||||
mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||
|
||||
|
@ -4241,7 +4241,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
|
||||
BfTypeInstance* typeInstance = type->ToTypeInstance();
|
||||
|
||||
// BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef, BfPopulateType_Identity);
|
||||
// mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
|
||||
// PopulateType(typeInstanceType);
|
||||
|
||||
BfType* typeInstanceType = ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef);
|
||||
mBfIRBuilder->PopulateType(typeInstanceType, BfIRPopulateType_Full_ForceDefinition);
|
||||
|
||||
if (typeInstanceType == NULL)
|
||||
{
|
||||
AssertErrorState();
|
||||
|
@ -18900,7 +18906,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
isValid = true;
|
||||
}
|
||||
else if ((genericParamInstance->mTypeConstraint->IsDelegate()) || (genericParamInstance->mTypeConstraint->IsFunction()) ||
|
||||
((genericParamInstance != NULL) &&
|
||||
((genericParamInstance != NULL) && (typeInstConstraint != NULL) &&
|
||||
((typeInstConstraint->mTypeDef == mCompiler->mDelegateTypeDef) || (typeInstConstraint->mTypeDef == mCompiler->mFunctionTypeDef))))
|
||||
{
|
||||
mCurMethodInstance->mHadGenericDelegateParams = true;
|
||||
|
|
|
@ -165,10 +165,10 @@ bool BfModule::BuildGenericParams(BfType* resolvedTypeRef)
|
|||
else
|
||||
{
|
||||
for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mTypeGenericArguments.size(); paramIdx++)
|
||||
{
|
||||
auto genericParamDef = typeDef->mGenericParamDefs[paramIdx];
|
||||
{
|
||||
auto genericParamInstance = genericTypeInst->mGenericParams[paramIdx];
|
||||
ResolveGenericParamConstraints(genericParamInstance, typeDef->mGenericParamDefs, paramIdx);
|
||||
auto genericParamDef = typeDef->mGenericParamDefs[paramIdx];
|
||||
|
||||
for (auto nameNode : genericParamDef->mNameNodes)
|
||||
{
|
||||
|
|
|
@ -811,7 +811,7 @@ int BfMethodInstance::DbgGetVirtualMethodNum()
|
|||
vDataIdx += mVirtualTableIdx;
|
||||
}
|
||||
if (vDataVal == -1)
|
||||
vDataVal = vDataIdx * module->mSystem->mPtrSize;
|
||||
vDataVal = vDataIdx;
|
||||
}
|
||||
return vDataVal;
|
||||
}
|
||||
|
|
|
@ -4877,11 +4877,23 @@ void DbgModule::CommitHotTargetSections()
|
|||
addr_target hotAddr = GetHotTargetAddress(hotTargetSection);
|
||||
if (hotAddr != 0)
|
||||
{
|
||||
void* imageDestPtr = mOrigImageData->mBlocks[0] + hotTargetSection->mImageOffset;
|
||||
if (hotTargetSection->mData != NULL)
|
||||
memcpy(imageDestPtr, hotTargetSection->mData, hotTargetSection->mDataSize);
|
||||
else
|
||||
// void* imageDestPtr = mOrigImageData->mBlocks[0] + hotTargetSection->mImageOffset;
|
||||
// if (hotTargetSection->mData != NULL)
|
||||
// memcpy(imageDestPtr, hotTargetSection->mData, hotTargetSection->mDataSize);
|
||||
// else
|
||||
// memset(imageDestPtr, 0, hotTargetSection->mDataSize);
|
||||
|
||||
BF_ASSERT(mOrigImageData->mAddr != 0);
|
||||
|
||||
void* imageDestPtr = hotTargetSection->mData;
|
||||
bool isTemp = false;
|
||||
if (imageDestPtr == NULL)
|
||||
{
|
||||
imageDestPtr = new uint8[hotTargetSection->mDataSize];
|
||||
memset(imageDestPtr, 0, hotTargetSection->mDataSize);
|
||||
isTemp = true;
|
||||
}
|
||||
|
||||
if (hotTargetSection->mCanExecute)
|
||||
{
|
||||
bool success = mDebugger->WriteInstructions(hotAddr, imageDestPtr, hotTargetSection->mDataSize);
|
||||
|
@ -4892,6 +4904,9 @@ void DbgModule::CommitHotTargetSections()
|
|||
bool success = mDebugger->WriteMemory(hotAddr, imageDestPtr, hotTargetSection->mDataSize);
|
||||
BF_ASSERT(success);
|
||||
}
|
||||
|
||||
if (isTemp)
|
||||
delete imageDestPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5664,7 +5679,8 @@ bool DbgModule::ReadCOFF(DataStream* stream, bool isHotObjectFile)
|
|||
mDebugger->ReserveHotTargetMemory(needHotTargetMemory);
|
||||
|
||||
// '0' address is temporary
|
||||
mOrigImageData = new DbgModuleMemoryCache(0, NULL, needHotTargetMemory, true);
|
||||
//mOrigImageData = new DbgModuleMemoryCache(0, NULL, needHotTargetMemory, true);
|
||||
mOrigImageData = new DbgModuleMemoryCache(0, needHotTargetMemory);
|
||||
}
|
||||
|
||||
int numSections = ntHdr.mFileHeader.mNumberOfSections;
|
||||
|
|
|
@ -1939,14 +1939,32 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe
|
|||
if (outReturnAddressLoc != NULL)
|
||||
*outReturnAddressLoc = 0;
|
||||
|
||||
// Don't even try to use the frame descriptor in x64, the exception directory
|
||||
// allows us to rollback from any instruction
|
||||
#ifdef BF_DBG_32
|
||||
CPUInst inst;
|
||||
if (DecodeInstruction(registers->GetPC(), &inst))
|
||||
{
|
||||
if (inst.IsReturn())
|
||||
{
|
||||
// If we are literally just a return then often the frame descriptor is wrong,
|
||||
// but we know this is ACTUALLY just a simple rollback
|
||||
|
||||
int regSize = sizeof(addr_target);
|
||||
addr_target* regPC = registers->GetPCRegisterRef();
|
||||
addr_target* regSP = registers->GetSPRegisterRef();
|
||||
|
||||
addr_target newPC = 0;
|
||||
gDebugger->ReadMemory(*regSP, sizeof(addr_target), &newPC);
|
||||
*regSP += regSize;
|
||||
*regPC = newPC;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BF_DBG_32
|
||||
if (RollBackStackFrame_DwFrameDescriptor(registers, outReturnAddressLoc))
|
||||
return true;
|
||||
if (RollBackStackFrame_COFFFrameDescriptor(registers, outReturnAddressLoc, isStackStart))
|
||||
return true;
|
||||
addr_target pc = registers->GetPC();
|
||||
auto pc = registers->GetPC();
|
||||
DbgSubprogram* dbgSubprogram = FindSubProgram(pc);
|
||||
if (dbgSubprogram != NULL)
|
||||
{
|
||||
|
|
|
@ -16,33 +16,35 @@ DbgModuleMemoryCache::DbgModuleMemoryCache(uintptr addr, int size)
|
|||
mBlocks = new uint8*[mBlockCount];
|
||||
memset(mBlocks, 0, mBlockCount * sizeof(uint8*));
|
||||
mFlags = new DbgMemoryFlags[mBlockCount];
|
||||
memset(mBlocks, 0, mBlockCount * sizeof(DbgMemoryFlags));
|
||||
memset(mFlags, 0, mBlockCount * sizeof(DbgMemoryFlags));
|
||||
mOwns = true;
|
||||
}
|
||||
|
||||
DbgModuleMemoryCache::DbgModuleMemoryCache(uintptr addr, uint8* data, int size, bool makeCopy)
|
||||
{
|
||||
mAddr = addr;
|
||||
mBlockSize = size;
|
||||
mBlocks = new uint8*[1];
|
||||
mFlags = new DbgMemoryFlags[1];
|
||||
mSize = size;
|
||||
|
||||
if (makeCopy)
|
||||
{
|
||||
uint8* dataCopy = new uint8[size];
|
||||
if (data != NULL)
|
||||
memcpy(dataCopy, data, size);
|
||||
mBlocks[0] = dataCopy;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBlocks[0] = data;
|
||||
}
|
||||
|
||||
mOwns = makeCopy;
|
||||
mBlockCount = 1;
|
||||
}
|
||||
// DbgModuleMemoryCache::DbgModuleMemoryCache(uintptr addr, uint8* data, int size, bool makeCopy)
|
||||
// {
|
||||
// mAddr = addr;
|
||||
// mBlockSize = size;
|
||||
// mBlocks = new uint8*[1];
|
||||
// mFlags = new DbgMemoryFlags[1];
|
||||
// mSize = size;
|
||||
//
|
||||
// if (makeCopy)
|
||||
// {
|
||||
// uint8* dataCopy = new uint8[size];
|
||||
// if (data != NULL)
|
||||
// memcpy(dataCopy, data, size);
|
||||
// else
|
||||
// memset(dataCopy, 0, size);
|
||||
// mBlocks[0] = dataCopy;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// mBlocks[0] = data;
|
||||
// }
|
||||
//
|
||||
// mOwns = makeCopy;
|
||||
// mBlockCount = 1;
|
||||
// }
|
||||
|
||||
DbgModuleMemoryCache::~DbgModuleMemoryCache()
|
||||
{
|
||||
|
@ -57,13 +59,17 @@ DbgModuleMemoryCache::~DbgModuleMemoryCache()
|
|||
|
||||
DbgMemoryFlags DbgModuleMemoryCache::Read(uintptr addr, uint8* data, int size)
|
||||
{
|
||||
BF_ASSERT(mAddr != 0);
|
||||
|
||||
int sizeLeft = size;
|
||||
DbgMemoryFlags flags = DbgMemoryFlags_None;
|
||||
|
||||
if ((addr < mAddr) || (addr > mAddr + mSize))
|
||||
{
|
||||
gDebugger->ReadMemory(addr, size, data);
|
||||
return gDebugger->GetMemoryFlags(addr);
|
||||
flags = gDebugger->GetMemoryFlags(addr);
|
||||
BfLogDbg("Got memory flags %p = %d\n", addr, flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
int relAddr = (int)(addr - mAddr);
|
||||
|
@ -80,7 +86,7 @@ DbgMemoryFlags DbgModuleMemoryCache::Read(uintptr addr, uint8* data, int size)
|
|||
mBlocks[blockIdx] = block;
|
||||
|
||||
mFlags[blockIdx] = gDebugger->GetMemoryFlags(mAddr + blockIdx * mBlockSize);
|
||||
//BfLogDbg("Memory flags for %p = %d\n", mAddr + blockIdx * mBlockSize, mFlags[blockIdx]);
|
||||
BfLogDbg("Memory flags for %p = %d\n", mAddr + blockIdx * mBlockSize, mFlags[blockIdx]);
|
||||
}
|
||||
|
||||
flags = mFlags[blockIdx];
|
||||
|
|
|
@ -192,7 +192,7 @@ public:
|
|||
|
||||
public:
|
||||
DbgModuleMemoryCache(uintptr addr, int size);
|
||||
DbgModuleMemoryCache(uintptr addr, uint8* data, int size, bool makeCopy);
|
||||
//DbgModuleMemoryCache(uintptr addr, uint8* data, int size, bool makeCopy);
|
||||
~DbgModuleMemoryCache();
|
||||
|
||||
DbgMemoryFlags Read(uintptr addr, uint8* data, int size);
|
||||
|
|
|
@ -522,7 +522,7 @@ WinDebugger::WinDebugger(DebugManager* debugManager) : mDbgSymSrv(this)
|
|||
mDbgProcessHandle = 0;
|
||||
mDbgThreadHandle = 0;
|
||||
mDbgProcessId = 0;
|
||||
mIsPartialCallStack = false;
|
||||
mIsPartialCallStack = true;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
|
@ -675,6 +675,9 @@ void WinDebugger::PhysSetBreakpoint(addr_target address)
|
|||
if ((flags & DbgMemoryFlags_Execute) == 0)
|
||||
{
|
||||
BfLogDbg("Breakpoint ignored - execute flag NOT set in breakpoint address\n", address);
|
||||
|
||||
BfLogDbg("Memory Flags = %d\n", gDebugger->GetMemoryFlags(address));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1289,6 +1292,7 @@ void WinDebugger::Detach()
|
|||
mRunState = RunState_NotStarted;
|
||||
mStepType = StepType_None;
|
||||
mHadImageFindError = false;
|
||||
mIsPartialCallStack = true;
|
||||
|
||||
delete mDebugPendingExpr;
|
||||
mDebugPendingExpr = NULL;
|
||||
|
@ -2007,9 +2011,8 @@ bool WinDebugger::DoUpdate()
|
|||
isDeeper = mStepSP > BF_CONTEXT_SP(lcContext);
|
||||
if ((mStepType == StepType_StepOut) || (mStepType == StepType_StepOut_ThenInto))
|
||||
{
|
||||
BfLogDbg("StepOut Iteration SP:%p StartSP:%p\n", BF_CONTEXT_SP(lcContext), mStepSP);
|
||||
|
||||
isDeeper = mStepSP >= BF_CONTEXT_SP(lcContext);
|
||||
BfLogDbg("StepOut Iteration SP:%p StartSP:%p IsDeeper:%d\n", BF_CONTEXT_SP(lcContext), mStepSP, isDeeper);
|
||||
}
|
||||
|
||||
if (((mStepType == StepType_StepOut) || (mStepType == StepType_StepOut_ThenInto)) && (breakpoint == NULL) && (isDeeper))
|
||||
|
@ -3637,11 +3640,11 @@ bool WinDebugger::CheckConditionalBreakpoint(WdBreakpoint* breakpoint, DbgSubpro
|
|||
conditional->mDbgEvaluationContext->mDbgExprEvaluator->mExpressionFlags = (DwEvalExpressionFlags)(DwEvalExpressionFlag_AllowSideEffects | DwEvalExpressionFlag_AllowCalls);
|
||||
}
|
||||
|
||||
WdStackFrame wdStackFrame;
|
||||
PopulateRegisters(&wdStackFrame.mRegisters);
|
||||
mCallStack.push_back(&wdStackFrame);
|
||||
WdStackFrame* wdStackFrame = new WdStackFrame();
|
||||
PopulateRegisters(&wdStackFrame->mRegisters);
|
||||
mCallStack.Add(wdStackFrame);
|
||||
DbgTypedValue result = conditional->mDbgEvaluationContext->EvaluateInContext(DbgTypedValue());
|
||||
mCallStack.pop_back();
|
||||
ClearCallStack();
|
||||
|
||||
if (conditional->mDbgEvaluationContext->mPassInstance->HasFailed())
|
||||
{
|
||||
|
@ -3744,6 +3747,8 @@ void WinDebugger::CleanupDebugEval(bool restoreRegisters)
|
|||
{
|
||||
SetAndRestoreValue<WdThreadInfo*> activeThread(mActiveThread, evalThreadInfo);
|
||||
RestoreAllRegisters();
|
||||
// if (mRunState == RunState_Running_ToTempBreakpoint)
|
||||
// mRunState = RunState_Paused;
|
||||
}
|
||||
|
||||
evalThreadInfo->mStartSP = mDebugEvalThreadInfo.mStartSP;
|
||||
|
@ -4110,10 +4115,19 @@ void WinDebugger::RestoreAllRegisters()
|
|||
BF_SetThreadContext(mActiveThread->mHThread, &mSavedContext);
|
||||
|
||||
#ifdef BF_DBG_32
|
||||
SetTempBreakpoint(mSavedContext.Eip);
|
||||
mRunState = RunState_Running_ToTempBreakpoint;
|
||||
mStepType = StepType_ToTempBreakpoint;
|
||||
mSteppingThread = mActiveThread;
|
||||
//TODO: Find the test that this was required for...
|
||||
// if (mActiveThread->mIsAtBreakpointAddress == mSavedContext.Eip)
|
||||
// {
|
||||
// if (mRunState == RunState_Running_ToTempBreakpoint)
|
||||
// mRunState = RunState_Paused;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// SetTempBreakpoint(mSavedContext.Eip);
|
||||
// mRunState = RunState_Running_ToTempBreakpoint;
|
||||
// mStepType = StepType_ToTempBreakpoint;
|
||||
// mSteppingThread = mActiveThread;
|
||||
// }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -4280,6 +4294,42 @@ bool WinDebugger::SetupStep(StepType stepType)
|
|||
if ((mStepType != StepType_StepOut_NoFrame) && (RollBackStackFrame(®isters, true)))
|
||||
{
|
||||
pcAddress = registers.GetPC();
|
||||
|
||||
addr_target oldAddress = pcAddress;
|
||||
|
||||
CPUInst inst;
|
||||
while (true)
|
||||
{
|
||||
if (!mDebugTarget->DecodeInstruction(pcAddress, &inst))
|
||||
break;
|
||||
if ((inst.IsBranch()) || (inst.IsCall()) || (inst.IsReturn()))
|
||||
break;
|
||||
DbgSubprogram* checkSubprogram = NULL;
|
||||
auto checkLineData = FindLineDataAtAddress(pcAddress, &checkSubprogram, NULL, NULL, DbgOnDemandKind_LocalOnly);
|
||||
if (checkLineData == NULL)
|
||||
break;
|
||||
if (checkSubprogram->GetLineAddr(*checkLineData) == pcAddress)
|
||||
break;
|
||||
pcAddress += inst.GetLength();
|
||||
}
|
||||
|
||||
if (pcAddress != oldAddress)
|
||||
{
|
||||
BfLogDbg("Adjusting stepout address from %p to %p\n", oldAddress, pcAddress);
|
||||
}
|
||||
|
||||
#ifdef BF_DBG_32
|
||||
// if (mDebugTarget->DecodeInstruction(pcAddress, &inst))
|
||||
// {
|
||||
// if (inst.IsStackAdjust())
|
||||
// {
|
||||
// auto oldAddress = pcAddress;
|
||||
// pcAddress += inst.GetLength();
|
||||
// BfLogDbg("Adjusting stepout address from %p to %p\n", oldAddress, pcAddress);
|
||||
// }
|
||||
// }
|
||||
#endif
|
||||
|
||||
BfLogDbg("SetupStep Stepout SetTempBreakpoint %p\n", pcAddress);
|
||||
SetTempBreakpoint(pcAddress);
|
||||
mStepBreakpointAddrs.push_back(pcAddress);
|
||||
|
@ -4380,10 +4430,16 @@ bool WinDebugger::SetupStep(StepType stepType)
|
|||
breakOnNext = true;
|
||||
}
|
||||
|
||||
if ((inst.IsReturn()) && (instIdx == 0) && (!mStepInAssembly))
|
||||
{
|
||||
// Do actual STEP OUT so we set up proper "stepping over unimportant post-return instructions"
|
||||
return SetupStep(StepType_StepOut);
|
||||
}
|
||||
|
||||
if ((breakOnNext) || (mStepInAssembly) || (isAtLine) || (inst.IsBranch()) || (inst.IsCall()) || (inst.IsReturn()))
|
||||
{
|
||||
if (((instIdx == 0) || (mStepInAssembly)) && (!breakOnNext))
|
||||
{
|
||||
{
|
||||
if ((stepType == StepType_StepOver) && (inst.IsCall()))
|
||||
{
|
||||
// Continue - sets a breakpoint on the call line to detect recursion.
|
||||
|
@ -4621,6 +4677,8 @@ void WinDebugger::CheckNonDebuggerBreak()
|
|||
return;
|
||||
}
|
||||
|
||||
bool showMainThread = false;
|
||||
|
||||
String symbol;
|
||||
addr_target offset;
|
||||
DbgModule* dbgModule;
|
||||
|
@ -4628,17 +4686,28 @@ void WinDebugger::CheckNonDebuggerBreak()
|
|||
{
|
||||
if (symbol == "DbgBreakPoint")
|
||||
{
|
||||
// This is a manual break, show the main thread
|
||||
mActiveThread = mThreadList.front();
|
||||
if (mDebugPendingExpr != NULL)
|
||||
showMainThread = true;
|
||||
}
|
||||
}
|
||||
#ifdef BF_DBG_32
|
||||
else if ((dbgModule != NULL) && (dbgModule->mDisplayName.Equals("kernel32.dll", StringImpl::CompareKind_OrdinalIgnoreCase)))
|
||||
{
|
||||
showMainThread = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (showMainThread)
|
||||
{
|
||||
// This is a manual break, show the main thread
|
||||
mActiveThread = mThreadList.front();
|
||||
if (mDebugPendingExpr != NULL)
|
||||
{
|
||||
for (auto thread : mThreadList)
|
||||
{
|
||||
for (auto thread : mThreadList)
|
||||
if (thread->mThreadId == mDebugEvalThreadInfo.mThreadId)
|
||||
{
|
||||
if (thread->mThreadId == mDebugEvalThreadInfo.mThreadId)
|
||||
{
|
||||
mActiveThread = thread;
|
||||
break;
|
||||
}
|
||||
mActiveThread = thread;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8754,8 +8823,10 @@ DbgSubprogram* WinDebugger::GetCallStackSubprogram(int callStackIdx)
|
|||
return NULL;
|
||||
if (callStackIdx >= (int)mCallStack.size())
|
||||
UpdateCallStack();
|
||||
if (mCallStack.IsEmpty())
|
||||
return NULL;
|
||||
if (callStackIdx >= (int)mCallStack.size())
|
||||
callStackIdx = 0;
|
||||
callStackIdx = 0;
|
||||
UpdateCallStackMethod(callStackIdx);
|
||||
auto subProgram = mCallStack[callStackIdx]->mSubProgram;
|
||||
return subProgram;
|
||||
|
@ -8767,6 +8838,8 @@ DbgCompileUnit* WinDebugger::GetCallStackCompileUnit(int callStackIdx)
|
|||
return NULL;
|
||||
if (callStackIdx >= (int)mCallStack.size())
|
||||
UpdateCallStack();
|
||||
if (mCallStack.IsEmpty())
|
||||
return NULL;
|
||||
if (callStackIdx >= (int)mCallStack.size())
|
||||
callStackIdx = 0;
|
||||
UpdateCallStackMethod(callStackIdx);
|
||||
|
|
|
@ -151,6 +151,11 @@ int X86Instr::GetLength()
|
|||
return mSize;
|
||||
}
|
||||
|
||||
bool X86Instr::IsStackAdjust()
|
||||
{
|
||||
return mMCInst.getOpcode() == X86::SUB32ri8;
|
||||
}
|
||||
|
||||
bool X86Instr::IsBranch()
|
||||
{
|
||||
const MCInstrDesc &instDesc = mX86->mInstrInfo->get(mMCInst.getOpcode());
|
||||
|
|
|
@ -292,6 +292,7 @@ public:
|
|||
}
|
||||
|
||||
int GetLength();
|
||||
bool IsStackAdjust();
|
||||
bool IsBranch();
|
||||
bool IsCall();
|
||||
bool IsRep(bool& isPrefixOnly);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue