mickeyl opened a new issue, #1741:
URL: https://github.com/apache/mynewt-nimble/issues/1741

   I'm currently debugging a race condition. There are two threads involved. My 
custom one is trying to `ble_l2cap_send`, the other one (`nimble_host`) is 
handling the `disconnect` event.
   
   Here are the corresponding tracebacks. The occurs in the thread 
`MCP-Receiver`:
   
   ```
   ble_hs_hci_acl_tx(struct ble_hs_conn * conn, struct os_mbuf ** om) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci.c:617)
   ble_l2cap_tx(struct ble_hs_conn * conn, struct ble_l2cap_chan * chan, struct 
os_mbuf * txom) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_l2cap.c:467)
   ble_l2cap_coc_continue_tx(struct ble_l2cap_chan * chan) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c:493)
   ble_l2cap_coc_send(struct ble_l2cap_chan * chan, struct os_mbuf * sdu_tx) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c:644)
   ble_l2cap_send(struct ble_l2cap_chan * chan, struct os_mbuf * sdu) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_l2cap.c:227)
   NimBLEL2CAPService::write(NimBLEL2CAPService * const this, const 
std::vector<unsigned char, std::allocator<unsigned char> > & bytes) 
(/home/mickey/Dokumente/late/ecos/esp-nimble-cpp/src/NimBLEL2CAPService.cpp:77)
   operator()(std::vector<unsigned char, std::allocator<unsigned char> > & 
data, const struct {...} * const __closure) 
(/home/mickey/Dokumente/late/ecos/firmware/main/Bluetooth/L2CAPServiceCallbacks.cpp:22)
   std::__invoke_impl<void, 
L2CAPServiceCallbacks::onConnect(NimBLEL2CAPService*)::<lambda(std::vector<unsigned
 char>&)>&, std::vector<unsigned char, std::allocator<unsigned char> >&>(struct 
{...} & __f) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/invoke.h:61)
   std::__invoke_r<void, 
L2CAPServiceCallbacks::onConnect(NimBLEL2CAPService*)::<lambda(std::vector<unsigned
 char>&)>&, std::vector<unsigned char, std::allocator<unsigned char> >&>(struct 
{...} & __fn) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/invoke.h:111)
   std::_Function_handler<void(std::vector<unsigned char, 
std::allocator<unsigned char> >&), 
L2CAPServiceCallbacks::onConnect(NimBLEL2CAPService*)::<lambda(std::vector<unsigned
 char, std::allocator<unsigned char> >&)> >::_M_invoke(const std::_Any_data &, 
std::vector<unsigned char, std::allocator<unsigned char> > &)(const 
std::_Any_data & __functor,  __args#0) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/std_function.h:290)
   std::function<void (std::vector<unsigned char, std::allocator<unsigned char> 
>&)>::operator()(std::vector<unsigned char, std::allocator<unsigned char> >&) 
const(const std::function<void(std::vector<unsigned char, 
std::allocator<unsigned char> >&)> * const this,  __args#0) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/std_function.h:591)
   ProtocolMachine::writePDU(ProtocolMachine * const this, CANyonero::PDU & 
pdu) 
(/home/mickey/Dokumente/late/ecos/firmware/main/ProtocolMachine/ProtocolMachine.cpp:192)
   ProtocolMachine::writePDUForIncomingData(ProtocolMachine * const this, const 
int channelNumber, const uint32_t id, const uint8_t extension, const 
std::vector<unsigned char, std::allocator<unsigned char> > & bytes) 
(/home/mickey/Dokumente/late/ecos/firmware/main/ProtocolMachine/ProtocolMachine.cpp:199)
   CANChannelManager::handleIncomingFrame(CANChannelManager * const this, 
CANMessage & frame) 
(/home/mickey/Dokumente/late/ecos/firmware/main/CAN/CANChannelManager.cpp:116)
   CANController::run(CANController * const this, void * data) 
(/home/mickey/Dokumente/late/ecos/firmware/main/CAN/CANController.cpp:76)
   Task::runTask(void * pTaskInstance) 
(/home/mickey/Dokumente/late/ecos/ESPenlaub/FreeRTOS/Task.hpp:175)
   vPortTaskWrapper(TaskFunction_t pxCode, void * pvParameters) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:134)
   ```
   
   While the channel is being shutdown, the `conn` is suddently NULL. Since the 
NimBLE code does not check for this case, it crashes.
   
   The root cause of this is the shutdown being handled by `nimble_host`:
   
   ```
   [Unknown/Just-In-Time compiled code] (Unknown Source:0)
   vPortClearInterruptMaskFromISR() 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h:564)
   vPortExitCritical(portMUX_TYPE * mux) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:504)
   xQueueSemaphoreTake(QueueHandle_t xQueue, TickType_t xTicksToWait) 
(/home/mickey/Dokumente/late/ecos/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:1853)
   Task::cancel(Task * const this) 
(/home/mickey/Dokumente/late/ecos/ESPenlaub/FreeRTOS/Task.hpp:102)
   CANController::~CANController(CANController * const this) 
(/home/mickey/Dokumente/late/ecos/firmware/main/CAN/CANController.cpp:36)
   CANController::~CANController(CANController * const this) 
(/home/mickey/Dokumente/late/ecos/firmware/main/CAN/CANController.cpp:39)
   std::default_delete<CANController>::operator()(CANController * __ptr) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/unique_ptr.h:93)
   std::__uniq_ptr_impl<CANController, std::default_delete<CANController> 
>::reset(std::__uniq_ptr_impl<CANController, std::default_delete<CANController> 
>::pointer __p, std::__uniq_ptr_impl<CANController, 
std::default_delete<CANController> > * const this) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/unique_ptr.h:211)
   std::unique_ptr<CANController, std::default_delete<CANController> 
>::reset(std::unique_ptr<CANController, std::default_delete<CANController> 
>::pointer __p, std::unique_ptr<CANController, 
std::default_delete<CANController> > * const this) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/unique_ptr.h:509)
   CANChannelManager::closeCAN(CANChannelManager * const this) 
(/home/mickey/Dokumente/late/ecos/firmware/main/CAN/CANChannelManager.cpp:143)
   CANChannelManager::~CANChannelManager(CANChannelManager * const this) 
(/home/mickey/Dokumente/late/ecos/firmware/main/CAN/CANChannelManager.cpp:28)
   std::default_delete<CANChannelManager>::operator()(const 
std::default_delete<CANChannelManager> * const this, CANChannelManager * __ptr) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/unique_ptr.h:99)
   std::unique_ptr<CANChannelManager, std::default_delete<CANChannelManager> 
>::~unique_ptr(std::unique_ptr<CANChannelManager, 
std::default_delete<CANChannelManager> > * const this) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/tuple:125)
   ProtocolMachine::~ProtocolMachine(ProtocolMachine * const this) 
(/home/mickey/Dokumente/late/ecos/firmware/main/ProtocolMachine/ProtocolMachine.cpp:28)
   std::default_delete<ProtocolMachine>::operator()(const 
std::default_delete<ProtocolMachine> * const this, ProtocolMachine * __ptr) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/unique_ptr.h:99)
   std::__uniq_ptr_impl<ProtocolMachine, std::default_delete<ProtocolMachine> 
>::reset(std::__uniq_ptr_impl<ProtocolMachine, 
std::default_delete<ProtocolMachine> >::pointer __p, 
std::__uniq_ptr_impl<ProtocolMachine, std::default_delete<ProtocolMachine> > * 
const this) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/unique_ptr.h:211)
   std::unique_ptr<ProtocolMachine, std::default_delete<ProtocolMachine> 
>::reset(std::unique_ptr<ProtocolMachine, std::default_delete<ProtocolMachine> 
>::pointer __p, std::unique_ptr<ProtocolMachine, 
std::default_delete<ProtocolMachine> > * const this) 
(/home/mickey/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/xtensa-esp-elf/include/c++/13.2.0/bits/unique_ptr.h:509)
   L2CAPServiceCallbacks::onDisconnect(L2CAPServiceCallbacks * const this, 
NimBLEL2CAPService * pService) 
(/home/mickey/Dokumente/late/ecos/firmware/main/Bluetooth/L2CAPServiceCallbacks.cpp:73)
   NimBLEL2CAPService::handleDisconnectionEvent(NimBLEL2CAPService * const 
this, ble_l2cap_event * event) 
(/home/mickey/Dokumente/late/ecos/esp-nimble-cpp/src/NimBLEL2CAPService.cpp:164)
   ```
   
   I tried to workaround this, but I have no chance of getting to the `conn`, 
since the `ble_l2cap_chan` is a private structure.
   
   What options do I have?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to