Code compiling but not executing???

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
I have the function below that is compiling without errors or warnings yet part of the code is not executing in the debugger.

I am using the XCB compiler V1.21 in MPLaBX V2.0

My chip is the PIC18F14K22.

If I set a breakpoint at the line "ones = val;" then I get a Broken Breakpoint in the IDE when the code starts to execute.

If I add a breakpoint on the line that calls display_setRefrigeratorValue and step into display_setRefrigeratorValue then it steps to the line ones = val within the while loop.

I also noticed that I cannot pause my code.




If I add the line int "m = 123;" after "ones = val;" then all works fine. The breakpoint works and I can pause the code.

At first I thought it might be a bad memory location (even though the chip verifies OK) so I changed out the chip with the same results. I also added a function with the same code but got similar results.

Any ideas what the heck is going on???





Rich (BB code):
void display_setRefrigeratorValue(int val)
{
    unsigned char tens;
    unsigned char ones;
   
    ones = val;        // If breakpoint is set here, I get Broken Breakpoint, unless the line below is not commented.
 // int m = 123;      If this line is uncomented then code executes as expected.

  
    while (val >= 10)
    {
      tens++;
      val -= 10;
      ones = val;    //Code steps to here if breakpoint is set where display_setRefrigeratorValue is being called.
    }

     val = ones;
    display_select(3);
    unsigned char portVal = DISPLAY_VALUE & 0xf0;
    DISPLAY_VALUE = portVal | (val);

    val = tens;
    display_select(2);
    unsigned char portVal = DISPLAY_VALUE & 0xf0;
    DISPLAY_VALUE = portVal | (val);

   

 }
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
I think its because you can only set a breakpoint on a line that actually generates code. The function name generates no code so the breakpoint can't resolve to a physical memory address. Sometimes I'll put a dummy variable operation to get a point to stop at so I can step into the first statement of a function.

It also may be a result of optimization. The first ones=val is not used before its updated in the loop. If you look at the disassembled output you can see where the actual machine code goes and at what address its set at.
 
Last edited:

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
I think its because you can only set a breakpoint on a line that actually generates code. The function name generates no code so the breakpoint can't resolve to a physical memory address. Sometimes I'll put a dummy variable operation to get a point to stop at so I can step into the first statement of a function.

If you look at the disassembled output you can see where the actual machine code goes and at what address its set at.

That can't be it. The line ones = val has to generate code. Why would adding a line int m = 123; fix it?

It also does not explain why Pause is disabled and why the code skips a number of lines of code when the function is stepped into.


I am think (maybe) it is because I was trying to modify a variable that was pushed onto the stack???

I changed things around so a temp variable is set with the value of val and that seems to work.
 

Tesla23

Joined May 10, 2009
542
I have the function below that is compiling without errors or warnings yet part of the code is not executing in the debugger.

I am using the XCB compiler V1.21 in MPLaBX V2.0

My chip is the PIC18F14K22.

If I set a breakpoint at the line "ones = val;" then I get a Broken Breakpoint in the IDE when the code starts to execute.

If I add a breakpoint on the line that calls display_setRefrigeratorValue and step into display_setRefrigeratorValue then it steps to the line ones = val within the while loop.

I also noticed that I cannot pause my code.




If I add the line int "m = 123;" after "ones = val;" then all works fine. The breakpoint works and I can pause the code.

At first I thought it might be a bad memory location (even though the chip verifies OK) so I changed out the chip with the same results. I also added a function with the same code but got similar results.

Any ideas what the heck is going on???





Rich (BB code):
void display_setRefrigeratorValue(int val)
{
    unsigned char tens;
    unsigned char ones;
   
    ones = val;        // If breakpoint is set here, I get Broken Breakpoint, unless the line below is not commented.
 // int m = 123;      If this line is uncomented then code executes as expected.

  
    while (val >= 10)
    {
      tens++;
      val -= 10;
      ones = val;    //Code steps to here if breakpoint is set where display_setRefrigeratorValue is being called.
    }

     val = ones;
    display_select(3);
    unsigned char portVal = DISPLAY_VALUE & 0xf0;
    DISPLAY_VALUE = portVal | (val);

    val = tens;
    display_select(2);
    unsigned char portVal = DISPLAY_VALUE & 0xf0;
    DISPLAY_VALUE = portVal | (val);

   

 }
Turn off optimization.

It looks like your compiler has eliminated all lines that refer to ones - as they don't do anything - check it out - just ignore all the lines that refer to ones, the algorithm still works. If that's the case that's impressive optimization.

Also, unless your compiler guarantees initialisation, you should initialise tens.
 

shteii01

Joined Feb 19, 2010
4,644
val is an integer. ones is declared as char. So main is passing an integer to the user defined function, but then in the user defined function you use it as character. Could this be a problem?
 

tshuck

Joined Oct 18, 2012
3,534
You could make them volatile, telling the compiler to not optimize them and implement them as coded.

The compiler might optimize out the first "ones = val", as this could be deemed unnecessary.
 

JohnInTX

Joined Jun 26, 2012
4,787
It looks like your compiler has eliminated all lines that refer to ones - as they don't do anything - check it out - just ignore all the lines that refer to ones, the algorithm still works. If that's the case that's impressive optimization.
XC8 is incredibly aggressive in its optimization. It can and will remove anything it decides isn't required - especially in the PRO (full-optimize) mode. The source lines that imply this removed code are basically comments i.e. source text that doesn't generate code. In multi-file projects, code that is generated by the compiler (extern functions etc) will be removed by the linker if its not referenced by anything. That's why I suggested that the disassembly listing be consulted to see what it actually generated. Its a different beast.

I don't know why adding the int m=123; line makes it work. Perhaps its actually breaking on the code that initializes the variable.

EDIT: I built the OP's code fragment in XC8 1.21 free (not full optimized) mode with the following results. Misc vars and routines are stubbed but as you can see on lines 25 and 34, no code is generated by ones=val because it doesn't affect anything. That's why you can't set a breakpoint on it.

Its too bad it doesn't show back in the source but that's the way it is.

Rich (BB code):
Disassembly Listing for Spinnaker
Generated From:
M:/UP/XC8/Spinaker/Spinnaker.X/dist/default/production/Spinnaker.X.production.elf
Jan 12, 2014 10:56:11 PM

---  M:/UP/XC8/Spinaker/Spinnaker.X/Spinaker.c  ---------------------------------------------------------
1:             /* 
2:              * File:   Spinaker.c
3:              * Author: John
4:              *
5:              * Created on January 12, 2014, 10:52 PM
6:              */
7:             
8:             #include <xc.h>
9:             
10:            
11:            /*
12:             * 
13:             */
14:            
15:            //void display_setRefrigeratorValue(int val)
16:            int val;
17:            unsigned char portVal, DISPLAY_VALUE;
18:            
19:            void main() {
3FB8  D005     BRA 0x3FC4
20:            
21:            
22:            {
23:                unsigned char tens;
24:                unsigned char ones;
25:   *********** ADDED BY JohnInTX: Note no code generated for the next line..  ******   
26:                ones = val;        // If breakpoint is set here, I get Broken Breakpoint, unless the line below is not commented.
27:             // int m = 123;      If this line is uncomented then code executes as expected.
28:            
29:            
30:                while (val >= 10)
3FC8  5002     MOVF 0x2, W, ACCESS
3FCA  0A80     XORLW 0x80
3FCC  0F80     ADDLW 0x80
3FCE  0E0A     MOVLW 0xA
3FD0  B4D8     BTFSC STATUS, 2, ACCESS
3FD2  5C01     SUBWF val, W, ACCESS
3FD4  B0D8     BTFSC STATUS, 0, ACCESS
3FD6  D7F1     BRA 0x3FBA
31:                {
32:                  tens++;
3FBA  2A05     INCF tens, F, ACCESS
33:                  val -= 10;
3FBC  0EF6     MOVLW 0xF6
3FBE  2601     ADDWF val, F, ACCESS
3FC0  0EFF     MOVLW 0xFF
3FC2  2202     ADDWFC 0x2, F, ACCESS
34:                  ones = val;    //Code steps to here if breakpoint is set where display_setRefrigeratorValue is being called.
3FC4  C001     MOVFF val, ones
3FC6  F006     NOP
35:                }
EDIT2: As to why it breaks with m=123, adding that to the code gets this (excerpt):
Rich (BB code):
19:            void main() {
20:            
21:            
22:            {
23:                unsigned char tens;
24:                unsigned char ones;
25:            
26:                ones = val;        // If breakpoint is set here, I get Broken Breakpoint, unless the line below is not commented.
3FAC  C006     MOVFF val, ones
3FAE  F004     NOP
27:              int m = 123;      //If this line is uncomented then code executes as expected.
3FB0  0E00     MOVLW 0x0
3FB2  6E02     MOVWF 0x2, ACCESS
3FB4  0E7B     MOVLW 0x7B
3FB6  6E01     MOVWF m, ACCESS
You can see that ones=val now generates code. I don't know why but that's where your breakpoint on ones=val came from.

Finally, I don't have PRO mode for 1.21 but DID rebuild it in 1.12 PRO mode with the same results, ones=val is generated but not int m=123. It DID issue warnings about unused variables though. Go figure.
 
Last edited:

Tesla23

Joined May 10, 2009
542
EDIT: I built the OP's code fragment in XC8 1.21 free (not full optimized) mode with the attached results. Misc vars and routines are stubbed but as you can see on lines 25 and 34, no code is generated by ones=val because it doesn't affect anything. That's why you can't set a breakpoint on it.
I'm intrigued that the compiler still generated code for
Rich (BB code):
ones = val
inside the loop. Did it actually do the assignment
Rich (BB code):
val = ones
after the loop, if so it would appear to be incorrect in the case that the loop doesn't execute (val < 10). If it omitted the one after the loop, then why did it leave the one inside the loop?

Ah - I see. It's not very aggressive optimization, it's just noticed that it can skip the initial "ones = val" line by having the entry point of the routine to be the "ones = val" line in the while loop. If you put anything else before the loop this doesn't work, so it has to generate the additional "ones = val" code before the loop.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
I'm intrigued that the compiler still generated code for
Rich (BB code):
ones = val
inside the loop. Did it actually do the assignment
Rich (BB code):
val = ones
after the loop, if so it would appear to be incorrect in the case that the loop doesn't execute (val < 10). If it omitted the one after the loop, then why did it leave the one inside the loop?
Beats me. In PRO mode it did warn about assigning a value that was never used, more like a conventional compiler.

I've been trying off and on to master XC8's optimizations. I have an old project using an RTOS that does scheduling via stack operations. XC8 doesn't seem to be able to track that kind of thing so it optimizes out pretty much the whole 30K lines of C. Unfortunate.
 

Tesla23

Joined May 10, 2009
542
Beats me. In PRO mode it did warn about assigning a value that was never used, more like a conventional compiler.

I've been trying off and on to master XC8's optimizations. I have an old project using an RTOS that does scheduling via stack operations. XC8 doesn't seem to be able to track that kind of thing so it optimizes out pretty much the whole 30K lines of C. Unfortunate.
I think I figured it out - and edited it into my previous reply while you were posting. In case you missed it:

It's not very aggressive optimization, it's just noticed that it can skip the initial "ones = val" line by having the entry point of the routine to be the "ones = val" line in the while loop. If you put anything else before the loop this doesn't work, so it has to generate the additional "ones = val" code before the loop.
 

JohnInTX

Joined Jun 26, 2012
4,787
It's not very aggressive optimization, it's just noticed that it can skip the initial "ones = val" line by having the entry point of the routine to be the "ones = val" line in the while loop. If you put anything else before the loop this doesn't work, so it has to generate the additional "ones = val" code before the loop.
Makes sense. Thanks for looking at it.
 
Top