• AVR Freaks

Hot!XC8 crashes

Author
CiccioB
Starting Member
  • Total Posts : 50
  • Reward points : 0
  • Joined: 2013/12/11 05:32:50
  • Location: 0
  • Status: offline
2019/05/23 05:55:24 (permalink)
0

XC8 crashes

Hi all,
lately I have had problems porting an old code from C18 to latest XC8 version (2.05) (using PIC18F 27K40, but it does not seem to be related to a particular PIC or family as the same problem appeared also with a 27J53 and a 13K22).
Despite the usual porting problem with the IRQs and pragmas all solved in few minutes, what was bugging me was that during the linking phase the linker crashed.
To understand it I had to compile the same code under Win7 where a window with gpic18 crash appeared (so at least I knew it was not my fault), while under Win10 nothing was appeared to inform about the crash and this message was in the console:
(908) exit status = 1
nbproject/Makefile-27K40.mk:361: recipe for target 'dist/27K40/production/Framework.X.production.hex' failed
make[2]: Leaving directory 'C:/Development/PIC/prj_B/MF000-Framework/Framework.X'
nbproject/Makefile-27K40.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Development/PIC/prj_B/MF000-Framework/Framework.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[2]: *** [dist/27K40/production/Framework.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 11s)

As you can see there's no actual reasons on why and where the problem was.
Even enabling the warnings didn't help.
So after an afternoon spent in trying to understand why it would not link (while all modules compiled correctly) I decided to simply "deconstruct" the code module by module and see who was the culprit.
It ended that there was a definition of an auto variable in a function managing IRQ disabling/enabling that was simply defined as:
const unsigned char gie = INTCONbits.GIE;

Removing the const resolved the problem and the program compiled and linked correctly.
const was used only as an help to the compiler to try to make it optimize better the use of that variables but it seems that in some occasions (others have appeared) it makes the linker die abruptly in the middle of its work, so removing it was not a problem.
After some code further manipulation, restating the const qualifier to that variables made an error message appear instead of a crash (don't ask why now it does not crash anymore):
../initfuncts.c:84:: error: (712) can't generate code for this expression

and clicking on it brings me to the same line as above.
I wonder how it is possible that a simple const qualifier prevents the linker (not the compiler) to generate the correct code which was correctly handled and generated by the old compiler.
 
Has some of you had similar experience with crashes on what seems to be perfectly legal C code?
 
post edited by CiccioB - 2019/05/25 04:20:40
#1

13 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 9998
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: XC8 crashes 2019/05/23 06:11:10 (permalink)
    +1 (1)
    I assume you are using the compiler in the new "C99" mode, not the old "C90" mode.
    https://microchipdeveloper.com/xc8:moving-to-xc8-2-0
     

    Nearly there...
    #2
    CiccioB
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2013/12/11 05:32:50
    • Location: 0
    • Status: offline
    Re: XC8 crashes 2019/05/23 06:56:54 (permalink)
    0
    Yes, C99 standard.
    #3
    NKurzman
    A Guy on the Net
    • Total Posts : 17341
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: XC8 crashes 2019/05/23 07:45:40 (permalink)
    0
    There is nothing above "(908) exit status = 1" ?
    #4
    du00000001
    Just Some Member
    • Total Posts : 2679
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: XC8 crashes 2019/05/23 08:29:31 (permalink)
    0 (2)
    Assigning a value to a const within a function body?
     
    I didn't know that such a construction could be compiled at all. Or has this been some "feature" (aka bug) in C18 ?

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #5
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11175
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: XC8 crashes 2019/05/23 08:46:04 (permalink)
    +1 (1)
    du00000001
    Assigning a value to a const within a function body?

     
    That's not an assignment, it's an initialization.  How else would you get a value into a const object?
    #6
    du00000001
    Just Some Member
    • Total Posts : 2679
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: XC8 crashes 2019/05/23 08:53:07 (permalink)
    0
    @ jtemples
    Sorry - you seem to have missed the point:
    CiccioB
    It ended that there was a definition of an auto variable in a function managing IRQ disabling/enabling that was simply defined as: ...
    const unsigned char gie = INTCONbits.GIE;


    This certainly is NOT some "standard intitialization". The more as the initialization value INTCONbits.GIE is a non-const and thus not available for standard const initialization.
     
    Really seems to be some weirdness of C18. No wonder XC8 exits ...

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #7
    1and0
    Access is Denied
    • Total Posts : 9200
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: XC8 crashes 2019/05/23 09:12:52 (permalink)
    +1 (1)
    As I understand it, the const qualifier implies that the variable is read-only. Any const qualified variable with automatic (non-static) storage in a function having its initial value assigned is valid.
     
    That is, within a function this
    const unsigned char gie = INTCONbits.GIE;

    is okay, but this
    const unsigned char gie;
    gie = INTCONbits.GIE;

    is not.
    #8
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11175
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: XC8 crashes 2019/05/23 09:30:00 (permalink)
    +1 (1)
    INTCONbits.GIE is a non-const and thus not available for standard const initialization.

     
    "const" does not mean "constant" and has nothing do with with constants.  It means "read only", i.e., you cannot modify it after it has been initialized.  At block scope, anything, including a const, can be initialized with a non-constant value.
     
    If you look at some other embedded compilers, you'll see const used in SFRs as well.  For example, it's common for the UART receive register to be declared const, because it's read-only; you cannot write to it.
    #9
    1and0
    Access is Denied
    • Total Posts : 9200
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: XC8 crashes 2019/05/23 09:32:21 (permalink)
    +1 (1)
    Just as an example, XC8 generates this 
    3: void foo(void)
    4: {
    5: const unsigned char gie = INTCONbits.GIE;
    7FE0 0E00 MOVLW 0x0
    7FE2 BEF2 BTFSC INTCON, 7, ACCESS
    7FE4 0E01 MOVLW 0x1
    7FE6 6E01 MOVWF __pcstackCOMRAM, ACCESS
    6:
    7: INTCONbits.GIE = 0;
    7FE8 9EF2 BCF INTCON, 7, ACCESS
    8: EECON2 = 0x55;
    7FEA 0E55 MOVLW 0x55
    7FEC 6EA7 MOVWF EECON2, ACCESS
    9: EECON2 = 0xAA;
    7FEE 0EAA MOVLW 0xAA
    7FF0 6EA7 MOVWF EECON2, ACCESS
    10: EECON1bits.WR = 1;
    7FF2 82A6 BSF EECON1, 1, ACCESS
    11: INTCONbits.GIE = gie;
    7FF4 B001 BTFSC __pcstackCOMRAM, 0, ACCESS
    7FF6 D002 BRA 0x7FFC
    7FF8 9EF2 BCF INTCON, 7, ACCESS
    7FFA D001 BRA 0x7FFE
    7FFC 8EF2 BSF INTCON, 7, ACCESS
    12: }

    for this
    void foo(void)
    {
    const unsigned char gie = INTCONbits.GIE;

    INTCONbits.GIE = 0;
    EECON2 = 0x55;
    EECON2 = 0xAA;
    EECON1bits.WR = 1;
    INTCONbits.GIE = gie;
    }

    #10
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11175
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: XC8 crashes 2019/05/23 10:01:48 (permalink)
    +1 (1)
    Just as an example, XC8 generates this

     
    And I would expect it to generate the exact same code without "const", because const has no relevance to the runtime code in this context.  const is just being used as "good programming practice" here.
    #11
    1and0
    Access is Denied
    • Total Posts : 9200
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: XC8 crashes 2019/05/23 10:13:58 (permalink)
    +1 (1)
    jtemples
    And I would expect it to generate the exact same code without "const", because const has no relevance to the runtime code in this context.  const is just being used as "good programming practice" here.

    Agreed and it does.
    #12
    mad_c
    Super Member
    • Total Posts : 1175
    • Reward points : 0
    • Joined: 2010/12/12 17:48:27
    • Location: Brisbane, Australia
    • Status: offline
    Re: XC8 crashes 2019/05/23 13:30:04 (permalink)
    +1 (1)
    Hi,
     
    I have seen occasions where the IDE does not report the errors generated by the compiler. Should you notice this, you can build your project on the command line to see what is happening. If you have the appropriate build tools installed on your machine, you can simply type 'make' using the project's makefile. Alternately, you can copy the command lines used by the IDE into your terminal window.
     
    In any case, your line of C code is valid, and in my tests, I could see that it built fine in C90 mode, but gave a can't generate code error when building for C99. There is a difference in the p1 output from the front end for these two cases, which may be why the code generator was not able to build the statement.
     
    I would send in a support request regarding this, so that it can be examined in more detail.
     
    Jeff.
    #13
    CiccioB
    Starting Member
    • Total Posts : 50
    • Reward points : 0
    • Joined: 2013/12/11 05:32:50
    • Location: 0
    • Status: offline
    Re: XC8 crashes 2019/05/25 04:35:11 (permalink)
    0
    NKurzman
    There is nothing above "(908) exit status = 1" ?

     
    Yes, just the long lie of the linker command with all the files, which compiled without errors or warning, it is trying to link.
     
    mad_c
    Hi,
     
    I have seen occasions where the IDE does not report the errors generated by the compiler. Should you notice this, you can build your project on the command line to see what is happening. If you have the appropriate build tools installed on your machine, you can simply type 'make' using the project's makefile. Alternately, you can copy the command lines used by the IDE into your terminal window.
     
    In any case, your line of C code is valid, and in my tests, I could see that it built fine in C90 mode, but gave a can't generate code error when building for C99. There is a difference in the p1 output from the front end for these two cases, which may be why the code generator was not able to build the statement.
     
    I would send in a support request regarding this, so that it can be examined in more detail.
     
    Jeff.




    Thanks mad_c.
    I have seen that some more warning/error messages can appear if you put a wrong extra parameter to the compiler. It just prints a lot of warning messages about the fact that the parameter is not valid and in between them some new warning/error messages, never seen otherwise, may appear.
     
    About the qualifier const, it is a perfectly allowed construct to declare a read-only variable with two goals:
    1. prompt an error at compilation time if trying to write to it after its initialization
    2. help the compiler takes some strategy to better optimize the code knowing that that variable value will never change throughout the entire function code.
     
    For instance that code was used to store the value of the GIE field to be restored before the exit of the function, as in this particular case:
    static void InitPPS(void)
     
    {
    const U8 gie = INTCONbits.GIE;
    INTCONbits.GIE = 0;

    /* Allow PPS register writing */
    /* Unlock sequence */
    EECON2 = 0x55;
    EECON2 = 0xAA;
    PPSCONbits.IOLOCK = 0;
    /* Now we can modify PPS registers */

    /* We lock PPS registers again */
    EECON2 = 0x55;
    EECON2 = 0xAA;
    PPSCONbits.IOLOCK = 1;
      
     INTCONbits.GIE = gie;
    }
     

     
     
    post edited by CiccioB - 2019/05/25 04:36:30
    #14
    Jump to:
    © 2019 APG vNext Commercial Version 4.5