We frequently test our robot code on a RoboRIO that is not plugged into the rest of the robot, which means that some or all of our normal motor controllers will be absent from the CAN bus.
We expect CAN errors in our logs, and this is fine as we’re only testing certain subsystems. But what actually happens is sometimes our robot code crashes when accessing a CANEncoder for a missing motor controller (probably inside JNI).
I ran a simple test with the following sample code, which was enough to reproduce the problem:
package frc.robot;
import com.revrobotics.CANEncoder;
import com.revrobotics.CANSparkMax;
import com.revrobotics.CANSparkMaxLowLevel.MotorType;
import edu.wpi.first.wpilibj.TimedRobot;
public class Robot extends TimedRobot {
// Note a device with id 1 is not present on the CAN network
CANSparkMax spark = new CANSparkMax(1, MotorType.kBrushless);
CANEncoder encoder = spark.getEncoder();
@Override
public void robotPeriodic() {
for (int i = 0; i < 5; i++) {
encoder.getVelocity();
}
}
}
An example error looks like this:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x4143202c, pid=7939, tid=7976
#
# JRE version: OpenJDK Runtime Environment (11.0.4.10) (build 11.0.4.10-frc+0-2020-11.0.4u10-2)
# Java VM: OpenJDK Client VM (11.0.4.10-frc+0-2020-11.0.4u10-2, mixed mode, concurrent mark sweep gc, linux-)
# Problematic frame:
# C 0x4143202c
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /tmp/hs_err_pid7939.log
Here’s the referenced error log: hs_err_pid7939.log.txt (39.2 KB)
Is there any way to make this a warning instead of a hard crash? I suspect it’s just a bug in the JNI bridge (look like a null pointer dereference).
This topic seems to be related, however they discuss an allocation issue, whereas I’m able to reproduce this problem with only a single .getEncoder()
call at the beginning of the program: