如何在Android Studio for Native C Code上调试致命信号6崩溃?

时间:2017-04-14 08:40:31

标签: c android-studio android-ndk

我正在努力寻找Android Studio中Native C中发生的崩溃。

我们知道错误源自Native C中的库。很可能来自垃圾处理程序。 我们试图以不同方式释放变量但尚未成功。奇怪的部分代码适用于Android 5.0及以上版本。

我还通过添加

来搜索如何在Android studio中调试NDK
Enable app debugging in your AndroidManifest.xml file by including an <application> element that sets the android:debuggable attribute to true.

并添加日志:

__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "The value R %f G %f B %f , H %f S %f V %f   ", rgbData[0], rgbData[1], rgbData[2], rgbData[3], rgbData[4], rgbData[5]);

但是,显示器仍然无法打印任何内容。在代码段和崩溃日志下面。

任何帮助都将受到高度赞赏。

#include <jni.h>

//#include <android/log.h>

#define APPNAME "handroid"

#define MAX(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })

#define MIN(a,b) \
    ({ __typeof__ (a) _a = (a); \
        __typeof__ (b) _b = (b); \
      _a < _b ? _a : _b; })


double* rgbData;
int rgbDataSize = 0;

JNIEXPORT
void
JNICALL
Java_handroid_classes_Camera_YUVtoRBGHSV(JNIEnv * env, jobject obj, jdoubleArray rgb_hsv, jbyteArray yuv420sp, jint width, jint height)
{
    int             sz;
    int             i;
    int             j;
    int             Y;
    int             Cr = 0;
    int             Cb = 0;
    int             pixPtr = 0;
    int             jDiv2 = 0;
    int             R = 0;
    int             G = 0;
    int             B = 0;
    double          tR = 0;
    double          tG = 0;
    double          tB = 0;
    int             cOff;
    int             w = width;
    int             h = height;
    sz = w * h;

    int pixel;
    int uvp;
    int y1192;
    int y;
    int v;
    int u;
    int yp;

    //for hsv
    double min, max, delta, hsv_h, hsv_s, hsv_v;

    jboolean isCopy;
    jbyte* yuv = (*env)->GetByteArrayElements(env, yuv420sp, &isCopy);

    if(rgbDataSize < sz) {
        double tmp[6];
        rgbData = &tmp[0];
        rgbDataSize = sz;
    }

    //Calculate pixel colors
    for (j = 0, yp = 0; j < h; j++) {
                uvp = sz + (j >> 1) * w, u = 0, v = 0;
                for (i = 0; i < w; i++, yp++) {

                            y = (0xff & yuv[yp]) - 16;
                            if (y < 0) y = 0;
                            if ((i & 1) == 0) {
                                v = (0xff & yuv[uvp++]) - 128;
                                u = (0xff & yuv[uvp++]) - 128;
                            }
                            y1192 = 1192 * y;
                            R = (y1192 + 1634 * v);
                            G = (y1192 - 833 * v - 400 * u);
                            B = (y1192 + 2066 * u);

                            if (R < 0) R = 0;
                            else if (R > 262143) R = 262143;
                            if (G < 0) G = 0;
                            else if (G > 262143) G = 262143;
                            if (B < 0) B = 0;
                            else if (B > 262143) B = 262143;


                            pixel = 0xff000000 | ((R << 6) & 0xff0000) | ((G >> 2) & 0xff00) | ((B >> 10) & 0xff);

                            tR += (pixel >> 16) & 0xff;
                            tG += (pixel >> 8) & 0xff;
                            tB += (pixel >> 0) & 0xff;

                }
            }


    //Create RGB sum (average pixel)
    rgbData[0] = (double)(tR/255/sz);
    rgbData[1] = (double)(tG/255/sz);
    rgbData[2] = (double)(tB/255/sz);

    //Calculate HSV
    min = MIN(rgbData[0], MIN(rgbData[1], rgbData[2]));
    max = MAX(rgbData[0], MAX(rgbData[1], rgbData[2]));
    hsv_v = max;
    delta = max - min;

    if( max != 0 ){
        hsv_s = delta / max;

        if( rgbData[0] == max )
            hsv_h = ( rgbData[1] - rgbData[2] ) / delta;
        else if( rgbData[1] == max )
            hsv_h=2+(rgbData[2]-rgbData[0])/delta;
        else
            hsv_h=4+(rgbData[0]-rgbData[1])/delta;
            hsv_h *= 60;

        if( hsv_h < 0 )
            hsv_h += 360;


        rgbData[3] = hsv_h;
        rgbData[4] = hsv_s;
        rgbData[5] = hsv_v;

    }else {
        // r = g = b = 0
        hsv_s = 0;
        hsv_h = -1;
        rgbData[3] = hsv_h;
        rgbData[4] = hsv_s;
        rgbData[5] = hsv_v;

    }

    //Log the data in Android
    //__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "The value R %f G %f B %f , H %f S %f V %f   ", rgbData[0], rgbData[1], rgbData[2], rgbData[3], rgbData[4], rgbData[5]);

    //Set RGB
    (*env)->SetDoubleArrayRegion(env, rgb_hsv, 0, 1, ( jdouble * ) &rgbData[0] );
    (*env)->SetDoubleArrayRegion(env, rgb_hsv, 1, 1, ( jdouble * ) &rgbData[1] );
    (*env)->SetDoubleArrayRegion(env, rgb_hsv, 2, 1, ( jdouble * ) &rgbData[2] );

    //Set HSV
    (*env)->SetDoubleArrayRegion(env, rgb_hsv, 3, 1, ( jdouble * ) &rgbData[3] );
    (*env)->SetDoubleArrayRegion(env, rgb_hsv, 4, 1, ( jdouble * ) &rgbData[4] );
    (*env)->SetDoubleArrayRegion(env, rgb_hsv, 5, 1, ( jdouble * ) &rgbData[5] );


    //Release the array data
    //(*env)->ReleaseByteArrayElements(env, yuv420sp, yuv, JNI_ABORT);
    (*env)->ReleaseByteArrayElements(env, yuv420sp, yuv, 0);
    //(*env)->ReleaseDoubleArrayElements(env, yuv420sp, yuv,rgbData,min,max,0);

}

崩溃日志

04-03 15:30:27.687 5547-5547/com.hlib E/dalvikvm: VM aborting
 04-03 15:30:27.687 5547-5547/com.hlib A/libc: Fatal signal 6 (SIGABRT) at 0x000015ab (code=-6), thread 5547 (it.hlib)

1 个答案:

答案 0 :(得分:1)

我不熟悉Android下的Native C,但我会尝试:)

  • 宏MIN&amp; MAX看起来非常奇特,不确定语法“({instr})”,它会被评估到最后一条指令吗?为什么不使用更传统的定义“MAX(a,b)((a)&gt;(b)?(a):( b))”?这将导致3次评估,而不是2次;但无论如何,MIN&amp; MAX以嵌套的方式在代码中使用,在这种情况下,使用普通函数可能更有效。

  • 使用堆栈变量tmp [6]初始化rgbData,该变量将在if块结束后销毁,

    if(rgbDataSize < sz) {
        double tmp[6];
        rgbData = &tmp[0];
        rgbDataSize = sz;
    }
    
  • 的结果
    jbyte* yuv = (*env)->GetByteArrayElements(env, yuv420sp, &isCopy);
    
    应检查

    是否为null,它是否返回至少(w * h + w *(h / 2)+ w)字节的数组?通过以下方式访问:

    v = (0xff & yuv[uvp++]) - 128; 
    u = (0xff & yuv[uvp++]) - 128;
    
  • 关于位图“yuv”的大小,“width”和“height”参数是否正确?

  • if( max != 0 ){
    

    将除以“delta”,可能为0.

  • 下一个块是否需要“{}”才能包含这两个指令?

    else
        hsv_h=4+(rgbData[0]-rgbData[1])/delta;
        hsv_h *= 60;
    
  • 似乎6个函数调用只能用1个调用替换

    <= (*env)->SetDoubleArrayRegion(env, rgb_hsv, 0, 1, ( jdouble * ) &rgbData[0] );
    => (*env)->SetDoubleArrayRegion(env, rgb_hsv, 0, 6, ( jdouble * ) &rgbData[0] );
    

这就是我能够简单地看出来的。