rosbag2 icon indicating copy to clipboard operation
rosbag2 copied to clipboard

rosbag2_cpp::Writer can not close correctly, rasing "Segmentation fault(core dumped)" Error

Open M201871109 opened this issue 11 months ago • 10 comments

Description

I want to write some pointcloud msg to the local rosbag,when I use the rosbag2_cpp:Writer to realize this funciton, it can write the msg to the local .db3 file, and can be visualized in the rviz2. But the rosbag2_cpp::Writer can not deconstructed correctly, rasing "Segmentation fault(core dumped)" Error. And no "metadata.yaml" created.

Expected Behavior

I hope that I can deconstructed the Writer correctly.

Actual Behavior

the following is the code I used: std::unique_ptr<rosbag2_cpp::Writer> writer_ = std::make_unique<rosbag2_cpp::Writer>(); writer_->open(rosbag_dir); // rosbag_dir is a path that does not exist

.... // msg data process ... writer_->writer(msg, topic, time)// write the pointcloud message the the bag file

writer.reset() // raise "Segmentation fault(core dumped)" Error

Especially, even if I deconstructed the Writer() after the open() function, the same bug occured, eg: writer_->open(rosbag_dir); writer.reset() // raise "Segmentation fault(core dumped)" Error

To Reproduce

** Steps to reproduce the behavior, e.g.

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. Logs print error '...' **

System (please complete the following information)

  • OS: [Ubuntu 20.04]
  • ROS 2 Distro: [galactic]
  • C++ project

Additional context

I try to test in another C++ project, and it can close correctly. But the code is all the same.

M201871109 avatar Mar 15 '24 06:03 M201871109

@M201871109 Sorry, but Galactic reached EOL and we don't support it.
Can you please try to reproduce it at least on Humble or Iron ROS 2 distros?

MichaelOrlov avatar Mar 15 '24 07:03 MichaelOrlov

@M201871109 As a workaround I can suggest to try calling writer_->close() before writer.reset()

MichaelOrlov avatar Mar 15 '24 07:03 MichaelOrlov

@MichaelOrlov I can confirm this on humble. Just ran into the same issue. I haven't investigated further, but it breaks somewhere between creating the next folder and logging Opened database '[DB_FILE]' for READ_WRITE

yschulz avatar Mar 16 '24 11:03 yschulz

If you want to reproduce the issue, I extended the test_rosbag_cpp_api here.

yschulz avatar Mar 17 '24 10:03 yschulz

@M201871109 Sorry, but Galactic reached EOL and we don't support it. Can you please try to reproduce it at least on Humble or Iron ROS 2 distros?

Thank you very much for your suggestion, I will try it in newer distros. But there is another strange question, I try to reproduce the bug in another demo C++ project, this time I can deconstruct the Writer correctly,and the code in both project alomost the same, which really confused me.

M201871109 avatar Mar 18 '24 07:03 M201871109

@M201871109 As a workaround I can suggest to try calling writer_->close() before writer.reset()

Thank you very much for your suggestion. But the rosbag2_cpp::Writer in galactic distro has no close() method. And I try to close the writer in the following way: writer_interfaces::BaseWriterInterface& impl = writer_->get_implementation_handle(); impl.close() // raising "Segmentation fault(core dumped)"

M201871109 avatar Mar 18 '24 07:03 M201871109

@M201871109 can you provide a SSCCE for this?

fujitatomoya avatar Mar 18 '24 17:03 fujitatomoya

@M201871109 can you provide a SSCCE for this?

Here are the source code.

rosbag_saver.h

#pragma once
#include <memory>
#include <rosbag2_cpp/writer.hpp>

class RosbagSaver
{
private:
    std::unique_ptr<rosbag2_cpp::Writer> writer_ros_ { nullptr };
public:
    bool Init();
};

rosbag_saver.cpp


#include "rosbag_saver.h"
#include <chrono>
#include <iostream>
bool RosbagSaver::Init()
{
    writer_ros_ = std::make_unique<rosbag2_cpp::Writer>();
    std::string rosbag_dir = "/home/hirain/TEST/du.he/rosbag/example";
    if (writer_ros_) {
        writer_ros_->open(rosbag_dir);
    }
    std::cout << "!!!!!!!!!!" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
    
    rosbag2_cpp::writer_interfaces::BaseWriterInterface& impl = writer_ros_->get_implementation_handle();
    std::cout << "111111111111" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));

    impl.close();  // sometimes raise "Segmentation Error"
    std::cout << "33333333333333333" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));

    writer_ros_.reset();
    std::cout << "************" << std::endl;

    return true;
}

main.cpp

#include <iostream>
#include "rosbag_saver.h"


int main()
{
    std::shared_ptr<RosbagSaver> a_ptr;
    a_ptr = std::make_shared<RosbagSaver>();
    if (!a_ptr->Init()) std::cout << "@@@@@@@@@@@@@@@@@@@@" << std::endl;

    std::cout << "!!!!!!" << std::endl;

    return 0;
}

But there is something strange, I try to run the code in different demo project, it can close correctly in project A, but can not in project B and no metadata.yaml created.

M201871109 avatar Mar 20 '24 05:03 M201871109

But there is something strange, I try to run the code in different demo project, it can close correctly in project A, but can not in project B and no metadata.yaml created.

I also cannot reproduce the issue with your sample.

fujitatomoya avatar Mar 28 '24 20:03 fujitatomoya

@M201871109 As regards

it can close correctly in project A, but can not in project B and no metadata.yaml created.

When you mentioned different projects what did you mean under the term "Project"?

Advise: Make sure that everything builds in the same mode. i.e. "Debug" or "ReleaseWithDebug". It might be misalignment and different sizes for data structures that could cause memory corruption at the end.

MichaelOrlov avatar Mar 28 '24 20:03 MichaelOrlov

  • Closing as fixed in the https://github.com/ros2/rosbag2/pull/1653

  • Note. We do have a unit test to make sure that rosbag2_cpp::Writer can be opened and closed multiple times https://github.com/ros2/rosbag2/blob/rolling/rosbag2_tests/test/rosbag2_tests/test_rosbag2_cpp_api.cpp#L44-L116

  • I also tried to replace Writer instantiation on the stack with allocation on the heap via unique pointer std::unique_ptr<rosbag2_cpp::Writer> writer = std::make_unique<rosbag2_cpp::Writer>(); as mentioned in issue description and call writer.reset() directly - all works fine there are no segfaults or any failures. Tested on the latest Humble.

MichaelOrlov avatar May 16 '24 23:05 MichaelOrlov