Fatal 11 SIGSEGV signal when closing BluetoothSocket on Android 4.2.2 and 4.3

My application worked fine under Android 2.3.3 to 4.1.2, but with Android 4.2.2 and Android 4.3 I have

fatal signal 11 (SIGSEGV) at 0x00.... 

when i close the bluetooth jack.

I go through many forums and the main answer is that

 BluetoothSocket.close(); 

called from two different threads at the same time, but this is not the case in my code.

I use Samsung Galaxy Note 2 under A4.1.2 (working fine) and Nexus 4 for A4.2.2 and 4.3.

Thanks in advance for your suggestions!

EDIT 1: here are 2 streams that control the Bluetooth jack.

the first:

  /** * This thread runs while attempting to make an outgoing connection with a * device. It runs straight through; the connection either succeeds or * fails. */ private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; //private final UUID MY_UUID = java.util.UUID.randomUUID(); public ConnectThread(BluetoothDevice device) { if(D) Log.d(TAG, "/S4B/ start connectThread "); mmDevice = device; BluetoothSocket connection = null; // Get a BluetoothSocket for a connection with the given BluetoothDevice try { if(D) Log.i(TAG,"/S4B/ Create RF Socket"); Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); connection = (BluetoothSocket) m.invoke(device, 1); //connection = device.createRfcommSocketToServiceRecord(MY_UUID); Utils.pause(100); } catch (Exception e) { Log.e(TAG, "/S4B/ create() failed", e); } mmSocket = connection; if(D) Log.i(TAG,"/S4B/ Socket initialized"); } public void run() { if(D) Log.i(TAG, "/S4B/ BEGIN mConnectThread"); setName("ConnectThread"); if (mmSocket != null) { // Always cancel discovery because it will slow down a connection if(mAdapter.isDiscovering()){ mAdapter.cancelDiscovery(); } // Make a connection to the BluetoothSocket try { // This is a blocking call and will only return on a successful connection or an exception if(D) Log.i(TAG,"/S4B/ Start socket connection"); mmSocket.connect(); if(D) Log.i(TAG,"/S4B/ End of socket connection"); } catch (Exception e) { Log.e(TAG, "/S4B/ socket connect failed", e); // Close the socket try { mmSocket.close(); if(D) Log.i(TAG,"/S4B/ close socket"); } catch (IOException e2) { Log.e(TAG,"/S4B/ unable to close() socket during connection failure",e2); } //Turn off the bluetooth - the Bluetooth STATE_OFF Broadcast will be received in welcome.class connectionFailed(); return; } // Reset the ConnectThread because we're done synchronized (BluetoothConnectionService.this) { mConnectThread = null; } // Start the connected thread connected(mmSocket, mmDevice); } else { BluetoothConnectionService.this.start(); connectionFailed(); } } public void cancel() { try { if (mmSocket != null) { mmSocket.close(); } } catch (IOException e) { Log.e(TAG, "/S4B/ close() of connect socket failed", e); } } } 

and second:

  /** * This thread runs during a connection with a remote device. It handles all * incoming and outgoing transmissions. */ private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final DataInputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { Log.d(TAG, "/S4B/ Create ConnectedThread"); mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the BluetoothSocket input and output streams try { if(D) Log.i(TAG,"/S4B/ Get input and output stream"); tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); isConnected = true; } catch (IOException e) { Log.e(TAG, "/S4B/ Temp sockets not created", e); isConnected = false; } mmInStream = new DataInputStream(tmpIn); mmOutStream = tmpOut; } public void run() { setName("ConnectedThread"); Log.i(TAG, "/S4B/ BEGIN mConnectedThread"); while (isConnected) { Utils.pause(50); isConnected = checkConnection(); } } /** * Check if the connection is still alive * * @return true or false */ private boolean checkConnection() { synchronized (mmInStream) { try { int len = mmInStream.available(); if (len > 0) {// Checks the available amount byte b[] = new byte[len]; if(D) Log.i(TAG,"/S4B/ start mmInStream readFully"); mmInStream.readFully(b, 0, len); mHandler.obtainMessage(MESSAGE_READ, len, -1, b).sendToTarget(); } return true; } catch (IOException ioe) { Log.e(TAG, "/S4B/ check connection, disconnected", ioe); connectionLost(); return false; // Connection is lost. } } } /** * Write to the connected OutStream. * * @param buffer * The bytes to write */ public void write(byte[] buffer) { try { mmOutStream.write(buffer); } catch (IOException e) { Log.e(TAG, "/S4B/ Exception during write", e); connectionLost(); return; } // Share the sent message back to the UI Activity mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); } public void cancel() { try { mmSocket.close(); Utils.pause(1000); } catch (IOException e) { Log.e(TAG, "/S4B/ close() of connect socket failed", e); } } } 

EDIT 2: I tried to use only one thread to make sure that in parrallel there is no access to

 BluetoothSocket 

but the result is exactly the same. As soon as i call

 BluetoothSocket.close(); 

I get a fatal signal 11 and the application crashes.

+4
source share
3 answers

I ran into this problem. However, close() not the reason for me. The problem was socket access after close() . In particular, calling available() on the socket input stream after closing the socket called segfault.

+7
source

I had the same problem. This helped me before closing the socket call

mConnectedThread.interrupt()

from an external class and the ConnectedThread run () add method

 public void run() { ... while (condition) { if (isInterrupted()) return; ... } ... } 

so that the stream does not read anything from the socket stream. After that you can call mmSocket.close ()

+5
source

I had the same issue with Android 4.4.2 in Galaxy Grand 2 device

I fixed the problem with @markrileybot answer answer

I accessed the socket.available() method after calling close() my code.

To add another answer to @markrileybot:

I also added a condition before calling socket.close() :

 public void cancel() { try { if(mmSocket.isConnected()) // this is condition mmSocket.close(); Utils.pause(1000); } catch (IOException e) { Log.e(TAG, "/S4B/ close() of connect socket failed", e); } } 

1 If you use the same socket between multiple threads , then this condition must be added, which will prevent close() from being called if the socket is already closed ( not connected )

2 Before calling socket.available() or socket.write() we must check socket.isConnected() , and if it returns true , then we must continue processing

+4
source

Source: https://habr.com/ru/post/1496151/


All Articles