4

I am developing software for a commercial product that runs on a Moxa MPC-2070 panel computer (Intel Atom based) under Debian 10 (Buster) with BlueZ (5.50) bluetooth support. The application has been developed using Qt Creator. I have been struggling to find a robust and reliable method to scan for Bluetooth Low Energy devices.

Because of an extreme performance problem associated with the QBluetoothDiscoveryAgent::start() method in Qt (which I won't go into here), I am using the bluetoothctl command to perform BLE device scanning. A wrapper around bluetoothctl provides it with input commands and parses the output from bluetoothctl. Sporadically (once every 1 - 150 times) that I launch bluetoothctl to perform the BLE scan, the bluetooth daemon process (bluetoothd) crashes with a SIGSEGV.

Here is the tail of syslog after the bluetoothd crash:

[315398.536280] show_signal_msg: 8 callbacks suppressed
[315398.536293] bluetoothd[523]: segfault at a8ec8148fd ip 00007f681ba3e143 sp 00007ffc8110a858 error 4 in libdbus-1.so.3.19.11[7f681ba2f000+2e000]
[315398.536343] Code: 85 ed 74 13 0a 18 88 18 48 83 c4 08 5b 5d c3 0f 1f 84 00 00 00 00 00 f7 d3 22 18 88 18 48 83 c4 08 5b 5d c3 0f 1f 00 48 8b 07 <0f> b6 40 02 85 f0 0f 
95 c0 0f b6 c0 c3 55 48 89 fd 53 89 f3 48 83

I have restarted bluetoothd with the -d flag to enable debug output via: $ sudo bluetoothd -d &

And again ran the bluetoothctl scans in a loop until bluetoothd again crashed. The full syslog showing the bluetoothd crash can be found here: Complete syslog with bluetoothd SIGSEGV

In the above syslog, the initial bluetoothd (without -d) crash can be found at Jan 14 09:58:55.
The restart of bluetoothd with the -d flag is at Jan 14 10:03:16.
The looping use of bluetoothctl begins at Jan 14 10:06:03.
bluetoothd again SIGSEGVs at Jan 14 10:05:13.

Sometimes the bluetoothd crashes happen after only 1 or 2 bluetoothctl commands, and other times it takes many iterations before the crash occurs.

This shell script will reproduce the bluetoothd crash. It loops performing essentially the same function as my C bluetoothctl wrapper program, but without the bluetoothctl output processing. Note that this script must be run as root or by a user id which is a member of the 'bluetooth' group.

#! /bin/bash
COUNT=0
RESULT=0
while [ "${RESULT}" != "9" ]
    do
    COUNT=`expr ${COUNT} + 1`
    echo "Loop #${COUNT}"
    # uveTagScanner -s FEA0 ${@}     # The compiled bluetoothctl wrapper program with output processing
    # RESULT="$?"

    ( echo "menu scan"             # Enter the bluetoothctl scan sub-menu 
    echo "clear"                     # Clear all filter parameters
    echo "transport le"              # Filter scanning for low-energy devices only
    echo "duplicate-data off"        # Disable reporting of duplicate-data
    echo "back"                      # Exit the bluetoothctl scan sub-menu & return to main menu
    echo "scan on"                   # Start scanning for LE devices
    sleep 10                         # Let scanning proceed for 10 seconds
    echo "scan off"                  # Stop scanning for LE devices
    echo "quit"                      # Quit the bluetoothctl command
        ) | bluetoothctl
done

Within my C wrapper program (uveTagScanner) which fork()/exec()s bluetoothctl and performs the output processing, I am able to detect if bluetoothd has crashed and then restart it. But this is only a band-aid solution, as it still leaves me with instances where the scanning for BLE devices does not provide the needed information.

I'm running out of ideas on how to reliably perform BLE device scanning! I could try using the BlueZ libraries and Dbus interface APIs instead of bluetoothctl, but I fear that the same bluetoothd crash would occur.

0 Answers0