Description
First of all, thank you for sharing the great plugin.
I have slightly modified the C++ publish / subscribe examples in the Readme.md.
After setting up & build the plugin, I have created two C++ Actor classes called, Publisher and Subscriber. In UE4Editor, I have added each class to the level editor by drag & drop.
Basically, the idea is that Publisher publishes a string message at each frame to the example_topic, and Subscriber listens to the example_topic and prints out what it heard to the console.
Every time I run the game in UE4Editor, everything works perfectly for the first 1 minute. However, some point after a minute, UE4Editor crashes with the following error message:
.
.
.
Subscriber listened: Message from frame 5035
Subscriber listened: Message from frame 5036
Subscriber listened: Message from frame 5037
Subscriber listened: Message from frame 5039
Subscriber listened: Message from frame 5040
Subscriber listened: Message from frame 5041
Subscriber listened: Message from frame 5042
Subscriber listened: Message from frame 5043
Subscriber listened: Message from frame 5045
Subscriber listened: Message from frame 5046
Subscriber listened: Message from frame 5047
Subscriber listened: Message from frame 5048
Subscriber listened: Message from frame 5049
Subscriber listened: Message from frame 5051
Subscriber listened: Message from frame 5052
Subscriber listened: Message from frame 5053
Subscriber listened: Message from frame 5054
Subscriber listened: Message from frame 5056
Subscriber listened: Message from frame 5057
Subscriber listened: Message from frame 5058
Subscriber listened: Message from frame 5059
Subscriber listened: Message from frame 5060
[ROSBridge] Found CB in UnregisterTopicCallback. Deleting it ...
[ROSTopic] No callbacks registered anymore - unsubscribe from topic
Signal 11 caught.
Malloc Size=131076 LargeMemoryPoolOffset=131092
CommonLinuxCrashHandler: Signal=11
Malloc Size=65535 LargeMemoryPoolOffset=196655
[2018.05.25-09.27.55:775][937]LogLinux: === Critical error: ===
Unhandled Exception: SIGSEGV: invalid attempt to read memory at address 0x00000000e30800a0
[2018.05.25-09.27.55:775][937]LogLinux: Fatal error!
0x00007f9cd4b6a625 FLinuxPlatformStackWalk::CaptureStackBackTrace(unsigned long long*, unsigned int, void*)
0x00007f9cd4a18c75 FGenericPlatformStackWalk::StackWalkAndDump(char*, unsigned long, int, void*)
0x00007f9cd4b1b231 FLinuxCrashContext::CaptureStackTrace()
0x00007f9cca344400 CommonLinuxCrashHandler(FGenericCrashContext const&)
0x00007f9cd4b1d2bd PlatformCrashHandler(int, siginfo_t*, void*)
0x00007f9cd5781390 /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390) [0x7f9cd5781390]
0x00007f9bc6cc3efe rosbridge2cpp::ROSTopic::GeneratePublishID()
0x00007f9bc6cc3048 rosbridge2cpp::ROSTopic::Publish(_bson_t*)
0x00007f9bc6cd7f18 UTopic::Impl::Publish(TSharedPtr<FROSBaseMsg, (ESPMode)0>)
0x00007f9bc6cc98b3 UTopic::Publish(TSharedPtr<FROSBaseMsg, (ESPMode)0>)
0x00007f9bb5d2da58 APublisher::Publish(char const*)
0x00007f9bb5d2d81d APublisher::Tick(float)
0x00007f9cd1243983 FActorTickFunction::ExecuteTick(float, ELevelTick, ENamedThreads::Type, TRefCountPtr<FGraphEvent> const&)
0x00007f9cd25efab6 FTickFunctionTask::DoTask(ENamedThreads::Type, TRefCountPtr<FGraphEvent> const&)
0x00007f9cd25ef41f TGraphTask<FTickFunctionTask>::ExecuteTask(TArray<FBaseGraphTask*, FDefaultAllocator>&, ENamedThreads::Type)
0x00007f9cd4a4443f FNamedTaskThread::ProcessTasksNamedThread(int, bool)
0x00007f9cd4a43903 FNamedTaskThread::ProcessTasksUntilQuit(int)
0x00007f9cd25e9813 FTickTaskSequencer::ReleaseTickGroup(ETickingGroup, bool)
0x00007f9cd25e2694 FTickTaskManager::RunTickGroup(ETickingGroup, bool)
0x00007f9cd1c2635f UWorld::RunTickGroup(ETickingGroup, bool)
0x00007f9cd1c303ee UWorld::Tick(ELevelTick, float)
0x00007f9ccb4888a2 UEditorEngine::Tick(float, bool)
0x00007f9ccbeb93e6 UUnrealEdEngine::Tick(float, bool)
0x00000000004255f3 FEngineLoop::Tick() [/home/jchoi/UnrealEngine/Engine/Source/Runtime/Launch/Private/LaunchEngineLoop.cpp:3339]
0x000000000042fed3 GuardedMain(wchar_t const*) [/home/jchoi/UnrealEngine/Engine/Source/Runtime/Launch/Private/Launch.cpp:62]
0x00007f9cca345227 CommonLinuxMain(int, char**, int (*)(wchar_t const*))
0x00007f9cc9d90830 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f9cc9d90830]
0x00000000004169c9 /home/jchoi/UnrealEngine/Engine/Binaries/Linux/UE4Editor(_start+0x29) [0x4169c9]
[2018.05.25-09.27.55:785][937]LogExit: Executing StaticShutdownAfterError
Malloc Size=772626 LargeMemoryPoolOffset=969298
LogPlatformFile: Not using cached read wrapper
LogInit: Display: RandInit(1644944209) SRandInit(1644944209).
LogTaskGraph: Started task graph with 4 named threads and 7 total threads with 1 sets of task threads.
LogInit: Build: ++UE4+Release-4.19-CL-0
LogInit: Engine Version: 4.19.2-0+++UE4+Release-4.19
LogInit: Compatible Engine Version: 4.19.0-0+++UE4+Release-4.19
LogInit: Net CL: 0
LogInit: Compiled (64-bit): May 10 2018 13:38:33
LogInit: Compiled with Clang: 3.8.0 (tags/RELEASE_380/final)
LogInit: Build Configuration: Shipping
LogInit: Branch Name: ++UE4+Release-4.19
LogInit: Command Line: -Abslog=/home/jchoi/Documents/Unreal Projects/ROSIntegrationTest/Saved/Logs/ROSIntegrationTest-CRC.log /home/jchoi/Documents/Unreal Projects/ROSIntegrationTest/Saved/Crashes/crashinfo-ROSIntegrationTest-pid-26649-13C1CCC037051219001B0312620BBC7F/
LogInit: Base Directory: /home/jchoi/UnrealEngine/Engine/Binaries/Linux/
LogInit: Installed Engine Build: 1
LogInit: Presizing for max 100000 objects, including 0 objects not considered by GC, pre-allocating 0 bytes for permanent pool.
LogInit: Object subsystem initialized
[2018.05.25-09.27.55:863][ 0]LogInit: Linux hardware info:
[2018.05.25-09.27.55:863][ 0]LogInit: - we are the first instance of this executable
[2018.05.25-09.27.55:863][ 0]LogInit: - this process' id (pid) is 5484, parent process' id (ppid) is 26649
[2018.05.25-09.27.55:863][ 0]LogInit: - we are not running under debugger
[2018.05.25-09.27.55:863][ 0]LogInit: - machine network name is 'jchoi-desktop'
[2018.05.25-09.27.55:863][ 0]LogInit: - user name is 'jchoi' (jchoi)
[2018.05.25-09.27.55:863][ 0]LogInit: - we're logged in locally
[2018.05.25-09.27.55:863][ 0]LogInit: - we're running with rendering
[2018.05.25-09.27.55:863][ 0]LogInit: - CPU: GenuineIntel 'Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz' (signature: 0x906E9)
[2018.05.25-09.27.55:863][ 0]LogInit: - Number of physical cores available for the process: 4
[2018.05.25-09.27.55:863][ 0]LogInit: - Number of logical cores available for the process: 8
[2018.05.25-09.27.55:863][ 0]LogInit: - Cache line size: 64
[2018.05.25-09.27.55:863][ 0]LogInit: - Memory allocator used: binned2
[2018.05.25-09.27.55:863][ 0]LogLinux: Skipped benchmarking clocks because the engine is running in a standalone program mode - CLOCK_REALTIME will be used.
[2018.05.25-09.27.55:863][ 0]LogInit: Linux-specific commandline switches:
[2018.05.25-09.27.55:863][ 0]LogInit: -nodwarf (currently OFF): suppress parsing of DWARF debug info (callstacks will be generated faster, but won't have line numbers)
[2018.05.25-09.27.55:863][ 0]LogInit: -ansimalloc - use malloc()/free() from libc (useful for tools like valgrind and electric fence)
[2018.05.25-09.27.55:863][ 0]LogInit: -jemalloc - use jemalloc for all memory allocation
[2018.05.25-09.27.55:863][ 0]LogInit: -binnedmalloc - use binned malloc for all memory allocation
[2018.05.25-09.27.55:863][ 0]LogInit: -httpproxy=ADDRESS:PORT - redirects HTTP requests to a proxy (only supported if compiled with libcurl)
[2018.05.25-09.27.55:863][ 0]LogInit: -reuseconn - allow libcurl to reuse HTTP connections (only matters if compiled with libcurl)
[2018.05.25-09.27.55:863][ 0]LogInit: -virtmemkb=NUMBER - sets process virtual memory (address space) limit (overrides VirtualMemoryLimitInKB value from .ini)
[2018.05.25-09.27.55:863][ 0]LogInit: - Physical RAM available (not considering process quota): 16 GB (16004 MB, 16388412 KB, 16781733888 bytes)
[2018.05.25-09.27.55:864][ 0]LogUObjectArray: 149 objects as part of root set at end of initial load.
[2018.05.25-09.27.55:864][ 0]LogUObjectAllocator: 22184 out of 0 bytes used by permanent object pool.
[2018.05.25-09.27.55:864][ 0]LogUObjectArray: CloseDisregardForGC: 0/0 objects in disregard for GC pool
[2018.05.25-09.27.55:864][ 0]LogInit: Using OS detected language ().
[2018.05.25-09.27.55:864][ 0]LogInit: Using OS detected locale ().
[2018.05.25-09.27.55:864][ 0]LogTextLocalizationManager: No localization for '' exists, so 'en' will be used for the language.
[2018.05.25-09.27.55:864][ 0]LogTextLocalizationManager: No localization for '' exists, so 'en' will be used for the locale.
[2018.05.25-09.27.55:866][ 0]CrashReportClientLog: CrashReportClientVersion=1.0
[2018.05.25-09.27.55:866][ 0]CrashReportClientLog: CrashReportReceiver disabled
[2018.05.25-09.27.55:866][ 0]CrashReportClientLog: DataRouterUrl: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data
[2018.05.25-09.27.55:866][ 0]LogExit: Preparing to exit.
[2018.05.25-09.27.55:866][ 0]LogExit: Object subsystem successfully closed.
[2018.05.25-09.27.55:867][ 0]LogModuleManager: Shutting down and abandoning module CoreUObject (4)
[2018.05.25-09.27.55:867][ 0]LogModuleManager: Shutting down and abandoning module SandboxFile (2)
[2018.05.25-09.27.55:867][ 0]LogExit: Exiting.
Engine crash handling finished; re-raising signal 11 for the default handler. Good bye.
The crash occurs at different frame number every time I try.
I was able to prevent UE4Editor from crashing by setting
bPublish = false;
in the Publisher.h below. (i.e. by not publishing any message)
But I still get the following message
[ROSBridge] Found CB in UnregisterTopicCallback. Deleting it ...
[ROSTopic] No callbacks registered anymore - unsubscribe from topic
I've never called ROSBridge::UnregisterTopicCallback in my code, but somehow it is called and causes the Subscriber to unsubscribe from the topic. So I tried to modify some parts of the plugin code, but it didn't go anywhere.
I've been fighting with this more than 6 hours but have no idea to fix it. Please help me!
Here are my codes.
Publisher.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Publisher.generated.h"
UCLASS()
class ROSINTEGRATIONTEST_API APublisher : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
APublisher();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
class UTopic *ExampleTopic;
void Publish(const char* Content);
int nFrames;
bool bPublish = true;
};
Publisher.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Publisher.h"
#include "ROSIntegration/Classes/RI/Topic.h"
#include "ROSIntegration/Classes/ROSIntegrationGameInstance.h"
#include "ROSIntegration/Public/std_msgs/String.h"
#include <sstream>
// Sets default values
APublisher::APublisher()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void APublisher::BeginPlay()
{
Super::BeginPlay();
ExampleTopic = NewObject<UTopic>(UTopic::StaticClass());
UROSIntegrationGameInstance* rosinst = Cast<UROSIntegrationGameInstance>(GetGameInstance());
ExampleTopic->Init(rosinst->ROSIntegrationCore, TEXT("/example_topic"), TEXT("std_msgs/String"));
}
// Called every frame
void APublisher::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
nFrames++;
if(bPublish)
{
std::ostringstream oss;
oss << "Message from frame " << nFrames;
Publish(oss.str().c_str());
}
}
void APublisher::Publish(const char *Content)
{
TSharedPtr<ROSMessages::std_msgs::String> StringMessage(new ROSMessages::std_msgs::String(Content));
ExampleTopic->Publish(StringMessage);
}
Subscriber.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Subscriber.generated.h"
UCLASS()
class ROSINTEGRATIONTEST_API ASubscriber : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ASubscriber();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
class UTopic *ExampleTopic;
static void SubscribeCallbackImpl(TSharedPtr<class FROSBaseMsg> msg);
};
Subscriber.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Subscriber.h"
#include "ROSIntegration/Classes/RI/Topic.h"
#include "ROSIntegration/Classes/ROSIntegrationGameInstance.h"
#include "ROSIntegration/Public/std_msgs/String.h"
#include <iostream>
// Sets default values
ASubscriber::ASubscriber()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ASubscriber::BeginPlay()
{
Super::BeginPlay();
ExampleTopic = NewObject<UTopic>(UTopic::StaticClass());
UROSIntegrationGameInstance* rosinst = Cast<UROSIntegrationGameInstance>(GetGameInstance());
ExampleTopic->Init(rosinst->ROSIntegrationCore, TEXT("/example_topic"), TEXT("std_msgs/String"));
std::function<void(TSharedPtr<FROSBaseMsg>)> SubscribeCallback = ASubscriber::SubscribeCallbackImpl;
ExampleTopic->Subscribe(SubscribeCallback);
}
// Called every frame
void ASubscriber::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ASubscriber::SubscribeCallbackImpl(TSharedPtr<FROSBaseMsg> msg)
{
auto Concrete = StaticCastSharedPtr<ROSMessages::std_msgs::String>(msg);
if (Concrete.IsValid())
{
std::cout << "Subscriber listened: " << TCHAR_TO_UTF8(*(Concrete->_Data)) << std::endl;
}
return;
}