【问题标题】:fatal signal 11 SIGSEGV when closing BluetoothSocket on Android 4.2.2 and 4.3在 Android 4.2.2 和 4.3 上关闭 BluetoothSocket 时出现致命信号 11 SIGSEGV
【发布时间】:2013-08-11 11:00:25
【问题描述】:

我的应用程序在 Android 2.3.3 到 4.1.2 下运行良好,但是从 Android 4.2.2 和 Android 4.3 开始,我有一个

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

当我关闭蓝牙插座时。

我搜索了很多论坛,主要的反应是

BluetoothSocket.close();

同时从两个不同的线程调用,但在我的代码中并非如此。

我在 A4.1.2 下使用三星 Galaxy Note 2(工作正常),在 A4.2.2 和 4.3 下使用 Nexus 4。

提前感谢您的建议!

编辑 1:这里有 2 个操作蓝牙套接字的线程。

第一个:

    /**
 * 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);
        }
    }
}

第二个:

    /**
 * 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);
        }
    }
}

编辑 2:我尝试仅使用一个线程来确保无法并行访问

BluetoothSocket

但结果完全一样。只要我打电话

BluetoothSocket.close();

我收到致命信号 11,应用程序崩溃。

【问题讨论】:

  • 您是否有权访问操纵套接字的线程或者您知道它在哪里被操纵?
  • 是的,我可以访问操纵 BluetoothSocket 的两个线程。它们都是在我用于蓝牙连接管理的类中创建的私有线程。
  • 那么也许你也应该同步它们。他们可能不在 UI 线程,但可以访问公共资源。让它们互相检查进度以避免此类冲突或准备第三个线程,该线程仅用于监视这两个先前的线程并管理它们使用的资源。
  • 我检查了 Eclipse DDMS 线程监控,但它们从未并行运行。 ConnectedThread 只有在 ConnectThread 停止后才会启动。
  • 通读并返回结果 -> stackoverflow.com/questions/1083154/…。我知道我很讨厌,但问题也是如此。 :(

标签: android eclipse sockets bluetooth nexus-4


【解决方案1】:

我也遇到了这个问题。然而,对我来说close() 并不是原因。问题是在close() 之后访问套接字。具体来说,在套接字关闭后对套接字输入流上的available() 的调用导致了段错误。

【讨论】:

  • 非常感谢@markrileybot 的回答。这解决了我在Android 4.4.2 版本的Grand 2 设备中的问题。我在回答stackoverflow.com/a/29529974/1994950 中添加了更多细节并提到了你的帮助。 . 再次感谢您
【解决方案2】:

我遇到了完全相同的问题。在关闭套接字调用之前它对我有帮助

mConnectedThread.interrupt()

从外部类,并添加到 ConnectedThread run() 方法

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

确保线程不会从套接字的流中读取任何内容。之后你可以调用 mmSocket.close()

【讨论】:

    【解决方案3】:

    我在Galaxy Grand 2 设备中遇到了与 Android 4.4.2 相同的问题

    我在@markrileybot answer 的回答的帮助下解决了这个问题

    close() 调用由我的代码完成后,我正在访问socket.available() 方法。

    要向@markrileybot 答案添加更多内容:

    在调用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如果您在multiple threads 之间共享同一个套接字,则应添加此条件,以防止在套接字已关闭时调用close() (not connected)

    2在调用socket.available()socket.write()之前,我们应该检查socket.isConnected(),如果它返回true,那么只有我们应该进一步处理

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多