SweepMultiByChannel in HUD::DrawHUD() crashed

UE4.14.3 + Macos Sierra.
System Configuration: MacBookPro 2011 Early ,(Intel Graphics 3000 + AMD Radeon HD 6750M) Metal has not supported.
Base on First Person C++ Example, I rewrite HUDClass named “AFPVProjectHUD”
When I use function ‘GetWorld()->SweepMultiByChannel’ in HUD::DrawHUD() ,and use Editor(Play in Editor).

  1. Click ‘Play’ in Editor.
  2. Click game screen then mouse can control the crosshair.
  3. Press ‘ESC’.
  4. Click ‘Play’ again, and it crashed.

If I comment out that line “GetWorld()->SweepMultiByChannel” ,it works fine and never crash even if I push the ‘Play’ button again and again.
I am not sure whether is my memory problem, but it always crash in the same place and give me the same crash report.
Source File is in Attachment.

##there is my code in FPVProjectHUD.cpp

void AFPVProjectHUD::DrawHUD()
{
	Super::DrawHUD();
	// find center of the Canvas
	const FVector2D Center(Canvas->ClipX * 0.5f, Canvas->ClipY * 0.5f);
	// offset by half the texture's dimensions so that the center of the texture aligns with the center of the Canvas
	const FVector2D CrosshairDrawPosition( (Center.X),
										   (Center.Y + 20.0f));
	// draw the crosshair
	FCanvasTileItem TileItem( CrosshairDrawPosition, CrosshairTex->Resource, FLinearColor::White);
	TileItem.BlendMode = SE_BLEND_Translucent;
	Canvas->DrawItem( TileItem );

	static APawn* Player = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
	if (Player) {
		FCollisionShape RadarCollision;
		RadarCollision.ShapeType = ECollisionShape::Sphere;
		RadarCollision.SetSphere(1000.0f);
        FVector EndLocation = Player->GetActorLocation();
        EndLocation.Z += 200;

        //why SEGV_NOOP at 0x0 ?
        GetWorld()->SweepMultiByChannel(HitResult, Player->GetActorLocation(), EndLocation,FQuat::Identity, ECollisionChannel::ECC_WorldDynamic, RadarCollision);
	}
}

##And there is my crash report
MachineId:C1*******
EpicAccountId:95f4aef******

 SEGV_NOOP at 0x0

AFPVProjectHUD::DrawHUD() Address = 0x162596fe7 [/Users/Shared/Epic Games/UE_4.14/Engine/Source/Runtime/Core/Public/Math/UnrealMathSSE.h, line 229] [in UE4Editor-FPVProject-4861.dylib]
AHUD::PostRender() Address = 0x105a28fc5 (filename not found) [in UE4Editor-Engine.dylib]
UGameViewportClient::Draw(FViewport*, FCanvas*) Address = 0x10596e1c7 (filename not found) [in UE4Editor-Engine.dylib]
FViewport::Draw(bool) Address = 0x1066df4a2 (filename not found) [in UE4Editor-Engine.dylib]
UEditorEngine::Tick(float, bool) Address = 0x10b5dee88 (filename not found) [in UE4Editor-UnrealEd.dylib]
UUnrealEdEngine::Tick(float, bool) Address = 0x10c21c3fc (filename not found) [in UE4Editor-UnrealEd.dylib]
FEngineLoop::Tick() Address = 0x103adbc79 (filename not found) [in UE4Editor]
GuardedMain(wchar_t const*) Address = 0x103ae2b72 (filename not found) [in UE4Editor]
-[UE4AppDelegate runGameThread:] Address = 0x103af016c (filename not found) [in UE4Editor]
-[FCocoaGameThread main] Address = 0x103d10526 (filename not found) [in UE4Editor-Core.dylib]
Unknown() Address = 0x7fff860dac6d (filename not found) [in Foundation]
_pthread_body Address = 0x7fff99eabaab (filename not found) [in libsystem_pthread.dylib]
_pthread_body Address = 0x7fff99eab9f7 (filename not found) [in libsystem_pthread.dylib]
thread_start Address = 0x7fff99eab1fd (filename not found) [in libsystem_pthread.dylib]

##Some part in Diagnostics.txt
Generating report for minidump

Application version 4.14.3-0
 ... built from changelist 3249277

OS version 10.12.3.27954
Running 1 x64 processors
Exception was " SEGV_NOOP at 0x0"

Source context from "engine/source/runtime/core/public/math/unrealmathsse.h"

<SOURCE START>
  214        * @param Vec	Vector to store
  215        * @param Ptr	Memory pointer
  216        */
  217       #define VectorStore( Vec, Ptr )			_mm_storeu_ps( (float*)(Ptr), Vec )
  218       
  219       /**
  220        * Stores the XYZ components of a vector to unaligned memory.
  221        *
  222        * @param Vec	Vector to store XYZ
  223        * @param Ptr	Unaligned memory pointer
  224        */
  225       FORCEINLINE void VectorStoreFloat3( const VectorRegister& Vec, void* Ptr )
  226       {
  227       	union { VectorRegister v; float f[4]; } Tmp;
  228 ***** 	Tmp.v = Vec;
  229       	float* FloatPtr = (float*)(Ptr);
  230       	FloatPtr[0] = Tmp.f[0];
  231       	FloatPtr[1] = Tmp.f[1];
  232       	FloatPtr[2] = Tmp.f[2];
  233       }
  234       
  235       /**
  236        * Stores the X component of a vector to unaligned memory.
  237        *
  238        * @param Vec	Vector to store X
  239        * @param Ptr	Unaligned memory pointer
  240        */
  241       #define VectorStoreFloat1( Vec, Ptr )	_mm_store_ss((float*)(Ptr), Vec)
  242       
  243       /**
<SOURCE END>

Hi vrqq,

This actually isn’t a bug with SweepMultiByChannel. This is the result of how static variables work in C++, and the fact that PIE does not create a new process for the project, but instead uses the existing Editor process.

What is happening here is that the first time you start PIE, the line static APawn* Player = UGameplayStatics::GetPlayerPawn(GetWorld(), 0); is run on the first DrawHUD call, creating the Player variable and setting it appropriately. The second time you start PIE, this line is skipped in each DrawHUD call since the Player variable already exists (project static variables do not get removed from memory until the Editor is closed), so the variable will be pointing to the memory where the Player Pawn was located the first time PIE was started, which is now either garbage data, or holding some other data entirely. The Player variable never gets updated to point to the memory where the current Player Pawn is stored.

In order to get around this, you could split this line into two separate lines. Something like this:

static APawn* Player = nullptr;
Player = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);

In this case, the first line above is only ever executed the first time you begin PIE and DrawHUD is called. The second line, which makes sure the Player variable is always pointing to valid memory, will run every time DrawHUD is called, so Player will always point to the correct memory location.

Depending on your project, it may not be ideal to be setting this every tick. Another option might be to add a member variable to your project’s HUD class that you can initialize to nullptr, and then check in DrawHUD and set if it does not contain a valid value. This would ensure that the variable is set correctly only the first time DrawHUD is called, which I am guessing is what your initial intention was.

One final thing I would like to point out. This will only be an issue when you are running your project in PIE multiple times. When you package your project, this will not be an issue since each time the packaged game is run, it uses a new process and a new static variable will be created and set.