【问题标题】:Android heap corruption on USB receiveUSB接收上的Android堆损坏
【发布时间】:2014-02-23 09:20:23
【问题描述】:

我正在尝试编写一个使用 USB 中断传输与 USB 设备通信的服务。基本上我在线程中阻塞 UsbConnection.requestWait() 以等待中断传输,然后使用意图将这些传递给活动。

当 USB 设备连续向我发送大量中断数据包(大约 50 个)时,我似乎遇到了问题。它有时会起作用,但通常应用程序会崩溃并显示这种风格的消息:

02-23 01:55:53.387: A/libc(8460): @@@ ABORTING: heap corruption detected by tmalloc_small
02-23 01:55:53.387: A/libc(8460): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 8460 (pf.mustangtamer)

malloc 调用并不总是失败,我见过几种 malloc(dlmalloc、malloc_small)和 dlfree。在每种情况下,我都会收到致命信号 11 和对 0xdeadbaad 的引用,因此我以某种方式破坏了堆。

从堆转储中看不出是什么导致了损坏。

这是我认为有问题的代码(仅在背靠背接收到许多数据包时才会出现问题):

    private class ReceiverThread extends Thread {

    public ReceiverThread(String string) {
        super(string);
    }

    public void run() {
        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);

        buffer.clear();
        UsbRequest inRequest = new UsbRequest();
        inRequest.initialize(mUsbConnection, mUsbEndpointIn);

        while(mUsbDevice != null ) {

            if (inRequest.queue(buffer, BUFFER_SIZE) == true) {
                // (mUsbConnection.requestWait() is blocking
                if (mUsbConnection.requestWait() == inRequest){
                    buffer.flip();
                    byte[] bytes = new byte[buffer.remaining()];
                    buffer.get(bytes);

                    //TODO: use explicit intent, not broadcast
                    Intent intent = new Intent(RECEIVED_INTENT);
                    intent.putExtra(DATA_EXTRA, bytes);
                    sendBroadcast(intent);
                } else{
                    Log.d(TAG, "mConnection.requestWait() returned for a different request (likely a send operation)");
                }
            } else {
                Log.e(TAG, "failed to queue USB request");
            }
            buffer.clear();
        }

        Log.d(TAG, "RX thread terminating.");
    }
}

现在活动没有消耗意图,我正在尝试让 USB 通信停止崩溃,然后再实施该端。

我没有看到上面的代码如何破坏堆,可能是通过一些非线程安全的行为。一次只有一个请求排队,所以我认为“缓冲区”是安全的。 我的目标是运行 JB 4.3.1 的平板电脑,如果这有影响的话。

【问题讨论】:

    标签: android usb heap-corruption


    【解决方案1】:

    我也没有发现这有什么问题。您可能想尝试从循环中删除代码,看看它是否仍会破坏堆以帮助您放大有问题的区域。

    请记住,堆操作通常会延迟,垃圾收集器不会立即运行,因此您可能会在其他地方破坏它,并且它只显示在此循环中,因为它非常密集。

    【讨论】:

    • 感谢您的建议,我一次删除了循环的内部,直到从缓冲区翻转到意图广播的所有内容,它仍然崩溃,尽管现在需要更长的时间。我认为你关于这个循环暴露问题但不一定创建它的观点是正确的。为您的答案 +1,但还不能使其成为公认的答案,因为我希望其他人会提出建议。
    【解决方案2】:

    通过在应用程序清单中设置 android:largeHeap="true" 尝试使用更大的堆大小。

    【讨论】:

    • 我会尝试一下,但我不会得到某种“堆外”消息而不是损坏的堆吗?我担心使用更大的堆会暂时掩盖问题但不能解决问题。
    • 更改堆大小没有影响,仍然以相同的方式崩溃
    • 这是因为 largeHeap 会影响 java 堆,而不是被损坏的本机堆。
    【解决方案3】:

    我会在评论中问这些问题,但可惜,没有足够的代表。

    我认为上面的代码没有任何问题,但我会检查以下内容:

    1. 什么是 BUFFER_SIZE?疯狂地,对于大于 15KB 的大小,我遇到了 非常 奇怪的 UsbRequest.queue() 问题。我很确定这不会导致您的堆损坏,但以后可能会导致奇怪。我不得不将我的请求分解为对 queue() 的多次调用以进行大量读取。

    2. 您使用的是批量 USB 端点吗?我不知道您的应用程序是什么,所以我不能确定您是否应该使用批量端点,但它是用于大型传输的端点类型。

    3. 最后,当我遇到这个 0xdeadbaad 问题(由 tmalloc_large 检测到)时,它与我认为有问题的代码(malloc 附近的代码)无关 - 这当然是一个线程问题,其中我让 JNI 本机代码在多个单独的线程上读取/写入相同的缓冲区!正如 user3343927 提到的那样,它只是在调用 malloc 时被检测到。

    【讨论】:

      猜你喜欢
      • 2010-11-15
      • 1970-01-01
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多