Linux crash in std::string destructor

Engine Version: 4.12.2 final release git commit: d727689444e4fbd689f5e7d924cd0c5b869fccea

The editor process crashes if I add an std::string object. Like this:

// This causes a crash //
{
    std::string InnocentString = "INFO would be merged here things;";

    check(InnocentString.length() > 0);
}

Here is the Crashes folder with the reports: https://boostslair.com/files/Crashes.7z

The callstack usually includes the string destructor, but it seems that the crash can happen any time after the destructor.
I’ve tried using -ansimalloc and running valgrind on it. Valgrind says there’s an invalid of size 8 just before the memory allocated by the string object.

I tried to get a crash by directly using delete but none of these cause a crash

int* ArrayTest = new int[400];

check(ArrayTest);
memset(ArrayTest, 1, sizeof(int) * 400);

ArrayTest[12] = 12;

check(ArrayTest[12] = 12);

delete[] ArrayTest;
ArrayTest = nullptr;

To reproduce:

  • Create new project from the first person c++ sample

  • Add this to MyProjectGameMode.h

    void InitGame(const FString & MapName, const FString & Options, FString & ErrorMessage) override;

  • And finally add this to MyProjectGameMode.cpp and hit play. The editor should immediately crash without
    showing the message

    void AMyProjectGameMode::InitGame(const FString & MapName, const FString & Options,
    FString & ErrorMessage)
    {
    Super::InitGame(MapName, Options, ErrorMessage);

     // This causes a crash //
     {
     std::string InnocentString = "INFO would be merged here things;";
    
     check(InnocentString.length() > 0);
     }
     
     GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("This is an on screen message!"));
    

    }

Commenting out the string stops the crashing.

Here’s a core file: https://boostslair.com/files/core.15258.7z Here’s the full project I created to test this: https://boostslair.com/files/MyProject_sample_crash.7z

And this is the callstack I get when the editor crashes:

#0  0x00007febe035e702 in free () from /lib64/libc.so.6
#1  0x00007febec8c48a6 in FMallocThreadSafeProxy::Free (this=0x20190a0, Ptr=0xc425f00)
    at Runtime/Core/Public/HAL/MallocThreadSafeProxy.h:62
#2  0x00007feb5fe65676 in operator delete (Ptr=0x31)
    at /home/hhyyrylainen/Unreal Projects/MyProject/Source/MyProject/MyProject.cpp:6
#3  0x00007feb5fe6907e in __gnu_cxx::new_allocator<char>::deallocate (
    __p=0x31 <error: Cannot access memory at address 0x31>, this=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-redhat-linux/5.3.1/../../../../include/c++/5.3.1/ext/new_allocator.h:110
#4  std::allocator_traits<std::allocator<char> >::deallocate (
    __p=0x31 <error: Cannot access memory at address 0x31>, __a=..., __n=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-redhat-linux/5.3.1/../../../../include/c++/5.3.1/bits/alloc_traits.h:517
#5  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy (
    this=<optimized out>, __size=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-redhat-linux/5.3.1/../../../../include/c++/5.3.1/bits/basic_string.h:185
#6  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose (
    this=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-redhat-linux/5.3.1/../../../../include/c++/5.3.1/bits/basic_string.h:180
#7  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string (
    this=<optimized out>)
    at /usr/bin/../lib/gcc/x86_64-redhat-linux/5.3.1/../../../../include/c++/5.3.1/bits/basic_string.h:543
#8  AMyProjectGameMode::InitGame (this=<optimized out>, MapName=..., Options=..., ErrorMessage=...)
    at /home/hhyyrylainen/Unreal Projects/MyProject/Source/MyProject/MyProjectGameMode.cpp:37
#9  0x00007febe9d9153a in UWorld::InitializeActorsForPlay (this=<optimized out>, InURL=..., 
    bResetTime=<optimized out>)
    at /home/hhyyrylainen/Projects/UnrealEngine/Engine/Source/Runtime/Engine/Private/World.cpp:3154
#10 0x00007febe920f560 in UGameInstance::StartPIEGameInstance (this=<optimized out>, 
    LocalPlayer=<optimized out>, bInSimulateInEditor=<optimized out>, 
    bAnyBlueprintErrors=<optimized out>, bStartInSpectatorMode=<optimized out>)
    at /home/hhyyrylainen/Projects/UnrealEngine/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:265
#11 0x00007febe2ed3417 in UEditorEngine::CreatePIEGameInstance (this=<optimized out>, 
    InPIEInstance=<optimized out>, bInSimulateInEditor=<optimized out>, 
    bAnyBlueprintErrors=<optimized out>, 
    bStartInSpectatorMode=<error reading variable: access outside bounds of object referenced via synthetic pointer>, bRunAsDedicated=<optimized out>, PIEStartTime=<optimized out>)
    at /home/hhyyrylainen/Projects/UnrealEngine/Engine/Source/Editor/UnrealEd/Private/PlayLevel.cpp:3249
#12 0x00007febe2ecac02 in UEditorEngine::PlayInEditor (this=<optimized out>, InWorld=<optimized out>, 
    bInSimulateInEditor=<optimized out>)
    at /home/hhyyrylainen/Projects/UnrealEngine/Engine/Source/Editor/UnrealEd/Private/PlayLevel.cpp:2344
#13 0x00007febe2ebb59e in UEditorEngine::StartQueuedPlayMapRequest (this=0x17597c40)
    at /home/hhyyrylainen/Projects/UnrealEngine/Engine/Source/Editor/UnrealEd/Private/PlayLevel.cpp:1097
#14 0x00007febe287a2ad in UEditorEngine::Tick (this=<optimized out>, DeltaSeconds=<optimized out>, 
    bIdleMode=<optimized out>)
    at /home/hhyyrylainen/Projects/UnrealEngine/Engine/Source/Editor/UnrealEd/Private/EditorEngine.cpp:1246
#15 0x00007febe3272170 in UUnrealEdEngine::Tick (this=0x17597c40, DeltaSeconds=0,00833345484, 

OS: Fedora 23, Kernel: 4.5.6-200.fc23.x86_64 (x86_64), Desktop: GNOME Shell 3.18.5, Display Driver: NVIDIA 358.16, OpenGL: 4.4.0, Compiler: GCC 5.3.1 20160406 + Clang 3.8.0, File-System: ext4, Screen Resolution: 3840x1080

Hey hhyyrylainen-

Rather than using std::string, the engine implements its own macro for handling/using strings which is FString. You should be able to replace std::string with FString to avoid the crash. This would also include changing the .length() in your check (line 10) to .Len() which is the FString function to return the length of a string.

Cheers

Hi,
I do use FStrings everywhere else, but I’m using an external library which uses std::strings. This just demonstrates that even without the library using std::string causes crashes.
If std::string cannot be used at all, I can see only two options, both of which are not worth the trouble:

  • Use the library in a separate executable and use RPCs to get the data to the game process.

  • Or rewrite the library functionality with FStrings, which would be a nightmare to try to maintain.

Meaning that it’s impossible to use libraries that aren’t specifically written for unreal engine (on linux, on windows the library works perfectly)

You can also wrap the library in a C interface. C++ compatibility is very flaky, this may not work even without Unreal Engine, e.g. if the library was compiled against libc++ but used with libstdc++.