簡體   English   中英

Android NDK-致命信號11(SIGSEGV)僅在設備上

[英]Android NDK - Fatal signal 11 (SIGSEGV) on device only

我的應用程式發生了一個非常奇怪的問題。 首先,我的應用程序是測試NDK的能力,以使用MatLab自動生成的庫來處理一些原始音頻數據。 該算法非常簡單。

我的C庫是通過MatLab代碼自動生成的,我進行了必要的更改以使其可以與C一起使用。該代碼在模擬器中可以正常運行,但是當我在Nexus 4設備上運行該應用程序時,它有時崩潰了,這給了我SIGSEGV致命錯誤。

這是我的C代碼:

JNIEXPORT jshortArray JNICALL Java_com_test_audiocapteffect_MainActivity_addeffects
(JNIEnv* env, jobject thiz, const jshortArray input, int32_T SampleRate, int32_T sizeofx) {
__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Creating/Getting Array Elements");
jshort* x = (*env)->GetShortArrayElements(env, input, 0);
//int16_T* x = (int16_T*)j_input;
jshortArray output;
output = (jshortArray)((*env)->NewShortArray(env, sizeofx));
jshort* y = (*env)->GetShortArrayElements(env, output, 0);
//int16_T* y = (int16_T*)j_output;

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Creating variables");
emxArray_real_T *temp;
uint32_T b_y;
int32_T i;
int32_T loop_ub;
int16_T iv0[sizeofx];
real_T thresh;
uint32_T delayedindex;
emxInit_real_T(&temp, 1);
b_y = (uint32_T)rt_roundd(0.3 * (real_T)SampleRate);

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Filling y with zeros");
for(i = 0; i<sizeofx; i++) {
    y[i] = 0;
}

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 1");
/* add distortion */
/* distortion function */
i = temp->size[0];
temp->size[0] = sizeofx;
emxEnsureCapacity((emxArray__common *)temp, i, (int32_T)sizeof(real_T));

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 2");
// get the absolute values of each element
for (i = 0; i < sizeofx; i++) {
    iv0[i] = b_abs(x[i]);
}

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 3");
thresh = 1.2 * mean(iv0, sizeofx);
for (i = 1; i <= sizeofx; i = (int32_T)((uint32_T)i + 1U)) {
    if ((real_T)x[(int32_T)(uint32_T)i - 1] > thresh) {
        temp->data[(int32_T)(uint32_T)i - 1] = thresh;
    } else if ((real_T)x[i - 1] < -thresh) {
        temp->data[(int32_T)(uint32_T)i - 1] = -thresh;
    } else {
        temp->data[(int32_T)(uint32_T)i - 1] = (real_T)x[i - 1];
    }
}


__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding delay part 1");
/* add delay */
/* delay function */
/* modified by Thomas Horta */    
for (i = 1; i <= sizeofx; i = (int32_T)((uint32_T)i + 1U)) {
    delayedindex = (uint32_T)i - b_y;
    if (1U < delayedindex) {
    } else {
        delayedindex = 1U;
    }
    if (i==1) {
        __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding delay part 2");
    }
    if ((uint32_T)i - b_y < 1U) {
        y[(int32_T)(uint32_T)i - 1] = (int16_T)(temp->data[(int32_T)(uint32_T)i - 1]);
    } else {
        y[(int32_T)(uint32_T)i - 1] = (int16_T)(temp->data[(int32_T)(uint32_T)i - 1] +
        0.3 * temp->data[(int32_T)delayedindex - 1]);
    }
}

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Freeing resources");
emxFree_real_T(&temp);

(*env)->ReleaseShortArrayElements(env, input, x, 0);
(*env)->ReleaseShortArrayElements(env, output, y, 0);

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Returning output");
return output;  }

當函數到達我的日志輸出消息為“ NDK:Adding delay part 2”的部分(填充輸出數組的循環)時,發生我的錯誤。

編輯:這是emxArray結構:(它也是由Matlab自動生成的)

typedef struct emxArray_real_T
{
    real_T *data;
    int32_T *size;
    int32_T allocatedSize;
    int32_T numDimensions;
    boolean_T canFreeData;
} emxArray_real_T;

由於MatLab約定,變量類型具有那些奇怪的名稱,但它們只是變量類型的typedef。 即使它們只是typedef,我認為該錯誤也可能是由於將類型轉換為int16_T (在Java等效項中為doubleshort

我的LogCat顯示以下內容:

06-06 15:36:12.382: I/AudioCaptEffect(2503): Add effects to the audio
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Creating/Getting Array Elements
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Creating variables
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Filling y with zeros
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Adding distortion part 1
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Adding distortion part 2
06-06 15:36:12.382: D/NDK_SimpleCApp(2503): NDK: Adding distortion part 3
06-06 15:36:12.392: D/NDK_SimpleCApp(2503): NDK: Adding delay part 1
06-06 15:36:12.392: D/NDK_SimpleCApp(2503): NDK: Adding delay part 2
06-06 15:36:12.392: A/libc(2503): Fatal signal 11 (SIGSEGV) at 0x72905a08 (code=1), thread 2769 (Thread-15238)

有誰知道為什么會這樣嗎? 最奇怪的是,這種情況僅發生在Nexus 4(我必須測試的只有Android設備)上,並且在大多數情況下都是運行該應用程序(並非所有時間)。

我解決了這個問題,但是並不太清楚為什么會這樣發生,因為有時它會起作用,有時卻不會(完全隨機)。

如您所見,我使用了一些無符號的int變量,因為MatLab以此方式創建了代碼,與Java一起使用時,由於Java沒有無符號的變量,因此使一切變得更加困難並且容易出錯。

所以基本上我所做的就是告訴MatLab編碼器我所有的變量都被簽名並再次生成代碼,然后我只是用生成的新代碼的一部分(沒有任何uint_16_T變量)替換了舊代碼的一部分(在問題中)。

現在,該應用程序在模擬器和設備上均可正常運行。 我測試了許多具有不同大小和采樣率的不同輸入,該應用程序再也沒有崩潰。

對於那些感興趣的人,新代碼是:

JNIEXPORT jshortArray JNICALL Java_com_test_audiocapteffect_MainActivity_addeffects
(JNIEnv* env, jobject thiz, const jshortArray input, int32_T SampleRate, int32_T sizeofx) {

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Creating/Getting Array Elements");
jshort* x = (*env)->GetShortArrayElements(env, input, 0);
//int16_T* x = (int16_T*)j_input;
jshortArray output;
output = (jshortArray)((*env)->NewShortArray(env, sizeofx));
jshort* y = (*env)->GetShortArrayElements(env, output, 0);
//int16_T* y = (int16_T*)j_output;

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Creating variables");
emxArray_real_T *temp;
int32_T b_y;
int32_T i;
int16_T iv0[sizeofx];
real_T thresh;
uint32_T delayedindex;
emxInit_real_T(&temp, 1);
b_y = (int32_T)rt_roundd(0.3 * (real_T)SampleRate) - 1;

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Filling y with zeros");
for(i = 0; i<sizeofx; i++) {
    y[i] = 0;
}

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 1");
/* add distortion */
/* distortion function */
i = temp->size[0];
temp->size[0] = sizeofx;
emxEnsureCapacity((emxArray__common *)temp, i, (int32_T)sizeof(real_T));

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 2");
// get the absolute values of each element
for (i = 0; i < sizeofx; i++) {
    iv0[i] = b_abs(x[i]);
}

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding distortion part 3");
thresh = 1.2 * mean(iv0, sizeofx);
for (i = 0; i + 1 <= sizeofx; i++) {
    if ((real_T) x[i] > thresh) {
        temp->data[i] = thresh;
    } else if ((real_T) x[i] < -thresh) {
        temp->data[i] = -thresh;
    } else {
        temp->data[i] = (real_T) x[i];
    }
}


__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding delay part 1");
/* add delay */
/* delay function */
/* modified by Thomas Horta */    
for (i = 0; i <= sizeofx - 1; i++) {
    delayedindex = i - b_y;
    if (1 < delayedindex) {
    } else {
        delayedindex = 1;
    }

    if (i==1) {
        __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Adding delay part 2");
    }

    if (i - b_y < 1) {
        y[i] = temp->data[i];
    } else {
        y[i] = temp->data[i] + 0.35 * temp->data[delayedindex - 1];
    }
}

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Freeing resources");

emxFree_real_T(&temp);
(*env)->ReleaseShortArrayElements(env, input, x, 0);
(*env)->ReleaseShortArrayElements(env, output, y, 0);

__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: Returning output");
return output;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM