why is there a FStallDetector

In there a way to disable StallDetector ?

This makes it practically impossible to debug a c++ plugin.
Not only that, it provides a tremendous amount of misleading information, even when not debugging, just testing your code.

Unreal is notoriously slow in debug builds, so if you are testing your plugin in Editor Debug build, unreal will generates random crashes with this kind of call stack.

        ntdll.dll!00007ff859981548()	Unknown
 	ntdll.dll!00007ff859981040()	Unknown
 	ntdll.dll!00007ff859980e7b()	Unknown
 	kernel32.dll!00007ff8589e1048()	Unknown
 	UnrealEditor-Core.dll!FMicrosoftPlatformStackWalk::CaptureStackTraceInternal
>	UnrealEditor-Core.dll!FWindowsPlatformStackWalk::CaptureStackTraceByProcess
 	UnrealEditor-Core.dll!FWindowsPlatformStackWalk::CaptureThreadStackBackTrace
 	UnrealEditor-Core.dll!UE::FStallDetectorRunnable::Run() Line 161	C++

This leads the programmer into a wild goose chases thinking he or she did something wrong, when in reality it is unreal crashing because it just took too much time loading resources or running some unreal process.

It took me the best part of the week debugging and refactoring code that I know works on other context, yet causes this crashes in different places in unreal, simply because some unreal system took too much time to complete.

On a more philosophic design question?, why a designer would put code like that knowing well that will cause crashes in a debug build, unless they are running on a computer that less that 1% of the people using Unreal will have? that will include large studios with huge budgets.
I would also assert that even in that case, this design will crash those systems given a big enough load to go in a debug build.

In my opinion, if something like that is going to be added, it should be a Final or shipping build,
but never in a dev or debug build.

Again is there a way to disable that funtionality?

This really is becoming an increasingly frustrating situation.

The project I am running is simply scanning a simple landscape of 4 x 4 tiles
each with 63 x 63 sample. Reduced from the original test I was using of 4 x 4 by (256 x 256 sample or so) which made impossible to work.
Now even with this small map, it also start to give me random timeout crashes.

the code just does this on each time on BeginPlay call back at when click start game…
m_tileHash = m_tile->ComputeCollisionHash();
This is to detect if a time was changed in the editor and update the surrogate mesh and need to maintain.
This is enough to randomly crash unreal, which means the frequency of the crashes will increase as more funtionality is added.

I decided to spend a little more time debugging this and see if there is a way to configure it.
It appears that the intention of this feature was configurable, but for some reason was just hard coded to be 2 seconds. This happen on the function bellow

void FEngineLoop::Tick()
{
	TRACE_CPUPROFILER_EVENT_SCOPE(FEngineLoop::Tick);
	SCOPE_STALL_COUNTER(FEngineLoop::Tick, 2.0);
...
...

macro SCOPE_STALL_COUNTER create a static class static UE::FStallDetectorStats

which store the max time the engine tick or any other thread is allow to take.

This means if you are debugging your plugin, and you set a break point on a call back called for engine tick. You game will crash randomly.

now, this static class can be assessable from FEngineLoop GEngineLoop;
which is one of those unreal global object .

In theory, a plugin could override the two secund just for the purpose of debugging.
The class is this

	class FStallDetectorStats
	{
		friend class FStallDetectorRunnable;

	public:
		/**
		* Construct a stats object for use with a stall detector
		*/
		CORE_API FStallDetectorStats(const TCHAR* InName, const double InBudgetSeconds, const EStallDetectorReportingMode InReportingMode);

		/**
		* Destruct a stats object, just removes it from the instance tracking
		*/
		CORE_API ~FStallDetectorStats();

		/**
		* Stall detector scope has ended, record the interval
		*/
		CORE_API void OnStallCompleted(double InOverageSeconds);

		struct TabulatedResult
		{
			const TCHAR* Name = TEXT("");
			double BudgetSeconds = 0.0;
			int64 TriggerCount = 0;
			double OverageSeconds = 0.0;
			double OverageRatio = 0.0;
		};
		static CORE_API void TabulateStats(TArray<TabulatedResult>& TabulatedResults);

		// The name to refer to this callsite in the codebase
		const TCHAR* Name;

		// The budgeted time we tolerate without sending a report
		const double BudgetSeconds;

		// Drives the behavior about what to do when a budget is violated (triggered)
		const EStallDetectorReportingMode ReportingMode;

		// Has this been reported yet, this is different than the trigger count for coherency reasons
		bool bReported;

		// The total number of times all callsites have been triggered
		static CORE_API FCountersTrace::FCounterAtomicInt TotalTriggeredCount;

		// The total number of reports that have been sent
		static CORE_API FCountersTrace::FCounterAtomicInt TotalReportedCount;

	private:
		// The number of times this callsite has been triggered
		FCountersTrace::TCounter<int64, TraceCounterType_Int> TriggerCount;
		TCHAR TriggerCountCounterName[StallDetectorStatNameBufferSize];

		// The cumulative overage time for this callsite
		FCountersTrace::TCounter<double, TraceCounterType_Float> OverageSeconds;
		TCHAR OverageSecondsCounterName[StallDetectorStatNameBufferSize];

		// Guards access to the stats from multiple threads, for coherency
		mutable FCriticalSection StatsSection;
	};

The variable that store the time is const double BudgetSeconds;

I tried my best to change that value, but for some reason, Launch module is one of those modules the unreal team does not allow end users to link to in a plugin, adding to the build.cs will makes the build system silently stop the build with a meaningless error.

So, the question is, other than compiling Ureal from source, which is not an attractive proportion, is there a way to change that variable by linking module or module that allow to include header //include “LaunchEngineLoop.h”

I actually look a the source to see why system using the launcher, and it seem onel internal stuff do it, not really clear how to do it on teh client side.

Thanks.