gpt4 book ai didi

java - 线程中 SetDoubleArrayRegion 上的 JNI SIGSEGV

转载 作者:行者123 更新时间:2023-12-02 11:21:41 25 4
gpt4 key购买 nike

我试图在单独的线程中从 Java 调用以下函数:

extern "C" JNIEXPORT jdoubleArray

JNICALL
Java_de_bastian_sip2labor_MainActivity_filtertest(JNIEnv *env, jobject, jdoubleArray ka)
{
double b_y1[121];
int k;
int j;
static const double dv0[12] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.65 };

jdouble *sig1;
sig1=env->GetDoubleArrayElements(ka, 0);


memset(&b_y1[0], 0, 121U * sizeof(double));
for (k = 0; k < 12; k++) {
for (j = k; j + 1 < 122; j++) {
b_y1[j] += dv0[k] * sig1[j - k];
}
}

env->ReleaseDoubleArrayElements(ka,sig1,JNI_ABORT);

jdoubleArray output = env->NewDoubleArray( sizeof(b_y1) );
env->SetDoubleArrayRegion( output, 0, sizeof(b_y1), &b_y1[0] );

return output;
}

它是一个过滤器,它接受一个 double 组,对其进行修改,然后将其作为函数结果返回给 java。

应用程序在启动时崩溃,我认为是因为这一行:

env->SetDoubleArrayRegion( output, 0, sizeof(b_y1), &b_y1[0] );

我第一次遇到此问题时,它发生在调用 onPause() 之后,而调用该调用的单独线程可能仍在运行。因此我认为这与生命周期有关。在尝试执行 SetDoubleArrayRegion() 之前是否可以以某种方式检查 Activity 是否仍处于 Activity 状态,或者可能是另一个问题?

奇怪的是,直到最近,代码都运行良好:我开始读取一个文件,然后将其用作过滤器的输入。全新安装后首次启动应用程序时,它会要求用户授予文件读取权限。如果用户授予他们该应用程序工作正常,您可以看到过滤器输出。从那时起,当应用程序启动时,读取文件的权限已经被授予,并且应用程序尝试立即启动过滤器,然后它崩溃了。

简单的 logcat 输出:

A/libc: Fatal signal 11 (SIGSEGV), code 2, fault addr 0x89fa2830 in tid 8498 (Thread-5)

详细的 Logcat 输出:

#00 pc 0001a21e  /system/lib/libc.so (memcpy+46)
#01 pc 004394a6 /system/lib/libart.so (_ZN3art3JNI23SetPrimitiveArrayRegionIP13_jdoubleArraydNS_6mirror14PrimitiveArrayIdEEEEvP7_JNIEnvT_iiPKT0_+1174)
#02 pc 0041e87c /system/lib/libart.so (_ZN3art3JNI20SetDoubleArrayRegionEP7_JNIEnvP13_jdoubleArrayiiPKd+44)
#03 pc 0015c9d2 /system/lib/libart.so (_ZN3art8CheckJNI23SetPrimitiveArrayRegionEPKcNS_9Primitive4TypeEP7_JNIEnvP7_jarrayiiPKv+1474)
#04 pc 00144665 /system/lib/libart.so (_ZN3art8CheckJNI20SetDoubleArrayRegionEP7_JNIEnvP13_jdoubleArrayiiPKd+53)
#05 pc 00000e10 /data/app/de.bastian.sip2labor-FUb-fvR-Nwyxco0g-cmxow==/lib/x86/libsip2labor-lib.so (_ZN7_JNIEnv20SetDoubleArrayRegionEP13_jdoubleArrayiiPKd+160)
#06 pc 00000fcc /data/app/de.bastian.sip2labor-FUb-fvR-Nwyxco0g-cmxow==/lib/x86/libsip2labor-lib.so (Java_de_bastian_sip2labor_MainActivity_filtertest+428)
#07 pc 0063ec67 /system/lib/libart.so (art_quick_generic_jni_trampoline+71)
#08 pc 000049d3 /dev/ashmem/dalvik-jit-code-cache (deleted)

我在这里做错了什么?预先感谢您的努力。

最佳答案

在调用env->SetDoubleArrayRegion(output, 0, sizeof(b_y1), &b_y1[0] );时,您正在读取超过b_y1数组的末尾。/

sizeof(b_y1)

返回数组的大小(以字节为单位),而不是元素的数量。在我的平台上,这是 968,但您的 b_y1 只有 121 个元素,因此这是未定义的行为。

您可以通过传递121(数组的实际大小)而不是sizeof(b_y1)来解决此问题。但由于您使用的是 C++,我建议改用 std::array ,因为它会为您保留大小,并且通常具有更高级的 api:

std::array<double, 121> b_y1;
int k;
int j;
static const double dv0[12] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.65 };

jdouble *sig1;
sig1 = env->GetDoubleArrayElements(ka, 0);

b_y1.fill(0);
for (k = 0; k < 12; k++) {
for (j = k; j + 1 < 122; j++) {
b_y1[j] += dv0[k] * sig1[j - k];
}
}

env->ReleaseDoubleArrayElements(ka, sig1, JNI_ABORT);

jdoubleArray output = env->NewDoubleArray(b_y1.size());
env->SetDoubleArrayRegion(output, 0, b_y1.size(), b_y1.data());

return output;

关于java - 线程中 SetDoubleArrayRegion 上的 JNI SIGSEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49876590/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com