wpilibsuite / allwpilib

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

SendableChooser crashes on reinitialization of Robot #2818

Closed calcmogul closed 3 years ago

calcmogul commented 3 years ago

I encountered this bug when trying to obtain a list of autonomous mode names to run in the instantiation macro of a TEST_P(), but this bug would occur in any test suite that instantiates the robot more than once (say, making a new robot in each TEST() block). The following minimal example reproduces the bug with version 2020.3.2-286-g7ae8c7b.

#include <frc/TimedRobot.h>
#include <frc/smartdashboard/SendableChooser.h>
#include <frc/smartdashboard/SmartDashboard.h>

class Robot : public frc::TimedRobot {
public:
    Robot() {
        std::cout << "ctor" << std::endl;
        m_chooser.SetDefaultOption("No-op", 0);
        frc::SmartDashboard::PutData("Autonomous modes", &m_chooser);
        std::cout << "ctor end" << std::endl;
    }

    ~Robot() { std::cout << "dtor" << std::endl; }

private:
    frc::SendableChooser<int> m_chooser;
};

#ifndef RUNNING_FRC_TESTS
int main() {
    frc::RunHALInitialization();
    {
        // ctor and dtor run fine
        Robot robot;
    }
    {
        // crashes in ctor in SmartDashboard::PutData()
        Robot robot;
    }
    return frc::StartRobot<Robot>();
}
#endif

Here's the gdb backtrace:

Starting program: /home/tav/git/frc3512/Robot-2020/build/install/frcUserProgram/linuxx86-64/debug/lib/frcUserProgram 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
HAL Extensions: No extensions found

********** Robot program starting **********
[New Thread 0x7ffff0f61640 (LWP 90062)]
Not loading CameraServerShared
[New Thread 0x7ffff0760640 (LWP 90063)]
[New Thread 0x7fffeff5f640 (LWP 90064)]
[New Thread 0x7fffef75e640 (LWP 90065)]
ctor
[New Thread 0x7fffeef5d640 (LWP 90066)]
ctor end
dtor
Not loading CameraServerShared
ctor

Thread 1 "frcUserProgram" received signal SIGSEGV, Segmentation fault.
0x00007ffff7c014af in frc::SendableRegistry::GetSendable (
    this=0x7ffff7fc7620 <frc::SendableRegistry::GetInstance()::instance>, uid=1)
    at /__w/allwpilib/allwpilib/wpilibc/src/main/native/cpp/smartdashboard/SendableRegistry.cpp:301
301 /__w/allwpilib/allwpilib/wpilibc/src/main/native/cpp/smartdashboard/SendableRegistry.cpp: No such file or directory.
(gdb) bt
#0  0x00007ffff7c014af in frc::SendableRegistry::GetSendable (
    this=0x7ffff7fc7620 <frc::SendableRegistry::GetInstance()::instance>, uid=1)
    at /__w/allwpilib/allwpilib/wpilibc/src/main/native/cpp/smartdashboard/SendableRegistry.cpp:301
#1  0x00007ffff7bac308 in frc::SmartDashboard::PutData (key=..., data=
    0x7fffffffe020)
    at /__w/allwpilib/allwpilib/wpilibc/src/main/native/cpp/smartdashboard/SmartDashboard.cpp:97
#2  0x000055555556b374 in Robot::Robot() ()
#3  0x000055555556a5e4 in main ()
calcmogul commented 3 years ago

Well, I know why I think... but will need to confirm. SmartDashboard.PutData() is given the pointer to the templated class, but the remove in the destructor removes the pointer to the non template base class.

We might need to not use the helper class in this case, or pull in the helper at the template class level instead of the base class. Really any derived classes from the helper class need to be final, or we need to change the helper class to not be CRTP.

-- Peter