wpilibsuite / allwpilib

Official Repository of WPILibJ and WPILibC
https://wpilib.org/
Other
1.04k stars 604 forks source link

Race condition in SmartDashboard::putData #3182

Open virtuald opened 3 years ago

virtuald commented 3 years ago

Describe the bug segfault, appears to be a race condition with the SendableRegistry that doesn't guarantee that objects are still alive when they're accessed. Easy way to trigger is by quickly deleting the object after calling SmartDashboard::putData.

To Reproduce

import wpilib
import weakreft = wpilib.Talon(4)
ref = weakref.ref(t)
wpilib.SmartDashboard.putData("talon", t)
del t

Expected behavior No segfault.

Stack trace

Thread 2 "python" received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffe7f08640 (LWP 1331063)]
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
49        return ret;
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
#1  0x00007ffff7a9b8a4 in __GI_abort () at abort.c:79
#2  0x00007fffe9bd5926 in __gnu_cxx::__verbose_terminate_handler () at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#3  0x00007fffe9be11ac in __cxxabiv1::__terminate (handler=<optimized out>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:48
#4  0x00007fffe9be1217 in std::terminate () at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:58
#5  0x00007fffe9be14c9 in __cxxabiv1::__cxa_throw (obj=<optimized out>, tinfo=0x7fffe9d12370 <typeinfo for std::bad_function_call>, dest=0x7fffe9c0b080 <std::bad_function_call::~bad_function_call()>) at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:95
#6  0x00007fffe9bd85ca in std::__throw_bad_function_call () at ../../../../../libstdc++-v3/src/c++11/functional.cc:34
#7  0x00007fffe93975e4 in std::function<void (nt::EntryNotification const&)>::operator()(nt::EntryNotification const&) const (__args#0=..., this=0x7fffe7f07d90) at /usr/include/c++/7/bits/std_function.h:705
#8  nt::impl::EntryNotifierThread::DoCallback(std::function<void (nt::EntryNotification const&)>, nt::EntryNotification const&) (this=0x555555987bb0, data=..., callback=...) at /__w/allwpilib/allwpilib/ntcore/src/main/native/cpp/EntryNotifier.h:64
#9  nt::impl::CallbackThread<nt::impl::EntryNotifierThread, nt::EntryNotification, nt::impl::EntryListenerData, nt::EntryNotification>::Main (this=0x555555987bb0) at /__w/allwpilib/allwpilib/ntcore/src/main/native/cpp/CallbackManager.h:133
#10 0x00007fffe9c0d5f4 in std::execute_native_thread_routine (__p=0x555555987d20) at ../../../../../libstdc++-v3/src/c++11/thread.cc:80
#11 0x00007ffff7a5c3f9 in start_thread (arg=0x7fffe7f08640) at pthread_create.c:463
#12 0x00007ffff7b76903 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Ref: https://github.com/robotpy/robotpy-wpilib/issues/685

Starlight220 commented 6 months ago

Is there a way to check this in C++?

SendableHelper should unregister the object at dtor, so I'm not sure how this is happening. Can someone reproduce this with latest?

virtuald commented 6 months ago

You can just do the same thing in C++.