android - 仅某些设备中的Android/NDK SIGILL错误

标签 android crash android-ndk

在Android / NDK下,我正在使用下一个算法将RGB转换为YUV420sp。我开始收到一些用户的少量崩溃报告。因此,在他们将日志发送给我之后,所有的似乎都在我发表评论时在下一个算法中失败,就在第二个算法 encodeARGB888_YUV420sp ,日志显示了 SIGILL 错误,我发现它存在下一个定义:

Illegal Instruction (ANSI) Generally indicates that the executable file is corrupted or use of data where a pointer to a function was expected.



这些报告全部来自SGSII-skyrocket和Rogers变体,以及Samsung Captivate Glide。而且并非全部,因为其他使用这些设备的用户也表示完全没有问题。

这些设备的硬件是否有特定的东西?还是任何已知的错误?还是我在代码中做错了什么?
JNIEXPORT void JNICALL Java_com_test_NatLib_decodeBitmapToYuv420sp(JNIEnv *env, jobject javaThis, jobject bitmap, jbyteArray yuv)
{
    AndroidBitmapInfo bitmapInfo;
    int code;
    void *nativeRGBPixels;

    if ((code = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo)) < 0)
    {
        return;
    }

    if ((code = AndroidBitmap_lockPixels(env, bitmap, (void**)&nativeRGBPixels)) < 0)
    {
        return;
    }

    char *nativeYuvPixels = (char*)env->GetByteArrayElements(yuv, 0);

    decodeARGB888_YUV420sp(nativeRGBPixels, nativeYuvPixels, bitmapInfo.width, bitmapInfo.height);

    env->ReleaseByteArrayElements(yuv, (jbyte*)nativeYuvPixels , 0);
    AndroidBitmap_unlockPixels(env, bitmap);
}

static void decodeARGB888_YUV420sp(const int *argb, char *yuv, const int width, const int height)
{
    const int totalPixels = width * height;
    int indexPixel = 0;
    int indexY = 0;
    int indexUV = totalPixels;
    int R, G, B, Y, U, V;
    int x, y;

    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {

//--------------------------------------------------------------------
// AT THIS POINT IS WHERE THE LAST LOG WITH SIGILL WAS CAPTURED
//--------------------------------------------------------------------

            const int pixelValue = argb[indexPixel];

            R = pixelValue & 0xff;
            G = (pixelValue & 0xff00) >> 8;
            B = (pixelValue & 0xff0000) >> 16;

            // RGB to YUV algorithm for component Y
            Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;

            // NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2 meaning for
            // every 4 Y pixels there are 1 V and 1 U. Note the sampling is every other pixel AND every other scanline
            yuv[indexY++] = (char)((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));

            if (y % 2 == 0 && indexPixel % 2 == 0)
            {
                // RGB to YUV algorithm for component U & V
                U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
                V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

                yuv[indexUV++] = (char)((V < 0) ? 0 : ((V > 255) ? 255 : V));
                yuv[indexUV++] = (char)((U < 0) ? 0 : ((U > 255) ? 255 : U));
            }

            indexPixel++;
        }
    }
}

最佳答案

由于它与SIGILL有关,因此可能是您在丢失env,它的值变得乱码,并且处理器在内存中执行了一些不是指令(text)而是data的区域。这是因为跳转目标是根据env实例计算的。

您可以阅读JNI Tips以获得有关env用法的一些指针。

关于android - 仅某些设备中的Android/NDK SIGILL错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17137089/

相关文章:

Android如何使用libjpeg-turbo库

Android - 触摸通知时提示对话框窗口

android - 将数组列表设置为微调器的方法

ios - 当我反向导航 UITableViewController 时应用程序崩溃,为什么?

excel - #xslt #C++ Excel 在打印预览时突然崩溃

ios - 即使我有正确的 .dSYM 文件,Xcode 也无法符号化我的崩溃日志

android - 将 C 代码转换为 JNI C 代码

java - IntentService 中的路由 Intent

android - 如何从协程返回 ArrayList?

android - NDK 位图操作使用 OpenCv 蓝色是橙色?