Stack overflow on the Mac after upgrading to 4.8

Hi,

We noticed that the game started crashing in one of the testing level after upgrading to 4.8 with a stack overflow in the rendering thread.

The callstack looks something like this:

#0	0x000000011ab9fef2 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:396
#1	0x000000011ab9fed8 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:394
#2	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#3	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#4	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#5	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#6	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#7	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#8	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#9	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#10	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#11	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#12	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#13	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#14	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#15	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#16	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#17	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#18	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#19	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#20	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#21	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#22	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#23	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#24	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#25	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#26	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#27	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#28	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#29	0x000000011ab9bd39 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:242
#30	0x000000011ab9b783 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:232
#31	0x000000011ab9b783 in FTextureLayout3d::AddSurfaceInner(int, unsigned int, unsigned int, unsigned int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:232
#32	0x000000011a9e5d33 in FTextureLayout3d::AddElement(unsigned int&, unsigned int&, unsigned int&, unsigned int, unsigned int, unsigned int) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Engine/Public/TextureLayout3d.h:70
#33	0x000000011a9447e0 in FIndirectLightingCache::AllocateBlock(int, FIntVector&) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/IndirectLightingCache.cpp:202
#34	0x000000011a94662b in FIndirectLightingCache::CreateAllocation(int, FBoxSphereBounds const&, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/IndirectLightingCache.cpp:312
#35	0x000000011a950563 in FIndirectLightingCache::UpdateCacheAllocation(FBoxSphereBounds const&, int, bool, FIndirectLightingCacheAllocation*&, TMap<FIntVector, FBlockUpdateInfo, FDefaultSetAllocator, TDefaultMapKeyFuncs<FIntVector, FBlockUpdateInfo, false> >&, TArray<FIndirectLightingCacheAllocation*, FDefaultAllocator>&) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/IndirectLightingCache.cpp:463
#36	0x000000011a94d97b in FIndirectLightingCache::UpdateCachePrimitive(FScene*, FPrimitiveSceneInfo*, bool, bool, TMap<FIntVector, FBlockUpdateInfo, FDefaultSetAllocator, TDefaultMapKeyFuncs<FIntVector, FBlockUpdateInfo, false> >&, TArray<FIndirectLightingCacheAllocation*, FDefaultAllocator>&) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/IndirectLightingCache.cpp:514
#37	0x000000011a94a162 in FIndirectLightingCache::UpdateCache(FScene*, FSceneRenderer&, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/IndirectLightingCache.cpp:395
#38	0x000000011b0e63a1 in FSceneRenderer::PostVisibilityFrameSetup() at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/SceneVisibility.cpp:2158
#39	0x000000011b0ecfda in FDeferredShadingSceneRenderer::InitViews(FRHICommandListImmediate&) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/SceneVisibility.cpp:2327
#40	0x000000011a553342 in FDeferredShadingSceneRenderer::Render(FRHICommandListImmediate&) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/DeferredShadingRenderer.cpp:708
#41	0x000000011af0406c in RenderViewFamily_RenderThread(FRHICommandListImmediate&, FSceneRenderer*) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/SceneRendering.cpp:1350
#42	0x000000011adb11e4 in FRendererModule::BeginRenderingViewFamily(FCanvas*, FSceneViewFamily*)::EURCMacro_FDrawSceneCommand::DoTask(ENamedThreads::Type, TRefCountPtr<FGraphEvent> const&) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Renderer/Private/SceneRendering.cpp:1441
#43	0x000000011adb3ed7 in TGraphTask<FRendererModule::BeginRenderingViewFamily(FCanvas*, FSceneViewFamily*)::EURCMacro_FDrawSceneCommand>::ExecuteTask(TArray<FBaseGraphTask*, FDefaultAllocator>&, ENamedThreads::Type) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Core/Public/Async/TaskGraphInterfaces.h:753
#44	0x000000010041a170 in FBaseGraphTask::Execute(TArray<FBaseGraphTask*, FDefaultAllocator>&, ENamedThreads::Type) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Core/Public/Async/TaskGraphInterfaces.h:308
#45	0x00000001004103a9 in FTaskThread::ProcessTasks(int, bool) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Core/Private/Async/TaskGraph.cpp:428
#46	0x0000000100409ed9 in FTaskThread::ProcessTasksUntilQuit(int) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Core/Private/Async/TaskGraph.cpp:271
#47	0x00000001003fadfd in FTaskGraphImplementation::ProcessThreadUntilRequestReturn(ENamedThreads::Type) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Core/Private/Async/TaskGraph.cpp:946
#48	0x000000010c2c912f in RenderingThreadMain(FEvent*) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp:283
#49	0x000000010c3ac3ed in FRenderingThread::Run() at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp:404
#50	0x000000010042575d in FRunnableThreadPThread::Run() at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Core/Private/HAL/PThreadRunnableThread.cpp:26
#51	0x00000001003e4879 in FRunnableThreadPThread::_ThreadProc(void*) at /Users/wanghao/work/UnrealEngine/Engine/Source/Runtime/Core/Private/GenericPlatform/../HAL/PThreadRunnableThread.h:167
#52	0x00007fff974c0268 in _pthread_body ()
#53	0x00007fff974c01e5 in _pthread_start ()
#54	0x00007fff974be41d in thread_start ()

Increasing the stack size to 4Mb helps but we’re not sure if it’s the right thing to do.

Is this something that Epic knows/is addressing internally?

Note that so far this crash only happens in the debug build.

I’m also curious where did the 2Mb default stack size come from? Or is that just a number that “seems to work”?

This is in MacPlatformRunnableThread.h:

virtual int GetDefaultStackSize() override
{
	// default is 512 KB, we need more
	return 2 * 1024 * 1024;
}

So, we’re also seeing similar stack overflow crash in the game thread in another level. Has something major changed in 4.8 with regard to stack usage?

Seems like the huge stack frames are due to temp storage for debug logs coming out of check/log/assert macros. Some LinkerLoad and other functions rely heavily on recursion, and end up allocating hundreds of kilobytes of stack per recursion.

Looks like there were a couple of changes to the logging, but I don’t have time to dig into the details. Epic?

We’re working on a proper fix, but in a meantime please increase the default stack size to 4 MB in GetDefaultStackSize() in MacPlatformRunnableThread.h

Thanks, that helped for our render thread issues, but we also had to bump the game thread to 16 MiB in CocoaThread.cpp, RunGameThread(…)
[GameThread setStackSize:N]