Dead code from libs cause Fatal Exception right after boot
Posted: Wed Aug 29, 2018 12:06 pm
Hi all !
I've the following test code that crashes right after boot with Fatal Exceptions depending on wether I link my code with the gc-option and if I link against some libs whoses functions are never called (no problem, not a signle line of my user code is even executed).
More interestingly, I noticed the crash only when I build my app for FOTA:
The simple code below runs as expected when compiled for non-FOTA. But when compiled for FOTA:
- If linked with gc-section option, works only if pwm_start() is commented out.
- If linked without gc-section option, works only if pwm_start() and espconn_secure_set_size() are commented out...
I strongly suspect some misaligned data.
The problem seems related to the influence of the order of the libs in the linker command (viewtopic.php?f=9&t=11972) but I can't see the logic to deduce the correct ordering, that seems to varies from an app to another.
Full of hope, I tried to force 4-byte alignment of the symbol _Pri_3_HandlerAddress, that is not aligned accorind to this post, as when I look into the disasembled code the very first instructions of user code seems to deal with NMI (viewtopic.php?f=6&t=4675&p=46002&hilit=linking+library+order#p46002)
This is making me crazy from weeks, would you have any idea ?
My Xtensa compiler command looks like:
I then use esptool elf2image -version=2 to convert the elf to binaries.
(esp-open-sdk, NONOS-SDK 2.2, esp8266 with 2MBytes 512+512 flash map)
Many thanks !
I've the following test code that crashes right after boot with Fatal Exceptions depending on wether I link my code with the gc-option and if I link against some libs whoses functions are never called (no problem, not a signle line of my user code is even executed).
More interestingly, I noticed the crash only when I build my app for FOTA:
The simple code below runs as expected when compiled for non-FOTA. But when compiled for FOTA:
- If linked with gc-section option, works only if pwm_start() is commented out.
- If linked without gc-section option, works only if pwm_start() and espconn_secure_set_size() are commented out...
I strongly suspect some misaligned data.
The problem seems related to the influence of the order of the libs in the linker command (viewtopic.php?f=9&t=11972) but I can't see the logic to deduce the correct ordering, that seems to varies from an app to another.
Full of hope, I tried to force 4-byte alignment of the symbol _Pri_3_HandlerAddress, that is not aligned accorind to this post, as when I look into the disasembled code the very first instructions of user code seems to deal with NMI (viewtopic.php?f=6&t=4675&p=46002&hilit=linking+library+order#p46002)
This is making me crazy from weeks, would you have any idea ?
Code: Select all
/*
* Debuging app that crashes with fatal exception when compiled fo OTA.
* Compiled fo non-OTA: works
* Compiled for OTA (bootloader 1.7): fatal exception right after boot. Due to PWM lib ?
*/
#include "osapi.h"
#include "os_type.h"
#include "user_interface.h"
#include "gpio.h"
#include "pwm.h"
#include "espconn.h"
#include "driver/i2c_master.h"
void PostInitCb(void);
uint32 user_rf_cal_sector_set(void);
void user_init(void);
/**
* @brief Called when system is fully initialized.
*/
void PostInitCb(void)
{
os_printf("PostInitCb() !\n");
/* Force references to functions from the libs without calling them */
volatile bool tt = false;
if(tt)
{
pwm_start(); /* Uncommented: crash ! */
gpio_init(); /* Uncommented or commented: ok */
espconn_secure_set_size(ESPCONN_CLIENT, 5120); /* Uncommented or commented: depends on gc-section */
i2c_master_gpio_init(); /* Uncommented or commented: ok */
}
}
/**
* @brief Was present in IoT_Demo/user/user_main.c on which this code is based...
*/
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void)
{
os_printf("BB!\n");
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
/**
* @brief Main entry point of our programm
*/
void user_init(void)
{
os_printf("AA!\n");
system_init_done_cb(PostInitCb);
}
My Xtensa compiler command looks like:
I then use esptool elf2image -version=2 to convert the elf to binaries.
(esp-open-sdk, NONOS-SDK 2.2, esp8266 with 2MBytes 512+512 flash map)
Code: Select all
xtensa-lx106-elf-gcc *.c -Wall -Wextra -Wconversion -Wshadow -Wcast-qual -Wdouble-promotion -Wcast-align -Wmissing-prototypes -std=c99 -pedantic -Wno-missing-braces -Wno-missing-field-initializers -mlongcalls -DICACHE_FLASH -ffunction-sections -fdata-sections -I. -isystem../ESP8266_NONOS_SDK-2.2.0/include -isystem../ESP8266_NONOS_SDK-2.2.0/driver_lib/include -nostdlib -Wl,-EL -mtext-section-literals -L../ESP8266_NONOS_SDK-2.2.0/lib -T../ESP8266_NONOS_SDK-2.2.0/ld/eagle.app.v6.new.1024.app1.ld -Wl,--no-check-sections -Wl,--gc-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lphy -lpp -lmain -lwpa -lcrypto -llwip -lupgrade -lssl -lpwm -ldriver -lnet80211 -lm -Wl,--end-group -o debug_rom1.bin.elf
Many thanks !