Perraco
Perraco

Reputation: 17360

Android/NDK SIGILL error in only some devices

Under Android/NDK, I am using the next algorithm to convert from RGB to YUV420sp. I started to have a small amount of crash reports from some users. So after they sent me the logs, all seemed to fail in the next algorithm at the point I market with a comment, right at the second algorithn decodeARGB888_YUV420sp, the logs show a SIGILL error, which I found it has the next definition:

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

The reports all come from the SGSII-skyrocket and Rogers variants, and the Samsung Captivate Glide. And not in all of them, as some other users with these devices also reported no problems at all.

Is there something specific with these devices hardware? Or any known bug? Or am I doing something wrong in my code?

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++;
        }
    }
}

Upvotes: 0

Views: 2027

Answers (2)

avish
avish

Reputation: 82

@Zhenya, I think that the actual solution should be different. You probably have in your Android.mk something like:

#ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
   LOCAL_ARM_NEON := true
#endif

This is WRONG. armeabi-v7a does not necessarily imply NEON (eg, Tegra2 chipset). Instead the check for NEON optimized code should always be a runtime check, and you can find documentation within the NDK on how to do that.

Upvotes: 0

auselen
auselen

Reputation: 28087

Since it is about SIGILL it is probably you are loosing env, its values goes garbage and processor executes some area in memory which is not instructions (text) but data. That's because jump target is calculated over env instance.

You can read JNI Tips to get some pointers aroudn env usage.

Upvotes: 1

Related Questions