Page 1 of 1
Why does this crash?
Posted: 21 Jul 2011, 18:42
by savedcoder
Hi, I'm having a problem with a NXC program I'm writing. Here's the code:
Code: Select all
task main()
{
char BOXNO = 0;
int b;
short a1, a2, a3, a4, a5, a6, a7, a8;
char joyvals[60];
while (1)
{
ReceiveMessage(BOXNO, true, joyvals);
b = (joyvals[0] << 24 | joyvals[1] << 16 | joyvals[2] << 8 | joyvals[3]) - 1;
a1 = (joyvals[4] << 8 | joyvals[5]);
a2 = (joyvals[6] << 8 | joyvals[7]);
a3 = (joyvals[8] << 8 | joyvals[9]);
a4 = (joyvals[10] << 8 | joyvals[11]);
a5 = (joyvals[12] << 8 | joyvals[13]);
a6 = (joyvals[14] << 8 | joyvals[15]);
a7 = (joyvals[16] << 8 | joyvals[17]);
a8 = (joyvals[18] << 8 | joyvals[19]);
}
}
For some reason, this crashes with "File Error!" The enhanced firmware adds "-1". If I comment out the
b = through
a8 = lines, it works fine.
The code is to receive (from the computer) the button values and axis info for a joystick. Any ideas why it fails?
-SavedCoder
Re: Why does this crash?
Posted: 21 Jul 2011, 19:47
by linusa
savedcoder wrote:
For some reason, this crashes with "File Error!" The enhanced firmware adds "-1". If I comment out the
b = through
a8 = lines, it works fine.
The code is to receive (from the computer) the button values and axis info for a joystick. Any ideas why it fails?
Well, you've said it yourself, so I'm stating the obvious: Have you checked if joyvals has the correct format? What happens if an empty or a malformed message arrives? Also check if you really can receive bluetooth messages to a char-array this way (or if you have to use a string).
You could start by displaying the the joyvals array on the scree, i.e. displaying i and joyvals
for i = 0 to 19, one by one with a little wait between. Then you can see WHERE your program crashes. Continue with this careful debugging and think about what bad things could happen (no message sent from computer, no message received, message received too late), etc. Then add some proper error handling.
Re: Why does this crash?
Posted: 21 Jul 2011, 20:18
by savedcoder
linusa wrote:Well, you've said it yourself, so I'm stating the obvious: Have you checked if joyvals has the correct format? What happens if an empty or a malformed message arrives?
Empty / malformed messages shouldn't make a difference, since the program only does some math on the array and stores the result. It's not like it makes decisions based on the values.
linusa wrote:You could start by displaying the the joyvals array on the scree, i.e. displaying i and joyvals for i = 0 to 19, one by one with a little wait between. Then you can see WHERE your program crashes.
I don't see how accessing a simple char-array could crash the program.
linusa wrote:Also check if you really can receive bluetooth messages to a char-array this way (or if you have to use a string).
The documentation just says "buffer". A char-array is about the simplest buffer.
Re: Why does this crash?
Posted: 21 Jul 2011, 21:41
by afanofosc
The documentation says this:
http://bricxcc.sourceforge.net/nbc/nxcd ... de5a08539e
You should definitely check the return value for possible error codes. The docs do not mention all the possible values but anything other than NO_ERR (0) means you do not have a valid message. The code replaces whatever you had in joyvals with whatever it read from the mailbox so if it read nothing from the mailbox then joyvals will have no bytes (other than the terminating null) in it (not 60).
The firmware code looks like this:
Code: Select all
//If there is a valid message in local mailbox, read it
if (!IS_ERR(Status) && MessageSize > 0 )
{
//!!! Also check for EMPTY_MAILBOX status?
//Size destination string
AllocStatus = cCmdDVArrayAlloc(DestDVIndex, MessageSize);
if (IS_ERR(AllocStatus))
return AllocStatus;
//Get Message
//!!! Should more aggressively enforce null termination before blindly copying to dataspace
Status = cCmdMessageRead(QueueID, cCmdDVPtr(DestDVIndex), MessageSize, *(ArgV[2]));
}
else
{
//Clear destination string
AllocStatus = cCmdDVArrayAlloc(DestDVIndex, 1);
if (IS_ERR(AllocStatus))
return AllocStatus;
//Successful allocation, make sure first byte is null terminator
*(UBYTE*)(cCmdDVPtr(DestDVIndex)) = '\0';
}
As you can see if there are no bytes to read (MessageSize == 0) it allocates 1 byte for the destination string and sets that byte to null. So if ReceiveMessage returns something other than NO_ERR then joyvals will be an empty string (joyvals[0] == 0 and any index > 0 will result in File Error -1 abort).
John Hansen
Re: Why does this crash?
Posted: 21 Jul 2011, 21:50
by savedcoder
Oh...
Thanks.
The documentation I looked at was the NXC guide that came with BricxCC.