LINKER_SORT_BY_ALIGNMENT causing crash in start-up code

Hello,

I am working in ncs1.5.0 on a nrf52840dk based custom board. I have found an issue where adding a certain number of characteristics in a single BLE service causing my code to crash during start-up. I ran the debugger and see code hitting a Zephyr Fatal Error in SystemInit() as shown in the debugger screenshot.

I have investigated the issue and found that if I remove one of the Client Characteristic Configuration Declarations, everything works fine. The firmware will also work fine with all the characteristics are included and CONFIG_LINKER_SORT_BY_ALIGNMENT is disabled.

I compared the generated map files and found that the failing code results in a fill of 0x3 bytes that the working code does not have. The working code has one less Client Characteristic Configuration Declaration.

I also tried to add attribute ((aligned (4))) to the BLE service definition which had no effect on the issue and still crashed.

For now, I have removed one of the characteristics in the problematic BLE service to avoid this crash. I do not want to disable CONFIG_LINKER_SORT_BY_ALIGNMENT because that results in using too much memory for padding. Please see the attached code and screenshots for more info.

`/* The following code will cause a crash. */

BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);
`

`/* One of the Client Characteristic Configuration Declarations has been
commented out (line 36). This change resolves the firmware crash.*/

BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        // BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);

/* One of the Client Characteristic Configuration Declarations has been
    commented out (line 36). This change resolves the firmware crash.*/
	
BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        // BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);
/* The following code will cause a crash. */

BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);

Related