From ee833c2e669470294ee225e22c56a5556f4dceac Mon Sep 17 00:00:00 2001 From: HanielUlises Date: Tue, 29 Sep 2026 08:21:56 -0600 Subject: [PATCH 1/2] Leave the demo performers without static destruction --- eplansys_demo/src/corridor_actions.cpp | 5 ++- eplansys_demo/src/leave.hpp | 45 ++++++++++++++++++++++ eplansys_demo/src/survey_actions.cpp | 5 ++- eplansys_demo/src/survey_sites_actions.cpp | 5 ++- 4 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 eplansys_demo/src/leave.hpp diff --git a/eplansys_demo/src/corridor_actions.cpp b/eplansys_demo/src/corridor_actions.cpp index 5fcbd831..98ba0f4b 100644 --- a/eplansys_demo/src/corridor_actions.cpp +++ b/eplansys_demo/src/corridor_actions.cpp @@ -31,6 +31,8 @@ #include "rclcpp/rclcpp.hpp" +#include "leave.hpp" + namespace eplansys_demo { @@ -130,6 +132,5 @@ int main(int argc, char ** argv) } executor.spin(); - rclcpp::shutdown(); - return 0; + eplansys_demo::leave(0); } diff --git a/eplansys_demo/src/leave.hpp b/eplansys_demo/src/leave.hpp new file mode 100644 index 00000000..01827772 --- /dev/null +++ b/eplansys_demo/src/leave.hpp @@ -0,0 +1,45 @@ +// Copyright 2026 Intelligent Robotics Lab +// +// 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. + +#ifndef EPLANSYS_DEMO__LEAVE_HPP_ +#define EPLANSYS_DEMO__LEAVE_HPP_ + +#include + +#include + +#include "rclcpp/rclcpp.hpp" + +namespace eplansys_demo +{ + +/// End the process once its work is done, without static destruction. +/// +/// rclcpp::shutdown() does not finalise the global context; that happens in +/// static destruction, inside _dl_fini, while Fast DDS listener threads are +/// still running in libraries the loader is unmapping. A performer interrupted +/// by the launch file at the end of a mission segfaulted in about one run in +/// five that way, after every action had finished. plansys2_tests leaves +/// through _exit for the same reason. +[[noreturn]] inline void leave(int status) +{ + rclcpp::shutdown(); + std::fflush(stdout); + std::fflush(stderr); + _exit(status); +} + +} // namespace eplansys_demo + +#endif // EPLANSYS_DEMO__LEAVE_HPP_ diff --git a/eplansys_demo/src/survey_actions.cpp b/eplansys_demo/src/survey_actions.cpp index 83132c6a..e9636ef9 100644 --- a/eplansys_demo/src/survey_actions.cpp +++ b/eplansys_demo/src/survey_actions.cpp @@ -31,6 +31,8 @@ #include "rclcpp/rclcpp.hpp" +#include "leave.hpp" + namespace eplansys_demo { @@ -133,6 +135,5 @@ int main(int argc, char ** argv) } executor.spin(); - rclcpp::shutdown(); - return 0; + eplansys_demo::leave(0); } diff --git a/eplansys_demo/src/survey_sites_actions.cpp b/eplansys_demo/src/survey_sites_actions.cpp index c835db42..e113809e 100644 --- a/eplansys_demo/src/survey_sites_actions.cpp +++ b/eplansys_demo/src/survey_sites_actions.cpp @@ -31,6 +31,8 @@ #include "lifecycle_msgs/msg/transition.hpp" #include "rclcpp/rclcpp.hpp" +#include "leave.hpp" + namespace eplansys_demo { @@ -136,6 +138,5 @@ int main(int argc, char ** argv) } executor.spin(); - rclcpp::shutdown(); - return 0; + eplansys_demo::leave(0); } From b6b91b5200eacea9a037d4e819f06641b10ba11f Mon Sep 17 00:00:00 2001 From: HanielUlises Date: Tue, 29 Sep 2026 08:26:31 -0600 Subject: [PATCH 2/2] Say where the performer's exit fault is --- eplansys_demo/src/leave.hpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/eplansys_demo/src/leave.hpp b/eplansys_demo/src/leave.hpp index 01827772..07b4eb08 100644 --- a/eplansys_demo/src/leave.hpp +++ b/eplansys_demo/src/leave.hpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef EPLANSYS_DEMO__LEAVE_HPP_ -#define EPLANSYS_DEMO__LEAVE_HPP_ +#ifndef LEAVE_HPP_ +#define LEAVE_HPP_ #include @@ -24,14 +24,16 @@ namespace eplansys_demo { -/// End the process once its work is done, without static destruction. +/// End the process once its work is done, without destroying the performers. /// -/// rclcpp::shutdown() does not finalise the global context; that happens in -/// static destruction, inside _dl_fini, while Fast DDS listener threads are -/// still running in libraries the loader is unmapping. A performer interrupted -/// by the launch file at the end of a mission segfaulted in about one run in -/// five that way, after every action had finished. plansys2_tests leaves -/// through _exit for the same reason. +/// A performer interrupted by the launch file at the end of a mission +/// segfaulted in about one run in five, after every action had finished. The +/// fault is in the performer's destructor, run from main after +/// rclcpp::shutdown(), while CascadeLifecycleNode frees its activators_state_ +/// map through a pointer that is no longer valid; no thread of this process was +/// using the node by then. Nothing is left to do at that point, so the process +/// leaves through _exit and skips the teardown, as plansys2_tests does for its +/// own exit-time fault. [[noreturn]] inline void leave(int status) { rclcpp::shutdown(); @@ -42,4 +44,4 @@ namespace eplansys_demo } // namespace eplansys_demo -#endif // EPLANSYS_DEMO__LEAVE_HPP_ +#endif // LEAVE_HPP_