Based on finding durring #596 I let AI agent analyze whole mbed-os for this wrong usage and found 12 issues with MBED_ASSERT. For example STM32WL will probably not work in Release profile because RCC config is placed inside MBED_ASSERT.
MBED_ASSERT expands to ((void)0) when NDEBUG is defined, so its argument is not evaluated. Several places call functions with required side effects directly inside MBED_ASSERT, causing initialization, configuration, buffer modification, or cleanup operations to be skipped in Release builds.
These function calls should be executed separately, with only their return values passed to MBED_ASSERT.
Confirmed MBED_ASSERT side-effect issues
1. GATT characteristic handle lookup is skipped
- File:
connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cpp
- Function:
ble::impl::GattServer::handleEvent()
- Exact lines: 1759 and 1776
- Affected subsystem/target: Cordio BLE GATT server
- GitHub permalinks: updates enabled, line 1759, updates disabled, line 1776
- Assert expression:
MBED_ASSERT(get_value_handle_by_cccd_handle(attributeHandle, charHandle));
This expression occurs at both locations.
- Required operation:
get_value_handle_by_cccd_handle() looks up the CCCD and writes the corresponding characteristic value handle through the charHandle reference. Its implementation assigns char_handle = cccd_handles[idx].
- Behaviour with NDEBUG: The lookup and output assignment do not happen. The subsequently constructed
GattUpdatesEnabledCallbackParams or GattUpdatesDisabledCallbackParams contains an uninitialized charHandle.
- Confidence: High
2. lwIP pbuf header adjustment is skipped
- File:
connectivity/lwipstack/source/LWIPMemoryManager.cpp
- Function:
LWIPMemoryManager::skip_header_space()
- Exact line: 131
- Affected subsystem/target: lwIP network buffer management
- GitHub permalink: line 131
- Assert expression:
MBED_ASSERT(pbuf_header_force(static_cast<struct pbuf *>(buf), -amount) == 0);
- Required operation:
pbuf_header_force() calls pbuf_header_impl(). For the negative argument used here, it calls pbuf_remove_header(), which advances p->payload and updates p->len, p->tot_len, and p->header_bytes_removed.
- Behaviour with NDEBUG:
skip_header_space() performs no header adjustment. Buffer payload position and length metadata remain unchanged.
- Confidence: High
3. Apollo3 BLE controller power-up is skipped
- File:
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cpp
- Function:
ble::AP3CordioHCIDriver::do_initialize()
- Exact line: 56
- Affected subsystem/target: Cordio BLE, Ambiq Micro Apollo3 when
USE_AMBIQ_DRIVER is not defined
- GitHub permalink: line 56
- Assert expression:
MBED_ASSERT(am_hal_ble_power_control(*_ptr_to_handle, AM_HAL_BLE_POWER_ACTIVE) == AM_HAL_STATUS_SUCCESS);
- Required operation:
am_hal_ble_power_control() enables the BLE power domain, releases reset, enables clocks, starts the BLE power-state machine, and waits for the controller to become active.
- Behaviour with NDEBUG: The BLE controller is not powered or released from reset before later initialization and interrupt enablement.
- Confidence: High
4. Apollo3 BLE hardware configuration is skipped
- File:
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cpp
- Function:
ble::AP3CordioHCIDriver::do_initialize()
- Exact line: 57
- Affected subsystem/target: Cordio BLE, Ambiq Micro Apollo3 when
USE_AMBIQ_DRIVER is not defined
- GitHub permalink: line 57
- Assert expression:
MBED_ASSERT(am_hal_ble_config(*_ptr_to_handle, &_ble_config) == AM_HAL_STATUS_SUCCESS);
- Required operation:
am_hal_ble_config() programs BLEIF SPI, FIFO, and clock registers, updates NVDS configuration where applicable, recalculates its CRC, and records patch configuration.
- Behaviour with NDEBUG: The BLE interface and controller configuration are not applied.
- Confidence: High
5. Apollo3 BLE boot and patch application is skipped
- File:
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cpp
- Function:
ble::AP3CordioHCIDriver::do_initialize()
- Exact line: 58
- Affected subsystem/target: Cordio BLE, Ambiq Micro Apollo3 when
USE_AMBIQ_DRIVER is not defined
- GitHub permalink: line 58
- Assert expression:
MBED_ASSERT(am_hal_ble_boot(*_ptr_to_handle) == AM_HAL_STATUS_SUCCESS);
- Required operation:
am_hal_ble_boot() performs the operations needed to prepare the BLE controller for HCI, including applicable code, trim, and NVDS patching and patch completion.
- Behaviour with NDEBUG: Controller boot preparation and required silicon patch application do not occur.
- Confidence: High
6. Apollo3 BLE transmit-power configuration is skipped
- File:
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cpp
- Function:
ble::AP3CordioHCIDriver::do_initialize()
- Exact line: 59
- Affected subsystem/target: Cordio BLE, Ambiq Micro Apollo3 when
USE_AMBIQ_DRIVER is not defined
- GitHub permalink: line 59
- Assert expression:
MBED_ASSERT(am_hal_ble_tx_power_set(*_ptr_to_handle, 0x0F) == AM_HAL_STATUS_SUCCESS);
- Required operation:
am_hal_ble_tx_power_set() unlocks BLE registers and writes the requested transmit-power level to controller registers/RAM.
- Behaviour with NDEBUG: The requested
0x0F transmit-power setting is not programmed.
- Confidence: High
7. Apollo3 BLE sleep configuration is skipped
- File:
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cpp
- Function:
ble::AP3CordioHCIDriver::do_initialize()
- Exact line: 60
- Affected subsystem/target: Cordio BLE, Ambiq Micro Apollo3 when
USE_AMBIQ_DRIVER is not defined
- GitHub permalink: line 60
- Assert expression:
MBED_ASSERT(am_hal_ble_sleep_set(*_ptr_to_handle, false) == AM_HAL_STATUS_SUCCESS);
- Required operation:
am_hal_ble_sleep_set() updates the BLE controller’s sleep-enable state in controller RAM; here it disables sleep.
- Behaviour with NDEBUG: Sleep is not explicitly disabled during controller initialization.
- Confidence: High
8. MAX32620C ADC initialization is skipped
- File:
targets/TARGET_Maxim/TARGET_MAX32620C/analogin_api.c
- Function:
analogin_init()
- Exact line: 56
- Affected subsystem/target: Analog input, Maxim MAX32620C
- GitHub permalink: line 56
- Assert expression:
MBED_ASSERT(ADC_Init() == E_NO_ERROR);
- Required operation:
ADC_Init() initializes the ADC system clock/power through SYS_ADC_Init(), clears prior configuration and interrupt flags, enables the completion interrupt, and powers up the ADC and associated clock/buffer/reference circuitry.
- Behaviour with NDEBUG:
initialized is set to 1, but the ADC hardware has not actually been initialized or powered up. Later calls will also skip initialization.
- Confidence: High
9. MAX32625 ADC initialization is skipped
- File:
targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.c
- Function:
analogin_init()
- Exact line: 56
- Affected subsystem/target: Analog input, Maxim MAX32625
- GitHub permalink: line 56
- Assert expression:
MBED_ASSERT(ADC_Init() == E_NO_ERROR);
- Required operation:
ADC_Init() enables the ADC through SYS_ADC_Init(), clears/configures ADC interrupt state, and powers up the ADC, clock, input buffer, reference buffer, and charge pump.
- Behaviour with NDEBUG: Software marks the ADC initialized without performing the hardware initialization.
- Confidence: High
10. MAX32630 ADC initialization is skipped
- File:
targets/TARGET_Maxim/TARGET_MAX32630/analogin_api.c
- Function:
analogin_init()
- Exact line: 56
- Affected subsystem/target: Analog input, Maxim MAX32630
- GitHub permalink: line 56
- Assert expression:
MBED_ASSERT(ADC_Init() == E_NO_ERROR);
- Required operation:
ADC_Init() enables the ADC through SYS_ADC_Init(), clears/configures ADC interrupt state, and powers up the ADC, clock, input buffer, reference buffer, and charge pump.
- Behaviour with NDEBUG: Software marks the ADC initialized without performing the hardware initialization.
- Confidence: High
11. STM32WL oscillator configuration is skipped
- File:
targets/TARGET_STM/TARGET_STM32WL/system_clock.c
- Function:
SetSysClock()
- Exact line: 56
- Affected subsystem/target: System clock initialization, STM32WL
- GitHub permalink: line 56
- Assert expression:
MBED_ASSERT(HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK);
- Required operation: STM32 HAL
HAL_RCC_OscConfig() programs and starts the selected MSI oscillator configuration.
- Behaviour with NDEBUG: The requested MSI oscillator state, calibration, and clock range are not applied.
- Confidence: High
12. STM32WL bus and system-clock configuration is skipped
- File:
targets/TARGET_STM/TARGET_STM32WL/system_clock.c
- Function:
SetSysClock()
- Exact line: 67
- Affected subsystem/target: System clock initialization, STM32WL
- GitHub permalink: line 67
- Assert expression:
MBED_ASSERT(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) == HAL_OK);
- Required operation: STM32 HAL
HAL_RCC_ClockConfig() applies the system-clock source, AHB/APB dividers, and flash latency.
- Behaviour with NDEBUG: The configured MSI system-clock selection, bus dividers, and flash latency are not applied.
- Confidence: High
Uncertain candidates
None. Other call-bearing assertions found by the audit were getters, validators, ownership/state queries, alignment checks, pin/property lookups, or equivalent read-only operations.
Audit summary
- Inspected commit:
1f5bc495dad0d551ff12a037d7f49e8f45ed2c7f
- Repository availability: The commit is present in
mbed-ce/mbed-os and is contained by origin/main.
- Number of MBED_ASSERT occurrences searched: 2,402 invocations, excluding 3 macro definitions
- Number of source files searched: 14,441 tracked C/C++ source and header files
- Number of confirmed issues: 13 assertion occurrences, grouped into 12 findings above because the identical GATT error occurs in two event branches
- Number of uncertain candidates: 0
Based on finding durring #596 I let AI agent analyze whole mbed-os for this wrong usage and found 12 issues with MBED_ASSERT. For example STM32WL will probably not work in Release profile because RCC config is placed inside MBED_ASSERT.
MBED_ASSERTexpands to((void)0)whenNDEBUGis defined, so its argument is not evaluated. Several places call functions with required side effects directly insideMBED_ASSERT, causing initialization, configuration, buffer modification, or cleanup operations to be skipped in Release builds.These function calls should be executed separately, with only their return values passed to
MBED_ASSERT.Confirmed MBED_ASSERT side-effect issues
1. GATT characteristic handle lookup is skipped
connectivity/FEATURE_BLE/source/cordio/source/GattServerImpl.cppble::impl::GattServer::handleEvent()MBED_ASSERT(get_value_handle_by_cccd_handle(attributeHandle, charHandle));get_value_handle_by_cccd_handle()looks up the CCCD and writes the corresponding characteristic value handle through thecharHandlereference. Its implementation assignschar_handle = cccd_handles[idx].GattUpdatesEnabledCallbackParamsorGattUpdatesDisabledCallbackParamscontains an uninitializedcharHandle.2. lwIP pbuf header adjustment is skipped
connectivity/lwipstack/source/LWIPMemoryManager.cppLWIPMemoryManager::skip_header_space()pbuf_header_force()callspbuf_header_impl(). For the negative argument used here, it callspbuf_remove_header(), which advancesp->payloadand updatesp->len,p->tot_len, andp->header_bytes_removed.skip_header_space()performs no header adjustment. Buffer payload position and length metadata remain unchanged.3. Apollo3 BLE controller power-up is skipped
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cppble::AP3CordioHCIDriver::do_initialize()USE_AMBIQ_DRIVERis not definedam_hal_ble_power_control()enables the BLE power domain, releases reset, enables clocks, starts the BLE power-state machine, and waits for the controller to become active.4. Apollo3 BLE hardware configuration is skipped
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cppble::AP3CordioHCIDriver::do_initialize()USE_AMBIQ_DRIVERis not definedam_hal_ble_config()programs BLEIF SPI, FIFO, and clock registers, updates NVDS configuration where applicable, recalculates its CRC, and records patch configuration.5. Apollo3 BLE boot and patch application is skipped
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cppble::AP3CordioHCIDriver::do_initialize()USE_AMBIQ_DRIVERis not definedam_hal_ble_boot()performs the operations needed to prepare the BLE controller for HCI, including applicable code, trim, and NVDS patching and patch completion.6. Apollo3 BLE transmit-power configuration is skipped
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cppble::AP3CordioHCIDriver::do_initialize()USE_AMBIQ_DRIVERis not definedam_hal_ble_tx_power_set()unlocks BLE registers and writes the requested transmit-power level to controller registers/RAM.0x0Ftransmit-power setting is not programmed.7. Apollo3 BLE sleep configuration is skipped
connectivity/drivers/ble/FEATURE_BLE/TARGET_Ambiq_Micro/TARGET_Apollo3/AP3CordioHCIDriver.cppble::AP3CordioHCIDriver::do_initialize()USE_AMBIQ_DRIVERis not definedam_hal_ble_sleep_set()updates the BLE controller’s sleep-enable state in controller RAM; here it disables sleep.8. MAX32620C ADC initialization is skipped
targets/TARGET_Maxim/TARGET_MAX32620C/analogin_api.canalogin_init()ADC_Init()initializes the ADC system clock/power throughSYS_ADC_Init(), clears prior configuration and interrupt flags, enables the completion interrupt, and powers up the ADC and associated clock/buffer/reference circuitry.initializedis set to1, but the ADC hardware has not actually been initialized or powered up. Later calls will also skip initialization.9. MAX32625 ADC initialization is skipped
targets/TARGET_Maxim/TARGET_MAX32625/analogin_api.canalogin_init()ADC_Init()enables the ADC throughSYS_ADC_Init(), clears/configures ADC interrupt state, and powers up the ADC, clock, input buffer, reference buffer, and charge pump.10. MAX32630 ADC initialization is skipped
targets/TARGET_Maxim/TARGET_MAX32630/analogin_api.canalogin_init()ADC_Init()enables the ADC throughSYS_ADC_Init(), clears/configures ADC interrupt state, and powers up the ADC, clock, input buffer, reference buffer, and charge pump.11. STM32WL oscillator configuration is skipped
targets/TARGET_STM/TARGET_STM32WL/system_clock.cSetSysClock()HAL_RCC_OscConfig()programs and starts the selected MSI oscillator configuration.12. STM32WL bus and system-clock configuration is skipped
targets/TARGET_STM/TARGET_STM32WL/system_clock.cSetSysClock()HAL_RCC_ClockConfig()applies the system-clock source, AHB/APB dividers, and flash latency.Uncertain candidates
None. Other call-bearing assertions found by the audit were getters, validators, ownership/state queries, alignment checks, pin/property lookups, or equivalent read-only operations.
Audit summary
1f5bc495dad0d551ff12a037d7f49e8f45ed2c7fmbed-ce/mbed-osand is contained byorigin/main.