mirror of
https://github.com/orbbec/OrbbecSDK_ROS2.git
synced 2026-10-12 07:19:50 +08:00
Merge branch 'fix/ethernet-graceful-shutdown' into v2/develop
This commit is contained in:
@@ -27,6 +27,13 @@
|
|||||||
#include <ament_index_cpp/get_package_share_directory.hpp>
|
#include <ament_index_cpp/get_package_share_directory.hpp>
|
||||||
#endif
|
#endif
|
||||||
#include <rclcpp_components/register_node_macro.hpp>
|
#include <rclcpp_components/register_node_macro.hpp>
|
||||||
|
#if __has_include(<rclcpp/version.h>)
|
||||||
|
#include <rclcpp/version.h>
|
||||||
|
#define ORBBEC_RCLCPP_HANDLES_SIGTERM \
|
||||||
|
((RCLCPP_VERSION_MAJOR > 13) || (RCLCPP_VERSION_MAJOR == 13 && RCLCPP_VERSION_MINOR >= 1))
|
||||||
|
#else
|
||||||
|
#define ORBBEC_RCLCPP_HANDLES_SIGTERM 0
|
||||||
|
#endif
|
||||||
#include <rcutils/logging.h>
|
#include <rcutils/logging.h>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@@ -94,65 +101,56 @@ std::string makeDefaultSdkLogFileName() {
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void signalHandler(int sig) {
|
void crashSignalHandler(int sig) {
|
||||||
// Prevent recursive signal handling
|
// Prevent recursive crash signal handling.
|
||||||
static std::atomic<bool> in_signal_handler{false};
|
static std::atomic<bool> in_signal_handler{false};
|
||||||
if (in_signal_handler.exchange(true)) {
|
if (in_signal_handler.exchange(true)) {
|
||||||
// Already in signal handler, force exit immediately
|
|
||||||
_exit(sig);
|
_exit(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "Received signal: " << sig << std::endl;
|
std::cerr << "Received signal: " << sig << std::endl;
|
||||||
if (sig == SIGINT || sig == SIGTERM) {
|
std::filesystem::path log_dir = getLogDirectoryForCamera(g_camera_name);
|
||||||
static int signal_count = 0;
|
|
||||||
signal_count++;
|
|
||||||
|
|
||||||
if (signal_count <= 3) {
|
// get current time
|
||||||
rclcpp::shutdown();
|
std::time_t now = std::time(nullptr);
|
||||||
// Give some time for graceful shutdown
|
std::tm *local_time = std::localtime(&now);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
||||||
} else if (signal_count >= 5) {
|
|
||||||
// Force exit after second signal
|
|
||||||
std::cout << "Force exit due to multiple signals" << std::endl;
|
|
||||||
_exit(sig);
|
|
||||||
}
|
|
||||||
in_signal_handler.store(false);
|
|
||||||
} else {
|
|
||||||
std::filesystem::path log_dir = getLogDirectoryForCamera(g_camera_name);
|
|
||||||
|
|
||||||
// get current time
|
// format date and time, format "2024_05_20_12_34_56"
|
||||||
std::time_t now = std::time(nullptr);
|
std::ostringstream time_stream;
|
||||||
std::tm *local_time = std::localtime(&now);
|
time_stream << std::put_time(local_time, "%Y_%m_%d_%H_%M_%S");
|
||||||
|
|
||||||
// format date and time to string, format as "2024_05_20_12_34_56"
|
// generate log file name
|
||||||
std::ostringstream time_stream;
|
std::string log_file_name = g_camera_name + "_crash_stack_trace_" + time_stream.str() + ".log";
|
||||||
time_stream << std::put_time(local_time, "%Y_%m_%d_%H_%M_%S");
|
std::filesystem::path log_file_path = log_dir / log_file_name;
|
||||||
|
|
||||||
// generate log file name
|
if (!std::filesystem::exists(log_dir)) {
|
||||||
std::string log_file_name = g_camera_name + "_crash_stack_trace_" + time_stream.str() + ".log";
|
std::filesystem::create_directories(log_dir);
|
||||||
std::filesystem::path log_file_path = log_dir / log_file_name;
|
|
||||||
|
|
||||||
if (!std::filesystem::exists(log_dir)) {
|
|
||||||
std::filesystem::create_directories(log_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << "Log crash stack trace to " << log_file_path.string() << std::endl;
|
|
||||||
std::ofstream log_file(log_file_path, std::ios::app);
|
|
||||||
|
|
||||||
if (log_file.is_open()) {
|
|
||||||
log_file << "Received signal: " << sig << std::endl;
|
|
||||||
|
|
||||||
backward::StackTrace st;
|
|
||||||
st.load_here(32); // Capture stack
|
|
||||||
backward::Printer p;
|
|
||||||
p.print(st, log_file); // Print stack to log file
|
|
||||||
}
|
|
||||||
|
|
||||||
log_file.close();
|
|
||||||
_exit(sig); // Use _exit instead of exit to avoid cleanup that may crash
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cerr << "Log crash stack trace to " << log_file_path.string() << std::endl;
|
||||||
|
std::ofstream log_file(log_file_path, std::ios::app);
|
||||||
|
|
||||||
|
if (log_file.is_open()) {
|
||||||
|
log_file << "Received signal: " << sig << std::endl;
|
||||||
|
|
||||||
|
backward::StackTrace st;
|
||||||
|
st.load_here(32); // Capture stack
|
||||||
|
backward::Printer p;
|
||||||
|
p.print(st, log_file); // Print stack to log file
|
||||||
|
}
|
||||||
|
|
||||||
|
log_file.close();
|
||||||
|
_exit(sig); // Use _exit instead of exit to avoid cleanup that may crash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ORBBEC_RCLCPP_HANDLES_SIGTERM
|
||||||
|
void forwardSigtermToRclcpp(int) {
|
||||||
|
// Older rclcpp versions such as Foxy's only handle SIGINT. Forward SIGTERM to that signal-safe
|
||||||
|
// shutdown path instead of calling rclcpp::shutdown() directly from this signal handler.
|
||||||
|
kill(getpid(), SIGINT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace orbbec_camera {
|
namespace orbbec_camera {
|
||||||
backward::SignalHandling OBCameraNodeDriver::sh;
|
backward::SignalHandling OBCameraNodeDriver::sh;
|
||||||
|
|
||||||
@@ -278,13 +276,18 @@ OBCameraNodeDriver::~OBCameraNodeDriver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OBCameraNodeDriver::init() {
|
void OBCameraNodeDriver::init() {
|
||||||
// Set signal handlers for crash reporting
|
// Keep shutdown signals managed by rclcpp. Overriding them from a composable node bypasses its
|
||||||
signal(SIGSEGV, signalHandler); // segment fault
|
// deferred signal handling and can leave SDK streaming threads running after the ROS context has
|
||||||
signal(SIGABRT, signalHandler); // abort
|
// already been shut down.
|
||||||
signal(SIGFPE, signalHandler); // float point exception
|
#if !ORBBEC_RCLCPP_HANDLES_SIGTERM
|
||||||
signal(SIGILL, signalHandler); // illegal instruction
|
// Older rclcpp versions such as Foxy's predate native SIGTERM handling, so translate it to the
|
||||||
signal(SIGINT, signalHandler);
|
// SIGINT path that rclcpp does manage. Newer distributions handle both signals themselves.
|
||||||
signal(SIGTERM, signalHandler);
|
signal(SIGTERM, forwardSigtermToRclcpp);
|
||||||
|
#endif
|
||||||
|
signal(SIGSEGV, crashSignalHandler); // segment fault
|
||||||
|
signal(SIGABRT, crashSignalHandler); // abort
|
||||||
|
signal(SIGFPE, crashSignalHandler); // float point exception
|
||||||
|
signal(SIGILL, crashSignalHandler); // illegal instruction
|
||||||
ob::Context::setExtensionsDirectory(extension_path_.c_str());
|
ob::Context::setExtensionsDirectory(extension_path_.c_str());
|
||||||
g_camera_name = declare_parameter<std::string>("camera_name", g_camera_name);
|
g_camera_name = declare_parameter<std::string>("camera_name", g_camera_name);
|
||||||
auto log_level_str = declare_parameter<std::string>("log_level", "info");
|
auto log_level_str = declare_parameter<std::string>("log_level", "info");
|
||||||
|
|||||||
Reference in New Issue
Block a user