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

Agent has crashed when using UXR_REUSE flag on entity's creation #331

Closed
bhlt opened this issue Nov 7, 2022 · 10 comments
Closed

Agent has crashed when using UXR_REUSE flag on entity's creation #331

bhlt opened this issue Nov 7, 2022 · 10 comments

Comments

@bhlt
Copy link

bhlt commented Nov 7, 2022

Change creation mode from UXR_REPLACE to UXR_RESUE in RequestAdder example, then the DDS Agent has been aborted when I run this example app secondly!!!
Modify:

const char* participant_xml = "<dds>"
            "<participant>"
            "<rtps>"
            "<name>default_xrce_participant</name>"
            "</rtps>"
            "</participant>"
            "</dds>";
    uint16_t participant_req = uxr_buffer_create_participant_xml(&session, reliable_out, participant_id, 0,
                    participant_xml, UXR_REPLACE);

    replier_id = uxr_object_id(0x01, UXR_REPLIER_ID);
    const char* replier_xml = "<dds>"
            "<replier profile_name=\"my_requester\""
            "service_name=\"service_name\""
            "request_type=\"request_type\""
            "reply_type=\"reply_type\">"
            "</replier>"
            "</dds>";
    uint16_t replier_req = uxr_buffer_create_replier_xml(&session, reliable_out, replier_id, participant_id,
                    replier_xml, UXR_REPLACE);

runing twice, Agent is aborted, as below:

terminate called after throwing an instance of 'dds::xrce::XRCETypesException'
  what():  This member is not been selected

the Agent backtrace is:

(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737211524672) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737211524672) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737211524672, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7331476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff73177f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff75b9bbe in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff75c524c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff75c52b7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff75c5518 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#9  0x00007ffff7d0b846 in dds::xrce::OBJK_Representation3Formats::object_reference[abi:cxx11]() const (this=0x7fffef7fda80) at /projects/git/Micro-XRCE-DDS-Agent/src/cpp/types/XRCETypes.cpp:1333
#10 0x00007ffff7d03f14 in eprosima::uxr::Requester::matched (this=0x7fffe010b990, new_object_rep=...) at /projects/git/Micro-XRCE-DDS-Agent/src/cpp/requester/Requester.cpp:103
#11 0x00007ffff7ce5e99 in eprosima::uxr::ProxyClient::create_object (this=0x7fffe0000b80, creation_mode=..., objectid_prefix=..., object_representation=...)
    at /projects/git/Micro-XRCE-DDS-Agent/src/cpp/client/ProxyClient.cpp:140

Can tell me what the problem is?

@pablogs9
Copy link
Member

pablogs9 commented Nov 7, 2022

@bhlt
Copy link
Author

bhlt commented Nov 7, 2022

It works when using UXR_REPLACE mode

@pablogs9
Copy link
Member

pablogs9 commented Nov 7, 2022

In order to use UXR_RESUE the entities must exist in order to be reusable.

@bhlt
Copy link
Author

bhlt commented Nov 7, 2022

I thought the entities has existed, because it's normal at the first running, but Agent crashed after trying again.

@pablogs9
Copy link
Member

pablogs9 commented Nov 7, 2022

Please provide full code to replicate this issue so we can reproduce the error.

@bhlt
Copy link
Author

bhlt commented Nov 7, 2022

this is examples/RequestAdder/main.c, I change UXR_REPLACE to UXR_REUSE:

// Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <uxr/client/client.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>

#define STREAM_HISTORY  8
#define BUFFER_SIZE     UXR_CONFIG_UDP_TRANSPORT_MTU* STREAM_HISTORY

void on_reply(
        uxrSession* session,
        uxrObjectId object_id,
        uint16_t request_id,
        uint16_t reply_id,
        ucdrBuffer* ub,
        uint16_t length,
        void* args)
{
    (void) session;
    (void) object_id;
    (void) request_id;
    (void) length;
    (void) args;

    uint64_t result;
    ucdr_deserialize_uint64_t(ub, &result);

#ifdef WIN32
    printf("Reply received: %I64u [id: %d]\n", result, reply_id);
#else
    printf("Reply received: %" PRIu64 " [id: %d]\n", result, reply_id);
#endif /* ifdef WIN32 */
}

int main(
        int args,
        char** argv)
{
    if (3 > args || 0 == atoi(argv[2]))
    {
        printf("usage: program [-h | --help] | ip port [key]\n");
        return 0;
    }

    char* ip = argv[1];
    char* port = argv[2];
    uint32_t key = (args == 4) ? (uint32_t)atoi(argv[3]) : 0xAAAABBBB;

    // Transport
    uxrUDPTransport transport;
    if (!uxr_init_udp_transport(&transport, UXR_IPv4, ip, port))
    {
        printf("Error at init transport.\n");
        return 1;
    }

    // Session
    uxrSession session;
    uxr_init_session(&session, &transport.comm, key);
    uxr_set_reply_callback(&session, on_reply, false);
    if (!uxr_create_session(&session))
    {
        printf("Error at init session.\n");
        return 1;
    }

    // Streams
    uint8_t output_reliable_stream_buffer[BUFFER_SIZE];
    uxrStreamId reliable_out = uxr_create_output_reliable_stream(&session, output_reliable_stream_buffer, BUFFER_SIZE,
                    STREAM_HISTORY);

    uint8_t input_reliable_stream_buffer[BUFFER_SIZE];
    uxrStreamId reliable_in = uxr_create_input_reliable_stream(&session, input_reliable_stream_buffer, BUFFER_SIZE,
                    STREAM_HISTORY);

    // Create entities
    uxrObjectId participant_id = uxr_object_id(0x01, UXR_PARTICIPANT_ID);
    const char* participant_xml = "<dds>"
            "<participant>"
            "<rtps>"
            "<name>default_xrce_participant</name>"
            "</rtps>"
            "</participant>"
            "</dds>";
    uint16_t participant_req = uxr_buffer_create_participant_xml(&session, reliable_out, participant_id, 0,
                    participant_xml, UXR_REUSE);
                    // participant_xml, UXR_REPLACE);

    uxrObjectId requester_id = uxr_object_id(0x01, UXR_REQUESTER_ID);
    const char* requester_xml = "<dds>"
            "<requester profile_name=\"my_requester\""
            "service_name=\"service_name\""
            "request_type=\"request_type\""
            "reply_type=\"reply_type\">"
            "</requester>"
            "</dds>";
    uint16_t requester_req = uxr_buffer_create_requester_xml(&session, reliable_out, requester_id, participant_id,
                    requester_xml, UXR_REUSE);
                    // requester_xml, UXR_REPLACE);

    // Send create entities message and wait its status
    uint8_t status[2];
    uint16_t requests[2] = {
        participant_req, requester_req
    };
    if (!uxr_run_session_until_all_status(&session, 1000, requests, status, 2))
    {
        printf("Error at create entities: participant: %i requester: %i\n", status[0], status[1]);
        return 1;
    }

    // Request replies
    uxrDeliveryControl delivery_control = {
        0
    };
    delivery_control.max_samples = UXR_MAX_SAMPLES_UNLIMITED;
    uxr_buffer_request_data(&session, reliable_out, requester_id, reliable_in,
            &delivery_control);

    // Write requests
    bool connected = true;
    uint32_t count = 0;
    while (connected)
    {
        uint8_t request[2 * 4] = {
            0
        };
        ucdrBuffer ub;

        ucdr_init_buffer(&ub, request, sizeof(request));
        ucdr_serialize_uint32_t(&ub, count);
        ucdr_serialize_uint32_t(&ub, count);

        uint16_t request_id = uxr_buffer_request(&session, reliable_out, requester_id, request, sizeof(request));
        printf("Request sent: (%d + %d) [id: %d]\n", count, count, request_id);
        connected = uxr_run_session_time(&session, 1000);

        ++count;
    }

    return 0;
}

example
agent

@pablogs9
Copy link
Member

pablogs9 commented Nov 8, 2022

Which version of the Micro XRCE-DDS Agent and Client are you using? I have just replicated your code and I have found no error.

Please provide complete replication instructions.

@bhlt
Copy link
Author

bhlt commented Nov 8, 2022

Client version: 2.2.0
Agent vsersion: 2.2.0
build environment : Ubuntu 22.04, gcc 11.3.0, cmake 3.24.2
runtime environment: Ubuntu 22.04
Build agent without any modification, then modify examples/RequestAdder/main.c as mentioned above before client building.
start agent in shell by command "MicroXRCEAgent udp4 -p 2022"
start example client in another shell by command "RequestAdder 127.0.0.1 2022", then stop the client by Ctrl+C; start again by the same way. At this time, we can discover the Agent has crashed.

@pablogs9
Copy link
Member

pablogs9 commented Nov 8, 2022

Hello @bhlt I have found the bug, we are working on it here: eProsima/Micro-XRCE-DDS-Agent#318

I will notify when we merge it

@bhlt
Copy link
Author

bhlt commented Nov 9, 2022

Thanks @pablogs9

@bhlt bhlt closed this as completed Nov 9, 2022
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

2 participants