Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An actor subscribed to a topic is automatically unsubscribed after about a minute #32

Closed
jiwoong-choi opened this issue May 25, 2018 · 3 comments

Comments

@jiwoong-choi
Copy link

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;
}
@Hemofektik
Copy link
Contributor

Your topics are getting garbage collected and thus unsubscribe automatically.
Put UPROPERTY() before
class UTopic *ExampleTopic;
and it should no longer happen.

@jiwoong-choi
Copy link
Author

Now it works perfectly fine. Thank you so much!

@xgwang
Copy link

xgwang commented Mar 11, 2020

Your topics are getting garbage collected and thus unsubscribe automatically.
Put UPROPERTY() before
class UTopic *ExampleTopic;
and it should no longer happen.

may i know the GC rules here? why this member pointer is GCed?

thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants