View previous topic :: View next topic |
Author |
Message |
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
sprintf bug? |
Posted: Mon Jun 04, 2018 8:17 am |
|
|
compiler: 5.074
chip: 18F67K40
I have a strange bug in some rather complicated code.
I've narrowed it down and can make/break it by changing an sprintf() statement.
I have a uint32 variable that I am writing to a buffer, and if I use the %ld format it works fine, even though it's unsigned. If I use the %lu format it seems to somehow avoid executing some code.
Can anyone make sense of why the compiler would use a BRA instruction instead of a CALL in the .lst output?
I know I'm probably a rev or two behind. I've requested a maintenance update, but sometimes that takes a while.
here is the %lu version:
.................... //** reload Tx buffer
.................... // note: using %lu for 2nd parm caused Vout not to work - don't know why
.................... // sprintf(TxBuffer+1," %8ld %8ld\r\n",(signed int32)FdcResultCh0 - llZeroOffset,(signed int32)FdcResultCh0);
.................... sprintf(TxBuffer+1," %10lu\r\n",FdcResultCh0);
0EBE8: MOVLB 2
0EBEA: CLRF xFA
0EBEC: MOVLW 53
0EBEE: MOVWF xF9
0EBF0: MOVLW 20
0EBF2: MOVLB 3
0EBF4: MOVWF x40
0EBF6: MOVLB 0
0EBF8: CALL BEAA
0EBFC: MOVLW 20
0EBFE: MOVLB 3
0EC00: MOVWF x40
0EC02: MOVLB 0
0EC04: CALL BEAA
0EC08: MOVLW 4A
0EC0A: MOVWF FE9
0EC0C: MOVFF 28,30E
0EC10: MOVFF 27,30D
0EC14: MOVFF 26,30C
0EC18: MOVFF 25,30B
0EC1C: BRA E986 // this seems very wrong
0EC1E: MOVLW 0D
0EC20: MOVLB 3
0EC22: MOVWF x40
0EC24: MOVLB 0
0EC26: CALL BEAA
0EC2A: MOVLW 0A
0EC2C: MOVLB 3
0EC2E: MOVWF x40
0EC30: MOVLB 0
0EC32: CALL BEAA
compiled with %ld
.................... //** reload Tx buffer
.................... // note: using %lu for 2nd parm caused Vout not to work - don't know why
.................... // sprintf(TxBuffer+1," %8ld %8ld\r\n",(signed int32)FdcResultCh0 - llZeroOffset,(signed int32)FdcResultCh0);
.................... sprintf(TxBuffer+1," %10ld\r\n",FdcResultCh0);
0EB22: MOVLB 2
0EB24: CLRF xFA
0EB26: MOVLW 53
0EB28: MOVWF xF9
0EB2A: MOVLW 20
0EB2C: MOVLB 3
0EB2E: MOVWF x40
0EB30: MOVLB 0
0EB32: CALL BEAA
0EB36: MOVLW 20
0EB38: MOVLB 3
0EB3A: MOVWF x40
0EB3C: MOVLB 0
0EB3E: CALL BEAA
0EB42: MOVLW 4A
0EB44: MOVWF FE9
0EB46: MOVFF 28,337
0EB4A: MOVFF 27,336
0EB4E: MOVFF 26,335
0EB52: MOVFF 25,334
0EB56: CALL BEFC
0EB5A: MOVLW 0D
0EB5C: MOVLB 3
0EB5E: MOVWF x40
0EB60: MOVLB 0
0EB62: CALL BEAA
0EB66: MOVLW 0A
0EB68: MOVLB 3
0EB6A: MOVWF x40
0EB6C: MOVLB 0
0EB6E: CALL BEAA
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 04, 2018 9:17 am |
|
|
If a routine is called only once in a program, the compiler will often do a BRA
to the routine, and then another BRA back to where it was "called" it from.
This is done to save a stack location.
If you want help on this, you should post a very small but complete test
program that is compilable without errors. |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Jun 04, 2018 9:28 am |
|
|
Thanks, PCM. I didn't know that.
I'm trying to sort out a bug and changing the sprintf resulted in the exact same symptom. I must be looking in the wrong place. Just not exactly sure what I'm looking for, yet. I'm suspecting it has to do with signed and unsigned int32's.
Is there any way to know if the last few compiler updates that I missed relate to this chip? I looked around on the website but couldn't find anything like a compiler rev history. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Mon Jun 04, 2018 11:48 am |
|
|
As a general comment, the commonest problem with a sprintf, would be not enough space for the output. Remember the trailing \0. An overflow of the target buffer could cause all sorts of oddities. |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Jun 04, 2018 12:53 pm |
|
|
That was one of my first thoughts too. but the buffer is 80-bytes and longer strings print out without a problem. (it sure seemed like buffer overflow clobbering another variable)
I'm gonna do some things (set flags/ print variables) to try and narrow down where things are going wrong. I just thought for sure I found something that was closely related because just changing the format from %ld to %lu would make or break it.
Sorry I can't give you more info, but it's a bit complicated and would take a while to write out clearly. If I can't corner it soon I will write up a test program and post it.
Thanks, |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Mon Jun 04, 2018 12:57 pm |
|
|
Try with a fractionally shorter length for the output. Wondering if something in the printf is overflowing at 10 digits. I know an int32 can give ten digits, but it might be a mode that isn't expected!... |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Jun 04, 2018 1:19 pm |
|
|
Excellent thought (it didn't fix it, but worth a try). That would've been exactly the kind of thing I would have hoped to find.
I'm making some of my key local static variables global and printing them out to see the process better.. I already see something that is totally wrong, just need to track down why. It's either me or the compiler - probably me, but I should figure it out soon. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Jun 05, 2018 12:33 am |
|
|
Good Luck..
One thought any possibility of an interrupt event occuring during the print changing something?. For instance if the value being printed was updated in an interrupt I'd be looking at copying it into a local temporary copy before printing. Can you test if the actual print works OK without the other code?. |
|
|
|