Hi,

On Wednesday, 18 August 2021 21:38:32 CEST Jeremy Cole-Baker wrote:
> Hi,
> 
> We are using Nimble BLE on an Espressif ESP32 project. We are getting
> frequent crashes due to invalid memory access. It looks like a race
> condition / threading issue to me, but I can't find much info about using
> Nimble from different threads (i.e. different tasks in FreeRTOS).
> 
> Here's a typical crash log:
> 
> 0x4012773f: put_le16 at
> C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/porting/nimble/s
> rc/endian.c:24 0x400e77c5: ble_hs_hci_cmd_send at
> C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/
> ble_hs_hci_cmd.c:77 0x400e7819: ble_hs_hci_cmd_send_buf at
> C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/
> ble_hs_hci_cmd.c:122 0x400e3611: ble_hs_hci_cmd_tx at
> C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/
> ble_hs_hci.c:304 0x400e386b: ble_hs_hci_util_read_rssi at
> C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/
> ble_hs_hci_util.c:96 0x400e1709: ble_gap_conn_rssi at
> C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/
> ble_gap.c:5906 0x400dc0d5: RSSIUpdateTask at
> C:\Users\Jeremycb\esp\wireless-controller\build/../components/wc_bluetooth/
> wc_ble_services.c:369 0x40092e39: vPortTaskWrapper at
> C:/Users/Jeremycb/esp-idf/components/freertos/port/xtensa/port.c:168
> 
> It looks like a bad pointer (NULL) passed to "put_le16".
> 
> I've seen 3 different call paths, 2 from my own tasks and one from the task
> used to start / run Nimble. They all converge at the function
> "ble_hs_hci_cmd_send_buf", which then calls "ble_hs_hci_cmd_send"
> 
> "ble_hs_hci_cmd_send" uses "ble_hci_trans_buf_alloc", but looking at the
> code for the "BLE_HCI_TRANS_BUF_CMD" option, there is only one buffer
> available, and the comments say that "The controller will only allow one
> outstanding command". Thus it returns NULL if called from different
> threads, and results in the crash.
> 
> Looking through the call paths, I see that we can get there two ways:
> "ble_hs_hci_cmd_tx" (called from our code and many other places) or
> "ble_hs_flow_tx_num_comp_pkts" (called from flow event callback, from BLE
> host task).
> 
> I looked for a mutex, and found that "ble_hs_hci_cmd_tx" locks
> ble_hs_hci_mutex, whereas "ble_hs_flow_event_cb" (called by BLE host task)
> locks ble_hs_mutex (different).
> 
> Our code is calling "ble_gap_conn_rssi" and "ble_gap_adv_rsp_set_fields" on
> different tasks / threads, which ultimately call "ble_hs_hci_cmd_tx".
> 
> So, it looks like it's NOT SAFE to call these functions on another thread.
> This looks like a bug, otherwise how would these functions be used?
> 

For the record, this will be handled by
https://github.com/apache/mynewt-nimble/pull/1012

-- 
pozdrawiam
Szymon Janc


Reply via email to