2017-04-14 78 views
1

我正在努力尋找Android Studio中原生C中發生的崩潰。如何調試Android Studio for Native C代碼的致命信號6崩潰?

我們知道錯誤來自本機C中的庫的位置。很可能來自垃圾處理程序。 我們試圖以不同的方式釋放變量,但沒有成功。 Android 5.0及更高版本的代碼工作的奇怪的部分。

我也用Google搜索如何在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) 
+0

你爲什麼只在'rgbDataSize Michael

+0

我會檢查。謝謝你的提示。 – Joseph

回答

1

我不是下的Android熟悉本機C,但我會努力:)

  • 宏MIN & MAX看起來很奇怪,不知道關於語法「({instr})」,它會被評估爲最後的指令嗎?爲什麼不使用更傳統的定義「MAX(a,b)((a)>(b)?(a):(b))」?它會招致3次評估而不是2次;但在任何情況下,MIN都以嵌套方式在代碼中使用,在這種情況下,使用普通函數可能更有效。

  • rgbData初始化爲堆棧變量TMP [6]將在如果塊結束之後被破壞,

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

    結果應檢查閹它是空的,它是否返回至少(w * h + w *(h/2)+ w)個字節的數組?通過訪問:

    v = (0xff & yuv[uvp++]) - 128; 
    u = (0xff & yuv[uvp++]) - 128; 
    
  • 是「寬度」和「高度」參數正確與問候位圖「YUV」的大小?

  • if(max != 0){ 
    

    將由 「增量」 分裂,這可能是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]); 
    

這是我能找到一個簡單的介紹一下更換。

+0

_「rgbData使用堆棧變量tmp [6]進行初始化,在if塊結束後將被銷燬」_不一定是這種情況。我沒有看過C標準說的是什麼,但是當我用clang編譯時,'tmp'的棧空間在進入函數時被保留,並且在函數離開之前可用(即,不僅在'if'聲明)。然而,當'rgbDataSize> = sz'時,'rgbData'未被初始化是一個潛在的問題。 – Michael

+0

@Michael你對rgbData的初始化是正確的。如果函數被多個線程調用,問題就會複雜化 –

+0

謝謝Ghazi,我們正在研究它。我們會關注你提到的幾點。如果我們找到了某些東西,我會讓你知道的。 – Joseph

相關問題