Skip to content

Greengrass IPC Subscriber C++ sample code Segfaults at the creation of GreengrassCoreIpcClient #792

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

Open
asdsastha opened this issue Apr 15, 2025 · 5 comments
Labels
bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.

Comments

@asdsastha
Copy link

asdsastha commented Apr 15, 2025

Describe the bug

The sample application fails to create a GreengrassCoreIpcClient object and gives a seg-fault when deployed, with the error message

Component_status: Errored
RUN_ERROR: An error occurred while running the component with error code: 139

Code:

#include <iostream>
#include <thread>

#include <aws/crt/Api.h>
#include <aws/greengrass/GreengrassCoreIpcClient.h>

using namespace Aws::Crt;
using namespace Aws::Greengrass;

class IoTCoreResponseHandler : public SubscribeToIoTCoreStreamHandler {

    public:
        virtual ~IoTCoreResponseHandler() {}

    private:

        void OnStreamEvent(IoTCoreMessage *response) override {
            auto message = response->GetMessage();
            if (message.has_value() && message.value().GetPayload().has_value()) {
                auto messageBytes = message.value().GetPayload().value();
                std::string messageString(messageBytes.begin(), messageBytes.end());
                std::string messageTopic = message.value().GetTopicName().value().c_str();
                std::cout << "Received new message on topic: " << messageTopic << std::endl;
                std::cout << "Message: " << messageString << std::endl;
            }
        }

        bool OnStreamError(OperationError *error) override {
            std::cout << "Received an operation error: ";
            if (error->GetMessage().has_value()) {
                std::cout << error->GetMessage().value();
            }
            std::cout << std::endl;
            return false; // Return true to close stream, false to keep stream open.
        }

        void OnStreamClosed() override {
            std::cout << "Subscribe to IoT Core stream closed." << std::endl;
        }
};

class IpcClientLifecycleHandler : public ConnectionLifecycleHandler {
    void OnConnectCallback() override {
        std::cout << "OnConnectCallback" << std::endl;
    }

    void OnDisconnectCallback(RpcError error) override {
        std::cout << "OnDisconnectCallback: " << error.StatusToString() << std::endl;
        exit(-1);
    }

    bool OnErrorCallback(RpcError error) override {
        std::cout << "OnErrorCallback: " << error.StatusToString() << std::endl;
        return true;
    }
};

int main() {
    String topic("test/topic/cpp");
    QOS qos = QOS_AT_LEAST_ONCE;
    int timeout = 10;

    ApiHandle apiHandle(g_allocator);
    Io::EventLoopGroup eventLoopGroup(1);
    Io::DefaultHostResolver socketResolver(eventLoopGroup, 64, 30);
    Io::ClientBootstrap bootstrap(eventLoopGroup, socketResolver);
    IpcClientLifecycleHandler ipcLifecycleHandler;
    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();
    if (!connectionStatus) {
        std::cerr << "Failed to establish IPC connection: " << connectionStatus.StatusToString() << std::endl;
        exit(-1);
    }

    SubscribeToIoTCoreRequest request;
    request.SetTopicName(topic);
    request.SetQos(qos);
    auto streamHandler = MakeShared<IoTCoreResponseHandler>(DefaultAllocator());
    auto operation = ipcClient.NewSubscribeToIoTCore(streamHandler);
    auto activate = operation->Activate(request, nullptr);
    activate.wait();

    auto responseFuture = operation->GetResult();
    if (responseFuture.wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout) {
        std::cerr << "Operation timed out while waiting for response from Greengrass Core." << std::endl;
        exit(-1);
    }

    auto response = responseFuture.get();
    if (response) {
        std::cout << "Successfully subscribed to topic: " << topic << std::endl;
    } else {
        // An error occurred.
        std::cout << "Failed to subscribe to topic: " << topic << std::endl;
        auto errorType = response.GetResultType();
        if (errorType == OPERATION_ERROR) {
            auto *error = response.GetOperationError();
            std::cout << "Operation error: " << error->GetMessage().value() << std::endl;
        } else {
            std::cout << "RPC error: " << response.GetRpcError() << std::endl;
        }
        exit(-1);
    }

    // Keep the main thread alive, or the process will exit.
    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }

    operation->Close();
    return 0;
}

Expected Behavior

The code should be in running state and the user should be able to see messages published by the Aws-Iot Core in the logs

Current Behavior

Getting Error with code: 139

And a segfault in the run.

ERROR LOG:
$:/greengrass/v2/logs# cat com.example.HelloWorld.log
2025-04-15T08:35:38.938Z [INFO] (pool-3-thread-26) com.example.HelloWorld: shell-runner-start. {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=STARTING, command=["/greengrass/v2/packages/artifacts/com.example.HelloWorld/1.0.4/HelloWorld"]}
2025-04-15T08:35:38.961Z [INFO] (Copier) com.example.HelloWorld: Run script exited. {exitCode=0, serviceName=com.example.HelloWorld, currentState=RUNNING}
2025-04-15T08:43:23.245Z [INFO] (pool-3-thread-29) com.example.HelloWorld: shell-runner-start. {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=STARTING, command=["/greengrass/v2/packages/artifacts/com.example.HelloWorld/1.0.5/HelloWorld"]}
2025-04-15T08:43:23.400Z [WARN] (Copier) com.example.HelloWorld: stderr. Segmentation fault (core dumped). {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=RUNNING}
2025-04-15T08:43:23.406Z [INFO] (Copier) com.example.HelloWorld: Run script exited. {exitCode=139, serviceName=com.example.HelloWorld, currentState=RUNNING}
2025-04-15T08:43:23.419Z [INFO] (pool-3-thread-30) com.example.HelloWorld: shell-runner-start. {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=STARTING, command=["/greengrass/v2/packages/artifacts/com.example.HelloWorld/1.0.5/HelloWorld"]}
2025-04-15T08:43:23.586Z [WARN] (Copier) com.example.HelloWorld: stderr. Segmentation fault (core dumped). {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=RUNNING}
2025-04-15T08:43:23.591Z [INFO] (Copier) com.example.HelloWorld: Run script exited. {exitCode=139, serviceName=com.example.HelloWorld, currentState=RUNNING}
2025-04-15T08:43:23.596Z [INFO] (pool-3-thread-30) com.example.HelloWorld: shell-runner-start. {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=STARTING, command=["/greengrass/v2/packages/artifacts/com.example.HelloWorld/1.0.5/HelloWorld"]}
2025-04-15T08:43:23.746Z [WARN] (Copier) com.example.HelloWorld: stderr. Segmentation fault (core dumped). {scriptName=services.com.example.HelloWorld.lifecycle.Run, serviceName=com.example.HelloWorld, currentState=RUNNING}
2025-04-15T08:43:23.749Z [INFO] (Copier) com.example.HelloWorld: Run script exited. {exitCode=139, serviceName=com.example.HelloWorld, currentState=RUNNING}

Reproduction Steps

CMakeLists.txt

build the code using the above cmake and deploy it as a component to the greengrass device.

Possible Solution

No response

Additional Information/Context

Using the following openssl version: OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

SDK version used

v0.31.0

Environment details (OS name and version, etc.)

Ubuntu 22.04.5 LTS

@asdsastha asdsastha added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Apr 15, 2025
@sfod
Copy link
Contributor

sfod commented Apr 15, 2025

I'm trying to reproduce the segfault, no luck so far.
Can you try to identify the exact line where it happens? It'll help a lot.

@asdsastha
Copy link
Author

asdsastha commented Apr 16, 2025

Hi @sfod, I am getting the seg-fault while creating the IPC-Client.

    GreengrassCoreIpcClient ipcClient(bootstrap);
    auto connectionStatus = ipcClient.Connect(ipcLifecycleHandler).get();

Also FYI: I am using the following openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

Edit:
I have switched the openssl version to 1.1.1 by building it from source and using that openssl to build aws-cpp sdk. I still face the same issue

@sfod
Copy link
Contributor

sfod commented Apr 17, 2025

To investigate this issue further, we need more information. Otherwise, this might take much more time than it should.
If you could run the sample with the debugger, it'd give us all we need. I found this instruction on how to debug a Greengrass component: https://dev.to/iotbuilders/debugging-cc-greengrass-components-using-vscode-1nbh
They even use the same example.

@asdsastha
Copy link
Author

I have got the following error message when I used gdb form the above step.
Failed to establish IPC connection: Failed with EVENT_STREAM_RPC_CRT_ERROR, the CRT error was Unknown Error Code

This looks more like a configuration issue. I am re-checking at my end.

Also please let me know if any Backtrace or something is needed here

@sfod
Copy link
Contributor

sfod commented Apr 25, 2025

Yeah, that's strange. Maybe the cmd options weren't passed?
If you'll manage to catch the segfault in the debugger, the backtrace and maybe local variables should suffice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. needs-triage This issue or PR still needs to be triaged.
Projects
None yet
Development

No branches or pull requests

2 participants