AnsweredAssumed Answered

Are setjmp()/longjmp() working correctly?

Question asked by Massimo Manca on Dec 7, 2016
Latest reply on Jan 26, 2017 by soledad
Branched to a new discussion

I am using LpcXpresso + GNU GCC + newlib-nano to write a short example to show how is possible to recover the execution from a Hard Fault (using a LPC1768). The problem is that longjmp() jumps out to the main() in startup code where I put an infinite while(1) loop instead to jump back to setjmp and choose the alternative path. Seems to me that this is a VERY BIG ERROR in the library. Any report confirming that?

 

#include <setjmp.h>

jmp_buf s_buf;

void printBoh(uint32_t sp, const char* str)
{
   printf("sp: %08X err: %s\r\n", sp, str);
}

void Pippo()
{
   longjmp(s_buf, 2);
}

void Start()
{
   if(!setjmp(s_buf))
      Pippo();
   else
      printBoh(0x10008000, "Hello World!");
}

int main(void)
{
   // TODO: insert code here
   Start();
   puts("End\n");
   return 0;
}

and this is the relevant part of the RESET handler:

 

__attribute__ ((section(".after_vectors")))void ResetISR(void)
{

    // Copy the data sections from flash to SRAM.
    unsigned int LoadAddr, ExeAddr, SectionLen;   
    unsigned int *SectionTableAddr;

    // Load base address of Global Section Table   
    SectionTableAddr = &__data_section_table;

    // Copy the data sections from flash to SRAM.   
    while (SectionTableAddr < &__data_section_table_end)
    {       
        LoadAddr = *SectionTableAddr++;       
        ExeAddr = *SectionTableAddr++;       
        SectionLen = *SectionTableAddr++;       
        data_init(LoadAddr, ExeAddr, SectionLen);   
    }   
    // At this point, SectionTableAddr = &__bss_section_table;   
    // Zero fill the bss segment   
    while (SectionTableAddr < &__bss_section_table_end)
    {       
        ExeAddr = *SectionTableAddr++;       
        SectionLen = *SectionTableAddr++;       
        bss_init(ExeAddr, SectionLen);   
    }   
    // fill the stack with 32bit mask data to find stack corruption   
    SectionLen = (unsigned)&__stack_start - (unsigned)&__stack_end;   
    _fill(&__stack_end, SectionLen, 0xDEADBEEF);

#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN)   
   SystemInit();
#endif

#if defined (__cplusplus)    // Call C++ library initialisation
   __libc_init_array();
#endif

#if defined (__REDLIB__)    // Call the Redlib library, which in turn calls main()   
   __main() ;
#else   
   main();
#endif

    // main() shouldn't return, but if it does, we'll just enter an infinite loop   
    while (1)
    {       
       ;   
    }
}

Outcomes