Skip to content

Heap use after free when BehaviorTreeFactory is destroyed before ticking #1046

@nyibbang

Description

@nyibbang

Describe the bug

BehaviorTree.CPP version: 4.8.2
Compiler: g++ 14.2.0
OS: Ubuntu 24.04

There is a heap use after free happening when the BehaviorTreeFactory object that creates a tree is destroyed before the tree is ticked. The NodeConfig passed to the constructor of the nodes of the tree holds a pointer to a TreeNodeManifest owned by the factory that is, consequently, dangling.

It is usually not a problem until we try to access the manifest, for example when we use TreeNode::getInput with an input port that was not declared. This, in some cases, resulted in a segmentation fault in my code (I made a mistake in the name of the port).

How to Reproduce

Here is a code example that reproduces the issue:

#include <behaviortree_cpp/bt_factory.h>

constexpr const auto TREE_XML = R"(
 <root BTCPP_format="4">
     <BehaviorTree ID="Main">
        <Dummy/>
     </BehaviorTree>
 </root>
 )";

class Dummy : public BT::SyncActionNode {
public:
  Dummy(const std::string &name, const BT::NodeConfig &config)
      : BT::SyncActionNode(name, config) {}

  static BT::PortsList providedPorts() { return {}; }

  BT::NodeStatus tick() override {
    auto bad = getInput<std::string>("bad");
    return BT::NodeStatus::SUCCESS;
  }
};

BT::Tree make_tree() {
  BT::BehaviorTreeFactory factory;
  factory.registerNodeType<Dummy>("Dummy");
  factory.registerBehaviorTreeFromText(TREE_XML);
  return factory.createTree("Main");
}

int main(int argc, char *argv[]) {
  auto tree = make_tree();
  auto bb = tree.rootBlackboard();
  tree.tickWhileRunning();

  return 0;
}

Then compile this with a ASAN (add -fsanitize=address to the compiler command line arguments) and you get the following error:

=================================================================
==167564==ERROR: AddressSanitizer: heap-use-after-free on address 0x50f000002808 at pc 0x61dddcfa4317 bp 0x7fffb0b2ccc0 sp 0x7fffb0b2ccb0
READ of size 8 at 0x50f000002808 thread T0
    #0 0x61dddcfa4316 in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::size() const /usr/include/c++/14/bits/hashtable.h:657
    #1 0x61dddcfa2492 in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::find(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const /usr/include/c++/14/bits/hashtable.h:1751
    #2 0x61dddcf9ee10 in std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, BT::PortInfo, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo> > >::find(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const /usr/include/c++/14/bits/unordered_map.h:888
    #3 0x61dddcf98edd in std::expected<BT::Timestamp, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > BT::TreeNode::getInputStamped<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) const /usr/local/include/behaviortree_cpp/tree_node.h:471
    #4 0x61dddcf94932 in std::expected<std::monostate, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > BT::TreeNode::getInput<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) const /usr/local/include/behaviortree_cpp/tree_node.h:562
    #5 0x61dddcf9538f in std::expected<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > BT::TreeNode::getInput<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const /usr/local/include/behaviortree_cpp/tree_node.h:273
    #6 0x61dddcf914ef in Dummy::tick() /home/nyibbang/bt-test/main.cpp:19
    #7 0x7275693555ca in BT::TreeNode::executeTick() /home/nyibbang/BehaviorTree.CPP/src/tree_node.cpp:110
    #8 0x7275692de5ef in BT::SyncActionNode::executeTick() /home/nyibbang/BehaviorTree.CPP/src/action_node.cpp:58
    #9 0x72756930541d in BT::Tree::tickRoot(BT::Tree::TickOption, std::chrono::duration<long, std::ratio<1l, 1000l> >) /home/nyibbang/BehaviorTree.CPP/src/bt_factory.cpp:589
    #10 0x61dddcf8b326 in main /home/nyibbang/bt-test/main.cpp:34
    #11 0x727568a2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #12 0x727568a2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #13 0x61dddcf8ab24 in _start (/home/nyibbang/bt-test/out/Debug/bt-heap-use-after-free+0xeb24) (BuildId: 6636fde6ea32282cc2caaa13daf481924c3b501e)

0x50f000002808 is located 104 bytes inside of 168-byte region [0x50f0000027a0,0x50f000002848)
freed by thread T0 here:
    #0 0x7275698ff5e8 in operator delete(void*, unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:164
    #1 0x7275693177ac in std::__new_allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> >::deallocate(std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true>*, unsigned long) /usr/include/c++/14/bits/new_allocator.h:172
    #2 0x7275693177ac in std::allocator_traits<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> > >::deallocate(std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> >&, std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true>*, unsigned long) /usr/include/c++/14/bits/alloc_traits.h:513
    #3 0x7275693177ac in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> > >::_M_deallocate_node_ptr(std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true>*) /usr/include/c++/14/bits/hashtable_policy.h:2051
    #4 0x7275693177ac in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> > >::_M_deallocate_node(std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true>*) /usr/include/c++/14/bits/hashtable_policy.h:2041
    #5 0x7275693177ac in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> > >::_M_deallocate_nodes(std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true>*) /usr/include/c++/14/bits/hashtable_policy.h:2062
    #6 0x7275693177ac in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::clear() /usr/include/c++/14/bits/hashtable.h:2584
    #7 0x727569317b6c in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::~_Hashtable() /usr/include/c++/14/bits/hashtable.h:1667
    #8 0x727569317b6c in std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, BT::TreeNodeManifest, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> > >::~unordered_map() /usr/include/c++/14/bits/unordered_map.h:109
    #9 0x727569317b6c in BT::BehaviorTreeFactory::PImpl::~PImpl() /home/nyibbang/BehaviorTree.CPP/src/bt_factory.cpp:27
    #10 0x7275693057ac in std::default_delete<BT::BehaviorTreeFactory::PImpl>::operator()(BT::BehaviorTreeFactory::PImpl*) const /usr/include/c++/14/bits/unique_ptr.h:93
    #11 0x7275693057ac in std::default_delete<BT::BehaviorTreeFactory::PImpl>::operator()(BT::BehaviorTreeFactory::PImpl*) const /usr/include/c++/14/bits/unique_ptr.h:87
    #12 0x7275693057ac in std::unique_ptr<BT::BehaviorTreeFactory::PImpl, std::default_delete<BT::BehaviorTreeFactory::PImpl> >::~unique_ptr() /usr/include/c++/14/bits/unique_ptr.h:398
    #13 0x7275693057ac in BT::BehaviorTreeFactory::~BehaviorTreeFactory() /home/nyibbang/BehaviorTree.CPP/src/bt_factory.cpp:106
    #14 0x61dddcf8af7a in make_tree() /home/nyibbang/bt-test/main.cpp:29
    #15 0x61dddcf8b272 in main /home/nyibbang/bt-test/main.cpp:32
    #16 0x727568a2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #17 0x727568a2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #18 0x61dddcf8ab24 in _start (/home/nyibbang/bt-test/out/Debug/bt-heap-use-after-free+0xeb24) (BuildId: 6636fde6ea32282cc2caaa13daf481924c3b501e)

previously allocated by thread T0 here:
    #0 0x7275698fe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x727569308445 in std::__new_allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> >::allocate(unsigned long, void const*) /usr/include/c++/14/bits/new_allocator.h:151
    #2 0x727569308445 in std::allocator_traits<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> > >::allocate(std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> >&, unsigned long) /usr/include/c++/14/bits/alloc_traits.h:478
    #3 0x727569308445 in std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true>* std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> > >::_M_allocate_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>&&) /usr/include/c++/14/bits/hashtable_policy.h:2019
    #4 0x727569308445 in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_Scoped_node::_Scoped_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >(std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, true> > >*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>&&) /usr/include/c++/14/bits/hashtable.h:312
    #5 0x727569308445 in std::pair<std::__detail::_Node_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, false, true>, bool> std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_emplace<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >(std::integral_constant<bool, true>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>&&) /usr/include/c++/14/bits/hashtable.h:2143
    #6 0x727569308445 in std::pair<std::__detail::_Node_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, false, true>, bool> std::__detail::_Insert<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, false>::insert<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>, void>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>&&) /usr/include/c++/14/bits/hashtable_policy.h:1150
    #7 0x727569308445 in std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, BT::TreeNodeManifest, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest> > >::insert(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::TreeNodeManifest>&&) /usr/include/c++/14/bits/unordered_map.h:566
    #8 0x727569308445 in BT::BehaviorTreeFactory::registerBuilder(BT::TreeNodeManifest const&, std::function<std::unique_ptr<BT::TreeNode, std::default_delete<BT::TreeNode> > (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, BT::NodeConfig const&)> const&) /home/nyibbang/BehaviorTree.CPP/src/bt_factory.cpp:134
    #9 0x61dddcf9b233 in void BT::BehaviorTreeFactory::registerNodeType<Dummy>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, BT::PortInfo, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo> > > const&) /usr/local/include/behaviortree_cpp/bt_factory.h:359
    #10 0x61dddcf956c1 in void BT::BehaviorTreeFactory::registerNodeType<Dummy>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/local/include/behaviortree_cpp/bt_factory.h:395
    #11 0x61dddcf8ad37 in make_tree() /home/nyibbang/bt-test/main.cpp:26
    #12 0x61dddcf8b272 in main /home/nyibbang/bt-test/main.cpp:32
    #13 0x727568a2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #14 0x727568a2a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #15 0x61dddcf8ab24 in _start (/home/nyibbang/bt-test/out/Debug/bt-heap-use-after-free+0xeb24) (BuildId: 6636fde6ea32282cc2caaa13daf481924c3b501e)

SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/14/bits/hashtable.h:657 in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, BT::PortInfo> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::size() const
Shadow bytes around the buggy address:
  0x50f000002580: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x50f000002600: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa
  0x50f000002680: fa fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd
  0x50f000002700: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
  0x50f000002780: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
=>0x50f000002800: fd[fd]fd fd fd fd fd fd fd fa fa fa fa fa fa fa
  0x50f000002880: fa fa 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50f000002900: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x50f000002980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50f000002a00: 00 00 00 00 00 fa fa fa fa fa fa fa fa fa 00 00
  0x50f000002a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==167564==ABORTING

End note

I understand that there was a mistake in my code that caused me to access to an undeclared input port. But I think that it is dangerous that a node might use dangling pointers.

Either BehaviorTreeFactory is not supposed to be destroyed once the tree is constructed, and it should be stated in the documentation, and it should throw an exception on the first tick of the tree. or even better but difficult it should not compile. Or if this is allowed, there should be a mechanism to sanitize these manifests pointers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions