JetsonGPIO
JetsonGPIO copied to clipboard
Solved sporadic crash when setmode is called multiple times
I had the problem, that sometimes if I wanted to set an output the software crashed with the exception "Channel 26 is invalid". I tracked down the problem to the is_in() function in PythonFunctions.h. The moment the exception is thrown, the is_in() functions received an empty dictionary. I tested this by printing the size of the dictionary in the is_in() function.
I'm not sure why this happens. Because the _channel_data dictionary is only updated on startup and on every setmode(), I added a check to change the dictionary only once. This should not be a problem in my opinion, as you cannot update the mode once it has been set.
After the change, the problem no longer occurred. However, since it occurred only sporadically, I cannot say with 100% certainty that it is solved.
Thanks for the report.
Ok, for confirmation
- You got the exception when you called
setup
to set the channel 26 as an output. - The exception was thrown from: https://github.com/pjueon/JetsonGPIO/blob/d935854455e4a00496bfccce90caa29079daf855/src/MainModule.cpp#L79-L82
- When the exception thrown,
global()._channel_data
was empty
Is my understanding correct?
And
- Did you call
setmode
multiple times in your code? - Can you reproduce the issue if you revert your change?
- Are you using
setmode
orsetup
asynchronously in your code?
Your understanding is correct. The exception is only thrown when the setmode is called multiple times. The exception was never thrown on the first call.
Yes, the bug is reproducible, but sometimes takes longer to occur.
Are you using setmode or setup asynchronously in your code? I always call setmode before setup, but sometimes multiple times. So e.g., setmode, setup, setmode, setup.
Thanks for your help
Could you give us any short and simple code example that can reproduce this bug?
I tried this code but I didn't get any exception:
#include <iostream>
#include <JetsonGPIO.h>
int main()
{
constexpr int pin_num = 32;
constexpr int N = 30;
// no cleanup among iterations for check.
for(int i = 0; i < N; i++)
{
std::cout << "i: " << i << std::endl;
std::cout << "setmode start" << std::endl;
GPIO::setmode(GPIO::BOARD);
std::cout << "setmode end" << std::endl;
std::cout << "setup start" << std::endl;
GPIO::setup(pin_num, GPIO::OUT);
std::cout << "setup end" << std::endl;
}
std::cout << "done" << std::endl;
return 0;
}