mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Improved debugger side effect handling, auto refresh options
This commit is contained in:
parent
7548bf23cd
commit
1484a5f53c
10 changed files with 150 additions and 30 deletions
|
@ -1017,6 +1017,25 @@ namespace System.Reflection
|
|||
strBuffer.Append(')');
|
||||
}
|
||||
|
||||
public void GetMethodSig(String strBuffer)
|
||||
{
|
||||
strBuffer.Append('(');
|
||||
int useParamIdx = 0;
|
||||
for (int paramIdx < ParamCount)
|
||||
{
|
||||
var flag = GetParamFlags(paramIdx);
|
||||
if (flag.HasFlag(.Implicit))
|
||||
continue;
|
||||
if (useParamIdx > 0)
|
||||
strBuffer.Append(", ");
|
||||
if (flag.HasFlag(.Params))
|
||||
strBuffer.Append("params ");
|
||||
strBuffer.Append(GetParamType(paramIdx));
|
||||
useParamIdx++;
|
||||
}
|
||||
strBuffer.Append(')');
|
||||
}
|
||||
|
||||
public void GetParamsDecl(String strBuffer)
|
||||
{
|
||||
int useParamIdx = 0;
|
||||
|
|
|
@ -432,7 +432,8 @@ namespace IDE.Debugger
|
|||
public int32 mActiveCallStackIdx;
|
||||
public Event<Action> mBreakpointsChangedDelegate ~ _.Dispose();
|
||||
public Breakpoint mRunToCursorBreakpoint;
|
||||
public int32 mDebugIdx;
|
||||
public int32 mSessionIdx;
|
||||
public int32 mStateIdx;
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
|
@ -466,6 +467,17 @@ namespace IDE.Debugger
|
|||
Debugger_Delete();
|
||||
}
|
||||
|
||||
public void IncrementSessionIdx()
|
||||
{
|
||||
mSessionIdx++;
|
||||
mStateIdx++;
|
||||
}
|
||||
|
||||
public void IncrementStateIdx()
|
||||
{
|
||||
mStateIdx++;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
for (var breakpoint in mBreakpointList)
|
||||
|
|
|
@ -4864,7 +4864,7 @@ namespace IDE
|
|||
{
|
||||
if (mDebugger.mIsRunning)
|
||||
{
|
||||
if (mExecutionPaused)
|
||||
if ((mExecutionPaused) && (mDebugger.IsPaused()))
|
||||
{
|
||||
DebuggerUnpaused();
|
||||
mDebugger.StepInto(IsInDisassemblyMode());
|
||||
|
@ -4882,7 +4882,7 @@ namespace IDE
|
|||
mStepCount++;
|
||||
if (mDebugger.mIsRunning)
|
||||
{
|
||||
if (mExecutionPaused)
|
||||
if ((mExecutionPaused) && (mDebugger.IsPaused()))
|
||||
{
|
||||
DebuggerUnpaused();
|
||||
mDebugger.StepOver(IsInDisassemblyMode());
|
||||
|
@ -4902,7 +4902,7 @@ namespace IDE
|
|||
[IDECommand]
|
||||
void StepOut()
|
||||
{
|
||||
if (mExecutionPaused)
|
||||
if ((mExecutionPaused) && (mDebugger.IsPaused()))
|
||||
{
|
||||
DebuggerUnpaused();
|
||||
mDebugger.StepOut(IsInDisassemblyMode());
|
||||
|
@ -12437,7 +12437,7 @@ namespace IDE
|
|||
CheckDebugVisualizers();
|
||||
|
||||
mDebugger.mIsRunning = true;
|
||||
mDebugger.mDebugIdx++;
|
||||
mDebugger.IncrementSessionIdx();
|
||||
WithSourceViewPanels(scope (sourceView) =>
|
||||
{
|
||||
sourceView.RehupAlias();
|
||||
|
@ -12496,7 +12496,7 @@ namespace IDE
|
|||
|
||||
CheckDebugVisualizers();
|
||||
mDebugger.mIsRunning = true;
|
||||
mDebugger.mDebugIdx++;
|
||||
mDebugger.IncrementSessionIdx();
|
||||
mDebugger.RehupBreakpoints(true);
|
||||
mDebugger.Run();
|
||||
mIsAttachPendingSourceShow = true;
|
||||
|
@ -12969,7 +12969,7 @@ namespace IDE
|
|||
if (mDebugger.OpenMiniDump(mCrashDumpPath))
|
||||
{
|
||||
mDebugger.mIsRunning = true;
|
||||
mDebugger.mDebugIdx++;
|
||||
mDebugger.IncrementSessionIdx();
|
||||
mExecutionPaused = false; // Make this false so we can detect a Pause immediately
|
||||
mIsAttachPendingSourceShow = true;
|
||||
}
|
||||
|
@ -13281,6 +13281,7 @@ namespace IDE
|
|||
|
||||
void DebuggerPaused()
|
||||
{
|
||||
mDebugger.IncrementStateIdx();
|
||||
mDebugger.mActiveCallStackIdx = 0;
|
||||
mExecutionPaused = true;
|
||||
mDebugger.GetRunState();
|
||||
|
@ -13294,6 +13295,8 @@ namespace IDE
|
|||
|
||||
void WithWatchPanels(delegate void(WatchPanel watchPanel) dlg)
|
||||
{
|
||||
if (mWatchPanel == null)
|
||||
return;
|
||||
dlg(mWatchPanel);
|
||||
dlg(mAutoWatchPanel);
|
||||
for (let window in mWindows)
|
||||
|
|
|
@ -153,7 +153,8 @@ namespace IDE
|
|||
public List<String> mSymbolSearchPath = new .() ~ DeleteContainerAndItems!(_);
|
||||
public List<String> mAutoFindPaths = new .() ~ DeleteContainerAndItems!(_);
|
||||
public int32 mProfileSampleRate = 1000;
|
||||
public bool mAutoEvaluateProperties = false;
|
||||
public bool mAutoEvaluatePropertiesOnHover = false;
|
||||
public bool mAutoRefreshWatches = false;
|
||||
|
||||
public void Serialize(StructuredData sd)
|
||||
{
|
||||
|
@ -194,7 +195,8 @@ namespace IDE
|
|||
sd.RemoveIfEmpty();
|
||||
}
|
||||
sd.Add("ProfileSampleRate", mProfileSampleRate);
|
||||
sd.Add("AutoEvaluateProperties", mAutoEvaluateProperties);
|
||||
sd.Add("AutoEvaluateProperties", mAutoEvaluatePropertiesOnHover);
|
||||
sd.Add("AutoRefreshWatches", mAutoRefreshWatches);
|
||||
}
|
||||
|
||||
public void Deserialize(StructuredData sd)
|
||||
|
@ -233,7 +235,8 @@ namespace IDE
|
|||
}
|
||||
}
|
||||
sd.Get("ProfileSampleRate", ref mProfileSampleRate);
|
||||
sd.Get("AutoEvaluateProperties", ref mAutoEvaluateProperties);
|
||||
sd.Get("AutoEvaluateProperties", ref mAutoEvaluatePropertiesOnHover);
|
||||
sd.Get("AutoRefreshWatches", ref mAutoRefreshWatches);
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
|
@ -264,6 +267,9 @@ namespace IDE
|
|||
gApp.mDebugger.SetSourcePathRemap(remapStr);
|
||||
|
||||
mProfileSampleRate = Math.Clamp(mProfileSampleRate, 10, 10000);
|
||||
|
||||
gApp.mDebugger.IncrementStateIdx();
|
||||
gApp.RefreshWatches();
|
||||
}
|
||||
|
||||
public void SetDefaults()
|
||||
|
@ -1349,7 +1355,6 @@ namespace IDE
|
|||
mKeySettings.Apply();
|
||||
mDebuggerSettings.Apply();
|
||||
|
||||
|
||||
for (var window in gApp.mWindows)
|
||||
{
|
||||
if (var widgetWindow = window as WidgetWindow)
|
||||
|
|
|
@ -639,7 +639,7 @@ namespace IDE
|
|||
gApp.mDebugger.RehupBreakpoints(true);
|
||||
gApp.mDebugger.Run();
|
||||
gApp.mDebugger.mIsRunning = true;
|
||||
gApp.mDebugger.mDebugIdx++;
|
||||
gApp.mDebugger.IncrementSessionIdx();
|
||||
}
|
||||
|
||||
mTestInstance.mThread.Start(false);
|
||||
|
|
|
@ -2977,11 +2977,15 @@ namespace IDE.ui
|
|||
//insertText = insertText.Substring(0, insertText.Length - 1);
|
||||
String implText = null;
|
||||
int tabIdx = insertText.IndexOf('\t');
|
||||
if (tabIdx != -1)
|
||||
int splitIdx = tabIdx;
|
||||
int crIdx = insertText.IndexOf('\r');
|
||||
if ((crIdx != -1) && (tabIdx != -1) && (crIdx < tabIdx))
|
||||
splitIdx = crIdx;
|
||||
if (splitIdx != -1)
|
||||
{
|
||||
implText = scope:: String();
|
||||
implText.Append(insertText, tabIdx);
|
||||
insertText.RemoveToEnd(tabIdx);
|
||||
implText.Append(insertText, splitIdx);
|
||||
insertText.RemoveToEnd(splitIdx);
|
||||
}
|
||||
String prevText = scope String();
|
||||
mTargetEditWidget.Content.ExtractString(editSelection.mStartPos, editSelection.mEndPos - editSelection.mStartPos, prevText);
|
||||
|
|
|
@ -775,7 +775,7 @@ namespace IDE.ui
|
|||
flags |= DebugManager.EvalExpressionFlags.DeselectCallStackIdx;
|
||||
if (mAllowSideEffects)
|
||||
flags |= .AllowSideEffects | .AllowCalls;
|
||||
if (gApp.mSettings.mDebuggerSettings.mAutoEvaluateProperties)
|
||||
if (gApp.mSettings.mDebuggerSettings.mAutoEvaluatePropertiesOnHover)
|
||||
flags |= .AllowProperties;
|
||||
if (watch.mResultType == .RawText)
|
||||
flags |= .RawStr;
|
||||
|
|
|
@ -347,7 +347,8 @@ namespace IDE.ui
|
|||
AddPropertiesItem(root, "Symbol File Locations", "mSymbolSearchPath");
|
||||
AddPropertiesItem(root, "Auto Find Paths", "mAutoFindPaths");
|
||||
AddPropertiesItem(root, "Profile Sample Rate", "mProfileSampleRate");
|
||||
AddPropertiesItem(root, "Auto Evaluate Properties", "mAutoEvaluateProperties");
|
||||
AddPropertiesItem(root, "Auto Eval Properties on Hover", "mAutoEvaluatePropertiesOnHover");
|
||||
AddPropertiesItem(root, "Auto Refresh Side Effects", "mAutoRefreshWatches");
|
||||
}
|
||||
|
||||
protected override void ResetSettings()
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace IDE.ui
|
|||
public bool mIsNewExpression;
|
||||
public bool mIsPending;
|
||||
public bool mUsedLock;
|
||||
public bool? mAutoRefresh;
|
||||
public int32 mDebuggerStateIdx;
|
||||
public int32 mCurStackIdx;
|
||||
public int mMemoryBreakpointAddr;
|
||||
public int32 mHadStepCount;
|
||||
|
@ -66,6 +68,24 @@ namespace IDE.ui
|
|||
public int32 mSeriesFirstVersion = -1;
|
||||
public int32 mSeriesVersion = -1;
|
||||
|
||||
public bool AutoRefresh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mAutoRefresh != null)
|
||||
return mAutoRefresh.Value;
|
||||
return gApp.mSettings.mDebuggerSettings.mAutoRefreshWatches;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value == gApp.mSettings.mDebuggerSettings.mAutoRefreshWatches)
|
||||
mAutoRefresh = null;
|
||||
else
|
||||
mAutoRefresh = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConstant
|
||||
{
|
||||
get
|
||||
|
@ -1968,7 +1988,32 @@ namespace IDE.ui
|
|||
{
|
||||
mWatchRefreshButton = new WatchRefreshButton();
|
||||
mWatchRefreshButton.Resize(GS!(-16), 0, GS!(20), GS!(20));
|
||||
mWatchRefreshButton.mOnMouseDown.Add(new (evt) => RefreshWatch());
|
||||
mWatchRefreshButton.mOnMouseDown.Add(new (evt) =>
|
||||
{
|
||||
if (evt.mBtn == 0)
|
||||
RefreshWatch();
|
||||
if (evt.mBtn == 1)
|
||||
{
|
||||
Menu menu = new Menu();
|
||||
Menu anItem;
|
||||
anItem = menu.AddItem("Refresh");
|
||||
anItem.mOnMenuItemSelected.Add(new (item) => { RefreshWatch(); });
|
||||
|
||||
anItem = menu.AddItem("Auto Refresh");
|
||||
if (mWatchEntry.AutoRefresh)
|
||||
anItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check);
|
||||
anItem.mOnMenuItemSelected.Add(new (item) =>
|
||||
{
|
||||
mWatchEntry.AutoRefresh = !mWatchEntry.AutoRefresh;
|
||||
if (mWatchEntry.AutoRefresh)
|
||||
RefreshWatch();
|
||||
});
|
||||
|
||||
MenuWidget menuWidget = ThemeFactory.mDefault.CreateMenuWidget(menu);
|
||||
menuWidget.Init(mWatchRefreshButton, evt.mX, mHeight + GS!(2));
|
||||
}
|
||||
|
||||
});
|
||||
var typeSubItem = GetSubItem(columnIdx);
|
||||
typeSubItem.AddWidget(mWatchRefreshButton);
|
||||
mListView.mListSizeDirty = true;
|
||||
|
@ -2024,7 +2069,7 @@ namespace IDE.ui
|
|||
|
||||
if ((mDisabled) && (allowRefresh))
|
||||
{
|
||||
AddRefreshButton();
|
||||
AddRefreshButton();
|
||||
}
|
||||
else if (mWatchRefreshButton != null)
|
||||
{
|
||||
|
@ -2061,7 +2106,7 @@ namespace IDE.ui
|
|||
return retVal;
|
||||
}
|
||||
|
||||
void RefreshWatch()
|
||||
public void RefreshWatch()
|
||||
{
|
||||
var parentWatchListViewItem = mParentItem as WatchListViewItem;
|
||||
if (parentWatchListViewItem != null)
|
||||
|
@ -2997,7 +3042,12 @@ namespace IDE.ui
|
|||
for (WatchListViewItem watchListViewItem in childItems)
|
||||
{
|
||||
var watchEntry = watchListViewItem.mWatchEntry;
|
||||
data.Add(watchEntry.mEvalStr);
|
||||
using (data.CreateObject())
|
||||
{
|
||||
data.Add("EvalStr", watchEntry.mEvalStr);
|
||||
if (watchEntry.mAutoRefresh != null)
|
||||
data.Add("AutoRefresh", watchEntry.mAutoRefresh.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3017,14 +3067,23 @@ namespace IDE.ui
|
|||
IDEUtils.DeserializeListViewState(data, mListView);
|
||||
for (let itemKey in data.Enumerate("Items"))
|
||||
{
|
||||
//for (int32 watchIdx = 0; watchIdx < data.Count; watchIdx++)
|
||||
//for (var watchKV in data)
|
||||
{
|
||||
String watchEntry = scope String();
|
||||
//data.GetString(watchIdx, watchEntry);
|
||||
data.GetCurString(watchEntry);
|
||||
AddWatch(watchEntry);
|
||||
}
|
||||
String watchEntry = scope String();
|
||||
data.GetCurString(watchEntry);
|
||||
WatchListViewItem watchItem;
|
||||
|
||||
if (!watchEntry.IsEmpty)
|
||||
{
|
||||
watchItem = AddWatch(watchEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.GetString("EvalStr", watchEntry);
|
||||
watchItem = AddWatch(watchEntry);
|
||||
if (data.Contains("AutoRefresh"))
|
||||
{
|
||||
watchItem.mWatchEntry.mAutoRefresh = data.GetBool("AutoRefresh");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3622,6 +3681,12 @@ namespace IDE.ui
|
|||
}
|
||||
else if (watch.mEvalStr.Length > 0)
|
||||
{
|
||||
if (!gApp.mDebugger.IsPaused())
|
||||
{
|
||||
// Keep waiting
|
||||
return;
|
||||
}
|
||||
|
||||
String evalStr = scope String(1024);
|
||||
if (watch.mStackFrameId != null)
|
||||
{
|
||||
|
@ -3637,6 +3702,7 @@ namespace IDE.ui
|
|||
DebugManager.EvalExpressionFlags flags = .AllowStringView;
|
||||
if (watch.mIsNewExpression)
|
||||
flags |= .AllowSideEffects | .AllowCalls;
|
||||
|
||||
gApp.DebugEvaluate(null, evalStr, val, -1, watch.mLanguage, flags);
|
||||
watch.mIsNewExpression = false;
|
||||
}
|
||||
|
@ -3666,6 +3732,14 @@ namespace IDE.ui
|
|||
if (((!valueSubItem.mFailed) && (watch.mHadValue)) || (hadSideEffects) || (hadPropertyEval))
|
||||
{
|
||||
watch.mHasValue = true;
|
||||
|
||||
if ((hadSideEffects) && (watch.AutoRefresh))
|
||||
{
|
||||
if (watch.mDebuggerStateIdx != gApp.mDebugger.mStateIdx)
|
||||
listViewItem.RefreshWatch();
|
||||
return;
|
||||
}
|
||||
|
||||
listViewItem.SetDisabled(true, hadSideEffects);
|
||||
return;
|
||||
}
|
||||
|
@ -3730,6 +3804,7 @@ namespace IDE.ui
|
|||
watch.mIsStackAlloc = false;
|
||||
watch.mUsedLock = false;
|
||||
watch.mCurStackIdx = -1;
|
||||
watch.mDebuggerStateIdx = gApp.mDebugger.mStateIdx;
|
||||
watch.mLanguage = .NotSet;
|
||||
DeleteAndNullify!(watch.mEditInitialize);
|
||||
DeleteAndNullify!(watch.mAction);
|
||||
|
|
|
@ -2920,7 +2920,8 @@ bool WinDebugger::DoUpdate()
|
|||
|
||||
if (!handled)
|
||||
{
|
||||
OutputMessage(StrFormat("Skipping first chance exception %08X at address %@ in thread %d\n", exceptionRecord->ExceptionCode, exceptionRecord->ExceptionAddress, threadInfo->mThreadId));
|
||||
if (mRunState != RunState_DebugEval)
|
||||
OutputMessage(StrFormat("Skipping first chance exception %08X at address %@ in thread %d\n", exceptionRecord->ExceptionCode, exceptionRecord->ExceptionAddress, threadInfo->mThreadId));
|
||||
::ContinueDebugEvent(mDebuggerWaitingThread->mProcessId, mDebuggerWaitingThread->mThreadId, DBG_EXCEPTION_NOT_HANDLED);
|
||||
mIsDebuggerWaiting = false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue