mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Improved hot compilation handling of DLLs
This commit is contained in:
parent
990b509111
commit
c7ae0988dc
9 changed files with 84 additions and 9 deletions
|
@ -16,6 +16,7 @@ namespace IDE
|
||||||
case DebugAfter;
|
case DebugAfter;
|
||||||
case DebugComptime;
|
case DebugComptime;
|
||||||
case Test;
|
case Test;
|
||||||
|
case WhileRunning;
|
||||||
|
|
||||||
public bool WantsRunAfter
|
public bool WantsRunAfter
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,8 @@ namespace IDE.Debugger
|
||||||
Terminating,
|
Terminating,
|
||||||
Terminated,
|
Terminated,
|
||||||
SearchingSymSrv,
|
SearchingSymSrv,
|
||||||
HotResolve
|
HotResolve,
|
||||||
|
TargetUnloaded
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum IntDisplayType
|
public enum IntDisplayType
|
||||||
|
@ -172,6 +173,9 @@ namespace IDE.Debugger
|
||||||
[CallingConvention(.Stdcall),CLink]
|
[CallingConvention(.Stdcall),CLink]
|
||||||
static extern RunState Debugger_GetRunState();
|
static extern RunState Debugger_GetRunState();
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall),CLink]
|
||||||
|
static extern bool Debugger_HasLoadedTargetBinary();
|
||||||
|
|
||||||
[CallingConvention(.Stdcall),CLink]
|
[CallingConvention(.Stdcall),CLink]
|
||||||
static extern char8* Debugger_GetCurrentException();
|
static extern char8* Debugger_GetCurrentException();
|
||||||
|
|
||||||
|
@ -534,6 +538,11 @@ namespace IDE.Debugger
|
||||||
return Debugger_GetRunState();
|
return Debugger_GetRunState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasLoadedTargetBinary()
|
||||||
|
{
|
||||||
|
return Debugger_HasLoadedTargetBinary();
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasPendingDebugLoads()
|
public bool HasPendingDebugLoads()
|
||||||
{
|
{
|
||||||
return Debugger_HasPendingDebugLoads();
|
return Debugger_HasPendingDebugLoads();
|
||||||
|
@ -561,8 +570,8 @@ namespace IDE.Debugger
|
||||||
public bool IsPaused(bool allowDebugEvalDone = false)
|
public bool IsPaused(bool allowDebugEvalDone = false)
|
||||||
{
|
{
|
||||||
RunState runState = GetRunState();
|
RunState runState = GetRunState();
|
||||||
return (runState == RunState.Paused) || (runState == RunState.Breakpoint) || (runState == RunState.Exception) ||
|
return (runState == .Paused) || (runState == .Breakpoint) || (runState == .Exception) ||
|
||||||
((runState == RunState.DebugEval_Done) && (allowDebugEvalDone));
|
((runState == .DebugEval_Done) && (allowDebugEvalDone));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetCurrentException(String exStr)
|
public void GetCurrentException(String exStr)
|
||||||
|
|
|
@ -4501,6 +4501,10 @@ namespace IDE
|
||||||
Compile(compileKind, null);
|
Compile(compileKind, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((mDebugger.mIsRunning) && (!mDebugger.HasLoadedTargetBinary()))
|
||||||
|
{
|
||||||
|
Compile(.WhileRunning, null);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mOutputPanel.Clear();
|
mOutputPanel.Clear();
|
||||||
|
@ -11588,7 +11592,7 @@ namespace IDE
|
||||||
if (mExecutionQueue.Count > 0)
|
if (mExecutionQueue.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((mDebugger != null) && (mDebugger.mIsRunning) && (hotProject == null))
|
if ((mDebugger != null) && (mDebugger.mIsRunning) && (hotProject == null) && (compileKind != .WhileRunning))
|
||||||
{
|
{
|
||||||
Debug.Assert(!mDebugger.mIsRunningCompiled);
|
Debug.Assert(!mDebugger.mIsRunningCompiled);
|
||||||
Debug.Assert((compileKind == .Normal) || (compileKind == .DebugComptime));
|
Debug.Assert((compileKind == .Normal) || (compileKind == .DebugComptime));
|
||||||
|
@ -13416,8 +13420,9 @@ namespace IDE
|
||||||
mBreakpointPanel.MarkStatsDirty();
|
mBreakpointPanel.MarkStatsDirty();
|
||||||
mTargetHadFirstBreak = true;
|
mTargetHadFirstBreak = true;
|
||||||
|
|
||||||
if (mDebugger.GetRunState() == DebugManager.RunState.Exception)
|
switch (mDebugger.GetRunState())
|
||||||
{
|
{
|
||||||
|
case .Exception:
|
||||||
String exceptionLine = scope String();
|
String exceptionLine = scope String();
|
||||||
mDebugger.GetCurrentException(exceptionLine);
|
mDebugger.GetCurrentException(exceptionLine);
|
||||||
var exceptionData = String.StackSplit!(exceptionLine, '\n');
|
var exceptionData = String.StackSplit!(exceptionLine, '\n');
|
||||||
|
@ -13431,11 +13436,26 @@ namespace IDE
|
||||||
OutputLine(exString);
|
OutputLine(exString);
|
||||||
if (!IsCrashDump)
|
if (!IsCrashDump)
|
||||||
Fail(exString);
|
Fail(exString);
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if ((mDebugger != null) && (mDebugger.GetRunState() == .TargetUnloaded))
|
||||||
|
{
|
||||||
|
if (mWorkspace.mHadHotCompileSinceLastFullCompile)
|
||||||
|
{
|
||||||
|
// Had hot compiles - we need to recompile!
|
||||||
|
Compile(.WhileRunning);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mDebugger.Continue();
|
||||||
|
}
|
||||||
|
mWorkspace.StoppedRunning();
|
||||||
|
break;
|
||||||
|
}
|
||||||
else if (mDebuggerPerformingTask)
|
else if (mDebuggerPerformingTask)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1108,6 +1108,14 @@ BF_EXPORT int BF_CALLTYPE Debugger_GetRunState()
|
||||||
return gDebugger->mRunState;
|
return gDebugger->mRunState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_EXPORT bool Debugger_HasLoadedTargetBinary()
|
||||||
|
{
|
||||||
|
AutoCrit autoCrit(gDebugManager->mCritSect);
|
||||||
|
if (gDebugger == NULL)
|
||||||
|
return false;
|
||||||
|
return gDebugger->HasLoadedTargetBinary();
|
||||||
|
}
|
||||||
|
|
||||||
BF_EXPORT bool BF_CALLTYPE Debugger_HasPendingDebugLoads()
|
BF_EXPORT bool BF_CALLTYPE Debugger_HasPendingDebugLoads()
|
||||||
{
|
{
|
||||||
if (gDebugger == NULL)
|
if (gDebugger == NULL)
|
||||||
|
|
|
@ -30,6 +30,8 @@ DebugTarget::DebugTarget(WinDebugger* debugger)
|
||||||
mCapturedNamesPtr = NULL;
|
mCapturedNamesPtr = NULL;
|
||||||
mCapturedTypesPtr = NULL;
|
mCapturedTypesPtr = NULL;
|
||||||
mHotHeap = NULL;
|
mHotHeap = NULL;
|
||||||
|
mHotHeapAddr = 0;
|
||||||
|
mHotHeapReserveSize = 0;
|
||||||
mLastHotHeapCleanIdx = 0;
|
mLastHotHeapCleanIdx = 0;
|
||||||
mIsEmpty = false;
|
mIsEmpty = false;
|
||||||
mWasLocallyBuilt = false;
|
mWasLocallyBuilt = false;
|
||||||
|
@ -107,12 +109,18 @@ void DebugTarget::SetupTargetBinary()
|
||||||
{
|
{
|
||||||
reservedPtr = (addr_target)VirtualAllocEx(mDebugger->mProcessInfo.hProcess, (void*)(intptr)checkHotReserveAddr, reserveSize, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
reservedPtr = (addr_target)VirtualAllocEx(mDebugger->mProcessInfo.hProcess, (void*)(intptr)checkHotReserveAddr, reserveSize, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
if (reservedPtr != NULL)
|
if (reservedPtr != NULL)
|
||||||
|
{
|
||||||
|
mHotHeapAddr = reservedPtr;
|
||||||
|
mHotHeapReserveSize = reserveSize;
|
||||||
|
BfLogDbg("VirtualAllocEx %p %d. ImageBase: %p\n", mHotHeapAddr, mHotHeapReserveSize, mTargetBinary->mImageBase);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
checkHotReserveAddr += 4 * mb;
|
checkHotReserveAddr += 4 * mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reservedPtr == 0)
|
if (reservedPtr == 0)
|
||||||
{
|
{
|
||||||
|
BfLogDbg("VirtualAllocEx failed. ImageBase: %p\n", mTargetBinary->mImageBase);
|
||||||
mDebugger->Fail("Failed to reserve memory for hot swapping");
|
mDebugger->Fail("Failed to reserve memory for hot swapping");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -207,7 +215,7 @@ DbgModule* DebugTarget::SetupDyn(const StringImpl& filePath, DataStream* stream,
|
||||||
{
|
{
|
||||||
BP_ZONE("DebugTarget::SetupDyn");
|
BP_ZONE("DebugTarget::SetupDyn");
|
||||||
|
|
||||||
AutoDbgTime dbgTime("DebugTarget::SetupDyn " + filePath);
|
//AutoDbgTime dbgTime("DebugTarget::SetupDyn " + filePath);
|
||||||
|
|
||||||
DbgModule* dwarf = new COFF(this);
|
DbgModule* dwarf = new COFF(this);
|
||||||
dwarf->mFilePath = filePath;
|
dwarf->mFilePath = filePath;
|
||||||
|
@ -239,7 +247,7 @@ String DebugTarget::UnloadDyn(addr_target imageBase)
|
||||||
{
|
{
|
||||||
String filePath;
|
String filePath;
|
||||||
|
|
||||||
AutoDbgTime dbgTime("DebugTarget::UnloadDyn");
|
//AutoDbgTime dbgTime("DebugTarget::UnloadDyn");
|
||||||
|
|
||||||
for (int i = 0; i < (int)mDbgModules.size(); i++)
|
for (int i = 0; i < (int)mDbgModules.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -252,7 +260,18 @@ String DebugTarget::UnloadDyn(addr_target imageBase)
|
||||||
filePath = dwarf->mFilePath;
|
filePath = dwarf->mFilePath;
|
||||||
|
|
||||||
if (mTargetBinary == dwarf)
|
if (mTargetBinary == dwarf)
|
||||||
|
{
|
||||||
mTargetBinary = NULL;
|
mTargetBinary = NULL;
|
||||||
|
delete mHotHeap;
|
||||||
|
mHotHeap = NULL;
|
||||||
|
|
||||||
|
if (mHotHeapAddr != 0)
|
||||||
|
{
|
||||||
|
BfLogDbg("VirtualFreeEx %p %d\n", mHotHeapAddr, mHotHeapReserveSize);
|
||||||
|
::VirtualFreeEx(mDebugger->mProcessInfo.hProcess, (void*)(intptr)mHotHeapAddr, 0, MEM_RELEASE);
|
||||||
|
mHotHeapAddr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mDbgModules.RemoveAt(i);
|
mDbgModules.RemoveAt(i);
|
||||||
bool success = mDbgModuleMap.Remove(dwarf->mId);
|
bool success = mDbgModuleMap.Remove(dwarf->mId);
|
||||||
|
|
|
@ -34,6 +34,8 @@ public:
|
||||||
Array<DbgType*>* mCapturedTypesPtr;
|
Array<DbgType*>* mCapturedTypesPtr;
|
||||||
|
|
||||||
HotHeap* mHotHeap;
|
HotHeap* mHotHeap;
|
||||||
|
addr_target mHotHeapAddr;
|
||||||
|
int64 mHotHeapReserveSize;
|
||||||
int mLastHotHeapCleanIdx;
|
int mLastHotHeapCleanIdx;
|
||||||
String mTargetPath;
|
String mTargetPath;
|
||||||
DbgModule* mLaunchBinary;
|
DbgModule* mLaunchBinary;
|
||||||
|
|
|
@ -159,7 +159,8 @@ enum RunState
|
||||||
RunState_Terminating,
|
RunState_Terminating,
|
||||||
RunState_Terminated,
|
RunState_Terminated,
|
||||||
RunState_SearchingSymSrv,
|
RunState_SearchingSymSrv,
|
||||||
RunState_HotResolve
|
RunState_HotResolve,
|
||||||
|
RunState_TargetUnloaded
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DebuggerResult
|
enum DebuggerResult
|
||||||
|
@ -268,6 +269,7 @@ public:
|
||||||
virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock, bool hotSwapEnabled) = 0;
|
virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock, bool hotSwapEnabled) = 0;
|
||||||
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) = 0;
|
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) = 0;
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
|
virtual bool HasLoadedTargetBinary() { return true; }
|
||||||
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) = 0;
|
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) = 0;
|
||||||
virtual void InitiateHotResolve(DbgHotResolveFlags flags) = 0;
|
virtual void InitiateHotResolve(DbgHotResolveFlags flags) = 0;
|
||||||
virtual intptr GetDbgAllocHeapSize() = 0;
|
virtual intptr GetDbgAllocHeapSize() = 0;
|
||||||
|
|
|
@ -1067,6 +1067,13 @@ void WinDebugger::Run()
|
||||||
CloseHandle(hThread);
|
CloseHandle(hThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WinDebugger::HasLoadedTargetBinary()
|
||||||
|
{
|
||||||
|
if (mDebugTarget == NULL)
|
||||||
|
return false;
|
||||||
|
return mDebugTarget->mTargetBinary != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void WinDebugger::HotLoad(const Array<String>& objectFiles, int hotIdx)
|
void WinDebugger::HotLoad(const Array<String>& objectFiles, int hotIdx)
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(mDebugManager->mCritSect);
|
AutoCrit autoCrit(mDebugManager->mCritSect);
|
||||||
|
@ -1891,10 +1898,16 @@ bool WinDebugger::DoUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hadTarget = mDebugTarget->mTargetBinary != NULL;
|
||||||
mDebugTarget->UnloadDyn(dbgModule->mImageBase);
|
mDebugTarget->UnloadDyn(dbgModule->mImageBase);
|
||||||
if (needsBreakpointRehup)
|
if (needsBreakpointRehup)
|
||||||
RehupBreakpoints(true);
|
RehupBreakpoints(true);
|
||||||
|
|
||||||
|
if ((mDebugTarget->mTargetBinary == NULL) && (hadTarget))
|
||||||
|
{
|
||||||
|
mRunState = RunState_TargetUnloaded;
|
||||||
|
}
|
||||||
|
|
||||||
mPendingDebugInfoLoad.Remove(dbgModule);
|
mPendingDebugInfoLoad.Remove(dbgModule);
|
||||||
mPendingDebugInfoRequests.Remove(dbgModule);
|
mPendingDebugInfoRequests.Remove(dbgModule);
|
||||||
mDebugManager->mOutMessages.push_back("modulesChanged");
|
mDebugManager->mOutMessages.push_back("modulesChanged");
|
||||||
|
@ -2880,7 +2893,7 @@ void WinDebugger::ContinueDebugEvent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mRunState == RunState_Breakpoint) || (mRunState == RunState_Paused))
|
if ((mRunState == RunState_Breakpoint) || (mRunState == RunState_Paused) || (mRunState == RunState_TargetUnloaded))
|
||||||
{
|
{
|
||||||
ClearCallStack();
|
ClearCallStack();
|
||||||
mRunState = RunState_Running;
|
mRunState = RunState_Running;
|
||||||
|
|
|
@ -584,6 +584,7 @@ public:
|
||||||
virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock, bool hotSwapEnabled) override;
|
virtual void OpenFile(const StringImpl& launchPath, const StringImpl& targetPath, const StringImpl& args, const StringImpl& workingDir, const Array<uint8>& envBlock, bool hotSwapEnabled) override;
|
||||||
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override;
|
virtual bool Attach(int processId, BfDbgAttachFlags attachFlags) override;
|
||||||
virtual void Run() override;
|
virtual void Run() override;
|
||||||
|
virtual bool HasLoadedTargetBinary() override;
|
||||||
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) override;
|
virtual void HotLoad(const Array<String>& objectFiles, int hotIdx) override;
|
||||||
virtual void InitiateHotResolve(DbgHotResolveFlags flags) override;
|
virtual void InitiateHotResolve(DbgHotResolveFlags flags) override;
|
||||||
virtual intptr GetDbgAllocHeapSize() override;
|
virtual intptr GetDbgAllocHeapSize() override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue