1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Merge pull request #1886 from daafu/output_filters

Add output window filtering options similar to what Visual Studio offers
This commit is contained in:
Brian Fiete 2023-09-05 07:13:04 -07:00 committed by GitHub
commit 18e0576d79
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 221 additions and 15 deletions

View file

@ -104,6 +104,19 @@ namespace IDE.Debugger
AllowStringView = 0x800
}
//[Flags]
public enum OutputFilterFlags
{
None = 0x0,
ModuleLoadMessages = 0x1,
ModuleUnloadMessages = 0x2,
ProcessExitMessages = 0x4,
ThreadCreateMessages = 0x8,
ThreadExitMessages = 0x10,
SymbolLoadMessages = 0x20,
ProgramOutput = 0x30
}
[Reflect]
public enum SymSrvFlags
{
@ -386,6 +399,12 @@ namespace IDE.Debugger
[CallingConvention(.Stdcall), CLink]
static extern char8* Debugger_GetEmitSource(char8* fileName);
[CallingConvention(.Stdcall), CLink]
static extern void Debugger_SetOutputFilterFlags(int32 flags);
[CallingConvention(.Stdcall), CLink]
static extern int32 Debugger_GetOutputFilterFlags();
public String mRunningPath ~ delete _;
public bool mIsRunning;
public bool mIsRunningCompiled;
@ -1285,5 +1304,15 @@ namespace IDE.Debugger
outString.Append(stackId);
return true;
}
public void SetOutputFilterFlags(OutputFilterFlags outputFilterFlags)
{
Debugger_SetOutputFilterFlags((int32)outputFilterFlags);
}
public OutputFilterFlags GetOutputFilterFlags()
{
return (OutputFilterFlags)Debugger_GetOutputFilterFlags();
}
}
}

View file

@ -2011,6 +2011,23 @@ namespace IDE
}
sd.RemoveIfEmpty();
}
using (sd.CreateObject("OutputFilters"))
{
IDE.Debugger.DebugManager.OutputFilterFlags outputFilterFlags = 0;
if (gApp.mDebugger != null)
{
outputFilterFlags = gApp.mDebugger.GetOutputFilterFlags();
}
sd.Add("ModuleLoadMessages", outputFilterFlags.HasFlag(.ModuleLoadMessages));
sd.Add("ModuleUnloadMessages", outputFilterFlags.HasFlag(.ModuleUnloadMessages));
sd.Add("ProcessExitMessages", outputFilterFlags.HasFlag(.ProcessExitMessages));
sd.Add("ThreadCreateMessages", outputFilterFlags.HasFlag(.ThreadCreateMessages));
sd.Add("ThreadExitMessages", outputFilterFlags.HasFlag(.ThreadExitMessages));
sd.Add("SymbolLoadMessages", outputFilterFlags.HasFlag(.SymbolLoadMessages));
sd.Add("ProgramOutput", outputFilterFlags.HasFlag(.ProgramOutput));
}
}
bool SaveWorkspaceUserData(bool showErrors = true)
@ -3466,6 +3483,24 @@ namespace IDE
mDebugger.CreateStepFilter(filter, false, .NotFiltered);
}
using (data.Open("OutputFilters"))
{
IDE.Debugger.DebugManager.OutputFilterFlags outputFilterFlags = 0;
outputFilterFlags |= data.GetBool("ModuleLoadMessages", false) ? .ModuleLoadMessages : 0;
outputFilterFlags |= data.GetBool("ModuleUnloadMessages", false) ? .ModuleUnloadMessages : 0;
outputFilterFlags |= data.GetBool("ProcessExitMessages", false) ? .ProcessExitMessages : 0;
outputFilterFlags |= data.GetBool("ThreadCreateMessages", false) ? .ThreadCreateMessages : 0;
outputFilterFlags |= data.GetBool("ThreadExitMessages", false) ? .ThreadExitMessages : 0;
outputFilterFlags |= data.GetBool("SymbolLoadMessages", false) ? .SymbolLoadMessages : 0;
outputFilterFlags |= data.GetBool("ProgramOutput", false) ? .ProgramOutput : 0;
if (gApp.mDebugger != null)
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags);
}
}
return true;
}

View file

@ -244,15 +244,100 @@ namespace IDE.ui
Menu menu = new Menu();
var menuItem = menu.AddItem("Clear All");
var menuItemClearAll = menu.AddItem("Clear All");
var panel = mParent.mParent.mParent as TextPanel;
menuItem.mOnMenuItemSelected.Add(new (evt) =>
{
menuItemClearAll.mOnMenuItemSelected.Add(new (evt) =>
{
if (panel != null)
panel.Clear();
else
ClearText();
});
ClearText();
});
// Separator
menu.AddItem();
IDE.Debugger.DebugManager.OutputFilterFlags outputFilterFlags = gApp.mDebugger.GetOutputFilterFlags();
var menuItemModuleLoadMessages = menu.AddItem("Module Load Messages");
if (!outputFilterFlags.HasFlag(.ModuleLoadMessages))
{
menuItemModuleLoadMessages.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check);
}
menuItemModuleLoadMessages.mOnMenuItemSelected.Add(new (evt) =>
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags ^ .ModuleLoadMessages);
});
var menuItemModuleUnloadMessages = menu.AddItem("Module Unload Messages");
if (!outputFilterFlags.HasFlag(.ModuleUnloadMessages))
{
menuItemModuleUnloadMessages.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check);
}
menuItemModuleUnloadMessages.mOnMenuItemSelected.Add(new (evt) =>
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags ^ .ModuleUnloadMessages);
});
var menuItemProcessExitMessages = menu.AddItem("Process Exit Messages");
if (!outputFilterFlags.HasFlag(.ProcessExitMessages))
{
menuItemProcessExitMessages.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check);
}
menuItemProcessExitMessages.mOnMenuItemSelected.Add(new (evt) =>
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags ^ .ProcessExitMessages);
});
var menuItemThreadCreateMessages = menu.AddItem("Thread Creation Messages");
if (!outputFilterFlags.HasFlag(.ThreadCreateMessages))
{
menuItemThreadCreateMessages.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check);
}
menuItemThreadCreateMessages.mOnMenuItemSelected.Add(new (evt) =>
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags ^ .ThreadCreateMessages);
});
var menuItemThreadExitMessages = menu.AddItem("Thread Exit Messages");
if (!outputFilterFlags.HasFlag(.ThreadExitMessages))
{
menuItemThreadExitMessages.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check);
}
menuItemThreadExitMessages.mOnMenuItemSelected.Add(new (evt) =>
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags ^ .ThreadExitMessages);
});
var menuItemSymbolLoadMessages = menu.AddItem("Symbol Load Messages");
if (!outputFilterFlags.HasFlag(.SymbolLoadMessages))
{
menuItemSymbolLoadMessages.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check);
}
menuItemSymbolLoadMessages.mOnMenuItemSelected.Add(new (evt) =>
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags ^ .SymbolLoadMessages);
});
/* Not sure how to filter Program Output, it's handled in BeefSysLib not the IDE/Debugger. Perhaps we would
also need SetOutputFilterFlags() in BeefSysLib
var menuItemProgramOutput = menu.AddItem("Program Output");
if (!outputFilterFlags.HasFlag(.ProgramOutput))
{
menuItemProgramOutput.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check);
}
menuItemProgramOutput.mOnMenuItemSelected.Add(new (evt) =>
{
gApp.mDebugger.SetOutputFilterFlags(outputFilterFlags ^ .ProgramOutput);
});
*/
MenuWidget menuWidget = DarkTheme.sDarkTheme.CreateMenuWidget(menu);
menuWidget.Init(this, useX, useY);

View file

@ -6020,7 +6020,7 @@ bool COFF::TryLoadPDB(const String& pdbPath, uint8 wantGuid[16], int32 wantAge)
BP_ZONE("COFF::TryLoadPDB");
if (!isVerifyOnly)
if (!isVerifyOnly && !(gDebugManager->GetOutputFilterFlags() & BfOutputFilterFlags_SymbolLoadMessages))
mDebugger->OutputMessage(StrFormat("Loading PDB %s\n", pdbPath.c_str()));
DWORD highFileSize = 0;

View file

@ -94,6 +94,8 @@ DebugManager::DebugManager()
mSymSrvOptions.mSymbolServers.Add("http://127.0.0.1/symbols");
SetSourceServerCacheDir();
mOutputFilterFlags = BfOutputFilterFlags_None;
}
DebugManager::~DebugManager()
@ -143,6 +145,16 @@ void DebugManager::SetSourceServerCacheDir()
#endif
}
void DebugManager::SetOutputFilterFlags(BfOutputFilterFlags outputFilterFlags)
{
mOutputFilterFlags = outputFilterFlags;
}
BfOutputFilterFlags DebugManager::GetOutputFilterFlags()
{
return mOutputFilterFlags;
}
//#define CAPTURE_ALLOC_BACKTRACE
//#define CAPTURE_ALLOC_SOURCES
@ -1661,6 +1673,24 @@ BF_EXPORT const char* BF_CALLTYPE Debugger_GetEmitSource(char* inFilePath)
return outString.c_str();
}
BF_EXPORT void BF_CALLTYPE Debugger_SetOutputFilterFlags(int flags)
{
if (gDebugManager != NULL)
{
gDebugManager->SetOutputFilterFlags((BfOutputFilterFlags)flags);
}
}
BF_EXPORT int BF_CALLTYPE Debugger_GetOutputFilterFlags()
{
if (gDebugManager != NULL)
{
return (int)gDebugManager->GetOutputFilterFlags();
}
return 0;
}
BF_EXPORT NetResult* HTTP_GetFile(char* url, char* destPath)
{
AutoCrit autoCrit(gDebugManager->mNetManager->mThreadPool.mCritSect);

View file

@ -35,6 +35,18 @@ enum BfStepFilterKind
BfStepFilterKind_NotFiltered = 2
};
enum BfOutputFilterFlags : uint16
{
BfOutputFilterFlags_None = 0x0,
BfOutputFilterFlags_ModuleLoadMessages = 0x1,
BfOutputFilterFlags_ModuleUnloadMessages = 0x2,
BfOutputFilterFlags_ProcessExitMessages = 0x4,
BfOutputFilterFlags_ThreadCreateMessages = 0x8,
BfOutputFilterFlags_ThreadExitMessages = 0x10,
BfOutputFilterFlags_SymbolLoadMessages = 0x20,
BfOutputFilterFlags_ProgramOutput = 0x40 // Can't trap these easily, they're in BeefSysLib
};
class StepFilter
{
public:
@ -81,6 +93,8 @@ public:
NetManager* mNetManager;
DbgSymSrvOptions mSymSrvOptions;
BfOutputFilterFlags mOutputFilterFlags;
public:
DebugManager();
~DebugManager();
@ -88,6 +102,9 @@ public:
void OutputMessage(const StringImpl& msg);
void OutputRawMessage(const StringImpl& msg);
void SetSourceServerCacheDir();
void SetOutputFilterFlags(BfOutputFilterFlags outputFilterFlags);
BfOutputFilterFlags GetOutputFilterFlags();
};
extern DebugManager* gDebugManager;

View file

@ -1708,7 +1708,9 @@ bool WinDebugger::DoUpdate()
mDebuggerWaitingThread = newThreadInfo;
mThreadList.push_back(mDebuggerWaitingThread);
UpdateThreadDebugRegisters();
OutputMessage(StrFormat("Creating thread from CREATE_PROCESS_DEBUG_EVENT %d\n", mDebugEvent.dwThreadId));
if (!(gDebugManager->GetOutputFilterFlags() & BfOutputFilterFlags_ThreadCreateMessages))
OutputMessage(StrFormat("Creating thread from CREATE_PROCESS_DEBUG_EVENT %d\n", mDebugEvent.dwThreadId));
threadInfo = mDebuggerWaitingThread;
mProcessInfo.dwThreadId = threadInfo->mThreadId;
@ -1776,10 +1778,14 @@ bool WinDebugger::DoUpdate()
else
exitCodeStr = StrFormat("%d", exitCode);
if (!exitMessage.IsEmpty())
OutputMessage(StrFormat("Process terminated. ExitCode: %s (%s).\n", exitCodeStr.c_str(), exitMessage.c_str()));
else
OutputMessage(StrFormat("Process terminated. ExitCode: %s.\n", exitCodeStr.c_str()));
if (!(gDebugManager->GetOutputFilterFlags() & BfOutputFilterFlags_ProcessExitMessages))
{
if (!exitMessage.IsEmpty())
OutputMessage(StrFormat("Process terminated. ExitCode: %s (%s).\n", exitCodeStr.c_str(), exitMessage.c_str()));
else
OutputMessage(StrFormat("Process terminated. ExitCode: %s.\n", exitCodeStr.c_str()));
}
mRunState = RunState_Terminated;
mDebugManager->mOutMessages.push_back("modulesChanged");
}
@ -1858,7 +1864,8 @@ bool WinDebugger::DoUpdate()
stream.mFileHandle = 0;
}
OutputMessage(loadMsg + "\n");
if (!(gDebugManager->GetOutputFilterFlags() & BfOutputFilterFlags_ModuleLoadMessages))
OutputMessage(loadMsg + "\n");
if (altFileHandle != INVALID_HANDLE_VALUE)
::CloseHandle(altFileHandle);
@ -1913,7 +1920,7 @@ bool WinDebugger::DoUpdate()
mDebugManager->mOutMessages.push_back("modulesChanged");
}
if (!name.empty())
if (!(gDebugManager->GetOutputFilterFlags() & BfOutputFilterFlags_ModuleUnloadMessages) && !name.empty())
OutputMessage(StrFormat("Unloading DLL: %s @ %0s\n", name.c_str(), EncodeDataPtr((addr_target)(intptr)mDebugEvent.u.UnloadDll.lpBaseOfDll, true).c_str()));
BfLogDbg("UNLOAD_DLL_DEBUG_EVENT %s\n", name.c_str());
@ -1959,12 +1966,15 @@ bool WinDebugger::DoUpdate()
mDebuggerWaitingThread = threadInfo;
mThreadList.push_back(mDebuggerWaitingThread);
UpdateThreadDebugRegisters();
OutputMessage(StrFormat("Creating thread %d\n", mDebugEvent.dwThreadId));
if (!(gDebugManager->GetOutputFilterFlags() & BfOutputFilterFlags_ThreadCreateMessages))
OutputMessage(StrFormat("Creating thread %d\n", mDebugEvent.dwThreadId));
}
break;
case EXIT_THREAD_DEBUG_EVENT:
{
OutputMessage(StrFormat("Exiting thread %d\n", mDebugEvent.dwThreadId));
if (!(gDebugManager->GetOutputFilterFlags() & BfOutputFilterFlags_ThreadExitMessages))
OutputMessage(StrFormat("Exiting thread %d\n", mDebugEvent.dwThreadId));
if (mSteppingThread == threadInfo)
{
// We were attempting stepping on this thread, but not anymore!