|
Re: C++ Crash On Load (Task related)
Team 1967 has had trouble with this fatal kernel task-level exception as well. We traced the error back to the LiveWindow SetEnabled() function. To flush out the problem, we put "printf"s to bracket the problem and looked at NetConsole to see how far the code "got" before it crashed. We also used "if" statements to check if pointers in both SetEnabled and InitializeLiveWindowComponents (which is called by SetEnabled) were null (such as: m_scheduler, m_liveWindowTable, table). Then, we checked to make sure it->first was non null, too. This led us to errors down in the PWM and Solenoid .cpp files. In the function StartLiveWindowMode for both the PWM and the Solenoid classes, we created an "if" statement to check if m_table was not null so that we would know that it wasn't using a null pointer. If it wasn't null, we let it call AddTableListener. In InitTable, we also put in an "if" statement that would print out that subTable was null if it really was null. The program STILL CRASHED. To debug this further, we went into a debug session (with our own JankyActuator task created as an object). It crashed in PWM's StopLiveWindowMode. The exception was that pointer m_table was 0xEEEEEEEE. The pointer m_table was never set to null in the constructor. So, we initialized m_table in both PWM's and Solenoid's constructors. The program still ended up crashing but we got "printf"s on NetConsole that m_table was now null - AHA! This caused us to see that in StartLiveWindowMode we got a failure because m_table was not checked before using it and Solenoid and PWM and other LiveWindow based classes all use this. We haven't completely fixed this problem but the lack of initializing m_table and using pointers without checking them is a big part of the problem.
Our work around of the problem is that we create pointer-based objects instead of objects proper in the class (i.e. use Victor * pV and new this object in RobotInit vs. the problematic way of Victor V(5) which gets instantiated too early and trips this problem more frequently). Also, we noted that m_scheduler is not checked in SetEnable() but is used. And it was unclear how the functionality of Initialized Components happens if a component is added after SetEnabled is called for the first time. This is due to the fact that InitializeLiveWindowComponents() is only called once and only the first time SetEnable() is called in LiveWindow. This means late-comers to LiveWindow will not get the same treatment as objects which are added prior to the first SetEnable() call.
Lastly - when adding the WPILib sources into our project as per the Screensteps documentation, we ran into troubles getting WPILib to compile. This is due to the fact that the .cpp -> .o build rule had a 'shell' command that called out to 'subversion' in order to get the subversion version and put it into a -D define variable. If you don't have subversion, this FAILS and the command fails, but the library winds up being created but it is empty. This caused a lot of delay until we changed the -D shell-out to a fixed value to get it to work.
Thanks,
Holly
|