2024-11-22 23:01:05 -05:00
|
|
|
|
2026-02-14 01:25:04 -05:00
|
|
|
#include "BreakToDebugger.h"
|
2025-08-27 20:57:12 -04:00
|
|
|
#include "Blueprint/BlueprintExceptionInfo.h"
|
2024-11-22 23:01:05 -05:00
|
|
|
#include "Kismet2/KismetDebugUtilities.h"
|
|
|
|
|
|
2026-02-14 01:25:04 -05:00
|
|
|
ELogVerbosity::Type FlxBreakToDebuggerOutputDevice::ConvertThreshold(ElxBreakToDebuggerThreshold Verbosity) {
|
2024-11-22 23:01:05 -05:00
|
|
|
switch (Verbosity) {
|
2026-02-14 01:25:04 -05:00
|
|
|
case ElxBreakToDebuggerThreshold::Error: return ELogVerbosity::Error;
|
|
|
|
|
case ElxBreakToDebuggerThreshold::Warning: return ELogVerbosity::Warning;
|
|
|
|
|
case ElxBreakToDebuggerThreshold::Display: return ELogVerbosity::Display;
|
|
|
|
|
case ElxBreakToDebuggerThreshold::Log: return ELogVerbosity::Log;
|
|
|
|
|
case ElxBreakToDebuggerThreshold::Verbose: return ELogVerbosity::Verbose;
|
|
|
|
|
case ElxBreakToDebuggerThreshold::VeryVerbose: return ELogVerbosity::VeryVerbose;
|
|
|
|
|
case ElxBreakToDebuggerThreshold::Fatal: return ELogVerbosity::Fatal;
|
2024-11-22 23:01:05 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-14 01:25:04 -05:00
|
|
|
FlxBreakToDebuggerOutputDevice::FlxBreakToDebuggerOutputDevice(const ElxBreakToDebuggerThreshold &SensitivityRef)
|
2024-11-22 23:01:05 -05:00
|
|
|
: Sensitivity(SensitivityRef)
|
|
|
|
|
{
|
|
|
|
|
GLog->AddOutputDevice(this);
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-14 01:25:04 -05:00
|
|
|
FlxBreakToDebuggerOutputDevice::~FlxBreakToDebuggerOutputDevice()
|
2024-11-22 23:01:05 -05:00
|
|
|
{
|
|
|
|
|
GLog->RemoveOutputDevice(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace UBreakPoint {
|
|
|
|
|
static volatile int V;
|
|
|
|
|
FORCENOINLINE static void OnLogFatal() {
|
|
|
|
|
V = 0;
|
|
|
|
|
}
|
|
|
|
|
FORCENOINLINE static void OnLogError() {
|
|
|
|
|
V = 1;
|
|
|
|
|
OnLogFatal();
|
|
|
|
|
}
|
|
|
|
|
FORCENOINLINE static void OnLogWarning() {
|
|
|
|
|
V = 2;
|
|
|
|
|
OnLogError();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const FName LogBlueprintDebugName(TEXT("LogBlueprintDebug"));
|
|
|
|
|
|
|
|
|
|
|
2026-02-14 01:25:04 -05:00
|
|
|
void FlxBreakToDebuggerOutputDevice::Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const FName& Category)
|
2024-11-22 23:01:05 -05:00
|
|
|
{
|
|
|
|
|
// If the error isn't serious enough, do nothing.
|
|
|
|
|
//
|
2026-02-14 01:25:04 -05:00
|
|
|
if (Verbosity > ConvertThreshold(Sensitivity))
|
2024-11-22 23:01:05 -05:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the Category is LogBlueprintDebug, then we're inside the debugger already.
|
|
|
|
|
//
|
|
|
|
|
if (Category == LogBlueprintDebugName)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find out if we're running in a blueprint thread. If not, return.
|
|
|
|
|
//
|
|
|
|
|
FFrame* Frame = FFrame::GetThreadLocalTopStackFrame();
|
|
|
|
|
if (Frame == nullptr) return;
|
|
|
|
|
UObject *TopObject = Frame->Object;
|
|
|
|
|
if (TopObject == nullptr) return;
|
|
|
|
|
|
|
|
|
|
// Notify the debugger that there's been an exception.
|
|
|
|
|
//
|
|
|
|
|
FBlueprintExceptionInfo ExceptionInfo(EBlueprintExceptionType::Breakpoint, FText::FromStringView(FStringView(V)));
|
|
|
|
|
FBlueprintCoreDelegates::ThrowScriptException(TopObject, *Frame, ExceptionInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|