Skip to content

[Exception Handling] Fail to catch memory access violation in native while interop with UnrealEngine #116668

Closed
@Liangjia0411

Description

@Liangjia0411

Issue Description

I'm using C# as a scripting language for Unreal Engine with CoreCLR as the virtual machine runtime. I'm leveraging the C# unmanaged function pointer mechanism to call C++ methods.

I've encountered an inconsistency in exception handling:

  • When C++ code experiences a memory access violation, the game crashes immediately and UE's exception handling mechanism fails to capture it. No C++ stack trace appears in logs.
  • However, when C++ code experiences a divide-by-zero exception, the exception is properly caught by the virtual machine, and the game continues to run without crashing.

Reproduction Steps

  1. Set up UE with C# scripting using CoreCLR
  2. Create C# code that uses unmanaged function pointers to call into C++ code
  3. Implement two test scenarios:
    • A C++ function that causes memory access violation (e.g., dereferencing a null pointer)
    • A C++ function that causes a divide-by-zero exception
  4. Call both functions from C#
  5. Observe that the memory violation crashes the game without stack trace, while divide-by-zero is handled gracefully

Sample Code

// C# method
public class ExceptionTest
{
  public static unsafe void CrashInEngine_AccessInvalidMemory() 
  {
    Internal_CrashInEngine_AccessInvalidMemory();
  }
  private static unsafe delegate* unmanaged<void> Internal_CrashInEngine_AccessInvalidMemory = default;
    
  public static unsafe void CrashInEngine_DivideByZero() 
  {
    Internal_CrashInEngine_DivideByZero();
  }
  private static unsafe delegate* unmanaged<void> Internal_CrashInEngine_DivideByZero = default;
}
// C++ method
void CrashInEngine_AccessInvalidMemory()
{
    int* ptr = nullptr;
    *ptr = 42; // This causes an access violation
}

void Internal_CrashInEngine_DivideByZero()
{
    int zero = 0;
    int result = 1 / zero; // This causes a divide-by-zero exception
}

Expected Behavior

Ideally, all exceptions in C++ code (including memory access violations) should be handled in one of two ways:

  1. Caught by the CoreCLR runtime or UE's exception handling mechanism, allowing the game to continue running without crashing
  2. Or, if it must crash, at least output the complete C++ stack trace so developers can diagnose the issue

Current Behavior

Memory access violations in C++ code called via unmanaged function pointers from C# cause the game to immediately crash with no stack trace, while divide-by-zero exceptions are correctly caught.

Environment

  • Unreal Engine Version: ue5
  • CoreCLR Version: 9.0.5
  • Operating System: windows

Additional Information

This inconsistency makes developing and debugging C# code that interfaces with C++ more difficult and risky, as memory access violations cannot be gracefully handled or properly diagnosed.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions