Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix task's move constructor #371

Merged
merged 4 commits into from
Jun 14, 2022

Conversation

JafarAbdi
Copy link
Member

@JafarAbdi JafarAbdi commented Jun 9, 2022

Fix moveit/moveit2_tutorials#426

Backtrace:

#1  0x00007ffff7e50972 in moveit::task_constructor::Property::typeName[abi:cxx11]() const () from /home/jafar/workspaces/ros/ws_moveit/devel/lib/libmoveit_task_constructor_core.so
#2  0x00007ffff7e3ca71 in moveit::task_constructor::Introspection::fillTaskDescription(moveit_task_constructor_msgs::TaskDescription_<std::allocator<void> >&)::{lambda(moveit::task_constructor::Stage const&, unsigned int)#1}::operator()(moveit::task_constructor::Stage const&, unsigned int) const [clone .isra.0] ()
   from /home/jafar/workspaces/ros/ws_moveit/devel/lib/libmoveit_task_constructor_core.so
#3  0x00007ffff7e17cad in moveit::task_constructor::ContainerBase::traverseRecursively(std::function<bool (moveit::task_constructor::Stage const&, unsigned int)> const&) const ()
   from /home/jafar/workspaces/ros/ws_moveit/devel/lib/libmoveit_task_constructor_core.so
#4  0x00007ffff7e3bce9 in moveit::task_constructor::Introspection::fillTaskDescription(moveit_task_constructor_msgs::TaskDescription_<std::allocator<void> >&) ()
   from /home/jafar/workspaces/ros/ws_moveit/devel/lib/libmoveit_task_constructor_core.so
#5  0x00007ffff7e3bf1e in moveit::task_constructor::Introspection::publishTaskDescription() () from /home/jafar/workspaces/ros/ws_moveit/devel/lib/libmoveit_task_constructor_core.so
#6  0x00007ffff7e6918a in moveit::task_constructor::Task::init() () from /home/jafar/workspaces/ros/ws_moveit/devel/lib/libmoveit_task_constructor_core.so
#7  0x000055555556541e in Task_taskMoveConstructor_Test::TestBody() ()
#8  0x00007ffff79fa151 in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
   from /home/jafar/workspaces/ros/ws_moveit/build/moveit_task_constructor_core/gtest/lib/libgtest.so
#9  0x00007ffff79ee2c6 in testing::Test::Run() () from /home/jafar/workspaces/ros/ws_moveit/build/moveit_task_constructor_core/gtest/lib/libgtest.so
#10 0x00007ffff79ee425 in testing::TestInfo::Run() () from /home/jafar/workspaces/ros/ws_moveit/build/moveit_task_constructor_core/gtest/lib/libgtest.so
#11 0x00007ffff79ee54d in testing::TestSuite::Run() () from /home/jafar/workspaces/ros/ws_moveit/build/moveit_task_constructor_core/gtest/lib/libgtest.so
#12 0x00007ffff79eeb03 in testing::internal::UnitTestImpl::RunAllTests() () from /home/jafar/workspaces/ros/ws_moveit/build/moveit_task_constructor_core/gtest/lib/libgtest.so
#13 0x00007ffff79eed68 in testing::UnitTest::Run() () from /home/jafar/workspaces/ros/ws_moveit/build/moveit_task_constructor_core/gtest/lib/libgtest.so
#14 0x0000555555560c00 in main ()

@JafarAbdi JafarAbdi force-pushed the pr-fix_task_move_constructor branch from a02070b to 06d5370 Compare June 9, 2022 18:49
@JafarAbdi
Copy link
Member Author

Running git bisect shows e67b325 being the culprit

@@ -77,7 +77,6 @@ TaskPrivate::TaskPrivate(Task* me, const std::string& ns)
TaskPrivate& TaskPrivate::operator=(TaskPrivate&& other) {
this->WrapperBasePrivate::operator=(std::move(other));
ns_ = std::move(other.ns_);
introspection_ = std::move(other.introspection_);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should reset other.introspection_?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving a unique_ptr like this should correctly reset other's introspection_ pointer.

@JafarAbdi
Copy link
Member Author

Thanks to the Address sanitizer, I was able to fix the bug, introspection hold a pointer to a PrivateTask so when we move the lhs the moved introspection will still point to the deleted task_ causing any call to introspection to access freed memory

=================================================================
==926838==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000001200 at pc 0x7f5af1404d1d bp 0x7ffd3ec14270 sp 0x7ffd3ec14260
READ of size 8 at 0x617000001200 thread T0
    #0 0x7f5af1404d1c in moveit::task_constructor::Introspection::fillTaskDescription(moveit_task_constructor_msgs::TaskDescription_<std::allocator<void> >&) /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/src/introspection.cpp:248
    #1 0x7f5af140633c in moveit::task_constructor::Introspection::publishTaskDescription() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/src/introspection.cpp:131
    #2 0x7f5af18070b9 in moveit::task_constructor::Task::init() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/src/task.cpp:222
    #3 0x55ebadc813fd in Task_taskMoveConstructor_Test::TestBody() (/home/jafar/workspaces/ros/ws_moveit/devel/.private/moveit_task_constructor_core/lib/moveit_task_constructor_core/moveit_task_constructor_core-test-move-to+0x113fd)
    #4 0x7f5aeec59b8e in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/src/googletest/googletest/src/gtest.cc:2433
    #5 0x7f5aeec59b8e in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/src/googletest/googletest/src/gtest.cc:2469
    #6 0x7f5aeeb82ec8 in testing::Test::Run() /usr/src/googletest/googletest/src/gtest.cc:2508
    #7 0x7f5aeeb82ec8 in testing::Test::Run() /usr/src/googletest/googletest/src/gtest.cc:2498
    #8 0x7f5aeeb83bf3 in testing::TestInfo::Run() /usr/src/googletest/googletest/src/gtest.cc:2684
    #9 0x7f5aeeb83bf3 in testing::TestInfo::Run() /usr/src/googletest/googletest/src/gtest.cc:2657
    #10 0x7f5aeeb849e8 in testing::TestSuite::Run() /usr/src/googletest/googletest/src/gtest.cc:2816
    #11 0x7f5aeeb88366 in testing::internal::UnitTestImpl::RunAllTests() /usr/src/googletest/googletest/src/gtest.cc:5338
    #12 0x7f5aeec5c97e in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/src/googletest/googletest/src/gtest.cc:2433
    #13 0x7f5aeec5c97e in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/src/googletest/googletest/src/gtest.cc:2469
    #14 0x7f5aeeb8aa01 in testing::UnitTest::Run() /usr/src/googletest/googletest/src/gtest.cc:4925
    #15 0x55ebadc7cbcf in main (/home/jafar/workspaces/ros/ws_moveit/devel/.private/moveit_task_constructor_core/lib/moveit_task_constructor_core/moveit_task_constructor_core-test-move-to+0xcbcf)
    #16 0x7f5aee1270b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #17 0x55ebadc7d63d in _start (/home/jafar/workspaces/ros/ws_moveit/devel/.private/moveit_task_constructor_core/lib/moveit_task_constructor_core/moveit_task_constructor_core-test-move-to+0xd63d)

0x617000001200 is located 0 bytes inside of 656-byte region [0x617000001200,0x617000001490)
freed by thread T0 here:
    #0 0x7f5af7f1e025 in operator delete(void*, unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x111025)
    #1 0x7f5af18923f6 in moveit::task_constructor::TaskPrivate::~TaskPrivate() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/include/moveit/task_constructor/task_p.h:51
    #2 0x7f5af15fd284 in moveit::task_constructor::Stage::~Stage() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/src/stage.cpp:318
    #3 0x7f5af1802240 in moveit::task_constructor::ContainerBase::~ContainerBase() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/include/moveit/task_constructor/container.h:48
    #4 0x7f5af1802240 in moveit::task_constructor::ParallelContainerBase::~ParallelContainerBase() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/include/moveit/task_constructor/container.h:113
    #5 0x7f5af1802240 in moveit::task_constructor::WrapperBase::~WrapperBase() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/include/moveit/task_constructor/container.h:207
    #6 0x7f5af1802240 in moveit::task_constructor::Task::~Task() /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/src/task.cpp:113
    #7 0x55ebadc813f5 in Task_taskMoveConstructor_Test::TestBody() (/home/jafar/workspaces/ros/ws_moveit/devel/.private/moveit_task_constructor_core/lib/moveit_task_constructor_core/moveit_task_constructor_core-test-move-to+0x113f5)
    #8 0x7ffd3ec14887  ([stack]+0x1e887)

previously allocated by thread T0 here:
    #0 0x7f5af7f1c947 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10f947)
    #1 0x7f5af180bbe3 in moveit::task_constructor::Task::Task(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, std::unique_ptr<moveit::task_constructor::ContainerBase, std::default_delete<moveit::task_constructor::ContainerBase> >&&) /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/src/task.cpp:92
    #2 0x55ebadc81013 in Task_taskMoveConstructor_Test::TestBody() (/home/jafar/workspaces/ros/ws_moveit/devel/.private/moveit_task_constructor_core/lib/moveit_task_constructor_core/moveit_task_constructor_core-test-move-to+0x11013)
    #3 0x61900001457f  (<unknown module>)

SUMMARY: AddressSanitizer: heap-use-after-free /home/jafar/workspaces/ros/ws_moveit/src/moveit_task_constructor/core/src/introspection.cpp:248 in moveit::task_constructor::Introspection::fillTaskDescription(moveit_task_constructor_msgs::TaskDescription_<std::allocator<void> >&)
Shadow bytes around the buggy address:
  0x0c2e7fff81f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8200: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8210: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8220: fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2e7fff8230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c2e7fff8240:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8250: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8260: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8270: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8280: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff8290: fd fd fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
  Shadow gap:              cc
==926838==ABORTING

@JafarAbdi JafarAbdi changed the title [WIP]: Fix task's move constructor Fix task's move constructor Jun 9, 2022
@codecov
Copy link

codecov bot commented Jun 9, 2022

Codecov Report

Merging #371 (ed09dea) into master (60229db) will increase coverage by 0.06%.
The diff coverage is n/a.

❗ Current head ed09dea differs from pull request most recent head 194a4df. Consider uploading reports for the commit 194a4df to get more accurate results

@@            Coverage Diff             @@
##           master     #371      +/-   ##
==========================================
+ Coverage   54.55%   54.61%   +0.06%     
==========================================
  Files         102      102              
  Lines        7852     7851       -1     
==========================================
+ Hits         4283     4287       +4     
+ Misses       3569     3564       -5     
Impacted Files Coverage Δ
core/src/task.cpp 79.10% <ø> (+0.45%) ⬆️
core/src/introspection.cpp 77.45% <0.00%> (+3.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 60229db...194a4df. Read the comment docs.

Copy link
Contributor

@rhaschke rhaschke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my point of view, the issue is not related to the introspection pointer, but to the list of children not correctly moved. This definitely needs deeper inspection, but I need to finish for today.

@@ -77,7 +77,6 @@ TaskPrivate::TaskPrivate(Task* me, const std::string& ns)
TaskPrivate& TaskPrivate::operator=(TaskPrivate&& other) {
this->WrapperBasePrivate::operator=(std::move(other));
ns_ = std::move(other.ns_);
introspection_ = std::move(other.introspection_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving a unique_ptr like this should correctly reset other's introspection_ pointer.

Copy link
Contributor

@rhaschke rhaschke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @JafarAbdi, for tracking this down. Your solution to keep the existing introspection instance was correct in principle. However, if the other task doesn't have introspection enable, we should disable it in the new instance too and vice versa. I added a corresponding fixup.

@rhaschke rhaschke merged commit e923fbc into moveit:master Jun 14, 2022
JafarAbdi added a commit to JafarAbdi/moveit_task_constructor that referenced this pull request Jun 15, 2022
* Add unit test
* Fix TaskPrivate's move assignment operator
* Slightly simplify code

Co-authored-by: Robert Haschke <[email protected]>
@JafarAbdi JafarAbdi deleted the pr-fix_task_move_constructor branch June 15, 2022 13:50
JafarAbdi added a commit to JafarAbdi/moveit_task_constructor that referenced this pull request Jun 15, 2022
* Add unit test
* Fix TaskPrivate's move assignment operator
* Slightly simplify code

Co-authored-by: Robert Haschke <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants