Compiler bug (cc 5.61) with large structures
André Timmermans (100) 655 posts |
While testing KinoAmp on the PI 3, I noticed a bug due to the compiler in the player_reset() function. This function just resets to zero some fields at the beginning and at the end of the structure. MOV R1,#0 STR R1,[R0,#AAA] STR R1,[R0,#BBB] ... ADD R0,R0,#&00010000 ADD R0,R0,#CCC STR R1,[R0,#CCC] ADD R0,R0,#&00010000 ADD R0,R0,#DDD STR R1,[R0,#DDD] ... As you can the compiler completely get it completely wrong when attempting to write to the end of the structure. Time for me to buy a more recent version of the DDE to use it on the PI 3 (once the zero pain bugs are fixed). Anyway, it’s not the only bug to fix, so a new version of KinoAmp is coming soon. |
Jeffrey Lee (213) 6048 posts |
I have a feeling your post was meant to include some sample C code somewhere! |
André Timmermans (100) 655 posts |
Indeed, minimal source code:
Output of cc 5.61:
|
David Pitt (102) 743 posts |
; generated by Norcroft RISC OS ARM C vsn 5.71 [25 Aug 2014] AREA |C$$code|, CODE, READONLY |x$codeseg| DATA test MOV a2,#0 STR a2,[a1] STR a2,[a1,#4] ADD a3,a1,#&10000 STR a2,[a3,#&108] STR a2,[a3,#&10c]! MOV pc,lr AREA |C$$data|,DATA |x$dataseg| EXPORT test END <pre> |
Jeffrey Lee (213) 6048 posts |
Beat me to it! However seeing the code has reminded me of this bug – I wonder if it’s another instance of the same thing? https://www.riscosopen.org/tracker/tickets/258 (You should really get a new version of the compiler, André!) |
Dave Higton (1515) 3497 posts |
I think I’m seeing a bug in version 5.69. I have code that has a global variable called icstate, which is initialised to -1. When a USB device is plugged in and recognised, it is set to 0. Code that runs under callbacks should then take it through a range of values – but the callback code only ever sees the value as -1. Yes, I’m certain that it is only a global. |
Rick Murray (539) 13806 posts |
A regular global or a volatile global? |
Dave Higton (1515) 3497 posts |
Regular. |
Dave Higton (1515) 3497 posts |
Declaring it as volatile everywhere hasn’t changed the behaviour, either. |
Rick Murray (539) 13806 posts |
The next thing I’d try is to set the variable to a known fixed value (0xDEADBABE for instance) and see how far that persists. If the callback handler sets dead babe, then the main code should have that value once the callback handler exists, and when the callback handler is re-entered, it should pick up the dead babe value. BTW – when you say callback; are we talking an event handler of some sort, or a regular scheduled callback? RISC OS is quite finicky about what can happen in event/servicecall handlers and callevery/callafter code. That said, you mentioned USB device insertion. If you’re responding to ServiceCall USB_CONNECTED, you must either parse in the service call handler or copy the data to deal with in your callback code, because the data will not persist. I ran into this with my MIDI module, so the ServiceCall handler directly calls usb_parsedevice which will register a connected MIDI device; however it is written carefully to do as little controversial as possible at that point… |
Dave Higton (1515) 3497 posts |
There is a CallEvery handler (20cs) which merely schedules a callback. The callback handler is executed, but only sees the variable at its initial value. The callback handler should run a state machine, but the machine never moves from its initial quiescent value. The service call USB_CONNECTED is executed, and sets the variable to the first non-quiescent state value. Logging shows what’s happening – and what’s not happening – but not why. I’m conscious that I’ve hijacked this thread, so I’ll start another one when I’ve tried setting the value in the callback handler to see if it’s reflected elsewhere. |