rosbag2
rosbag2 copied to clipboard
rosbag2_cpp::Writer can not close correctly, rasing "Segmentation fault(core dumped)" Error
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.
- Go to '...'
- Click on '....'
- Scroll down to '....'
- 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 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?
@M201871109 As a workaround I can suggest to try calling writer_->close()
before writer.reset()
@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
If you want to reproduce the issue, I extended the test_rosbag_cpp_api
here.
@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 As a workaround I can suggest to try calling
writer_->close()
beforewriter.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 can you provide a SSCCE for this?
@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.
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.
@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.
-
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 callwriter.reset()
directly - all works fine there are no segfaults or any failures. Tested on the latest Humble.