android - JNI - SIGSEGV 信号 SIGSEGV:在工作线程中时地址无效
问题描述
我有一个来自 android 的 JNI 调用,我在其中发送数据(字节、宽度和高度)以进行图像处理。从主 android 线程执行时,该函数工作正常。我想从另一个线程调用,以避免阻塞 UI,但是当我这样做时,JNI 会引发内存错误。如果我从主线程调用,工作正常。
该错误是从env->GetIntArrayRegion(...)引发的。
extern "C"
JNIEXPORT jobjectArray JNICALL
Java_topcodes_TopCodesScanner_searchTopCodesNative(JNIEnv *env, jobject thiz, jint image_width,
jint image_height, jintArray image_data) {
auto image_data_size = env->GetArrayLength(image_data);
jint image_data_buf[image_data_size];
// error in this line
env->GetIntArrayRegion(image_data, 0, image_data_size, image_data_buf);
我创建新线程的方式是这样的:
private val executorService by lazy { Executors.newFixedThreadPool(4) }
override fun analyze(image: ImageProxy) {
executorService.submit { // if comment, works fine
try {
val blocks = findBlocks(image)
handler.post { listener(blocks); }
} finally {
image.close()
}
} // if comment, works fine
}
这是堆栈跟踪。
memcpy 0x0000007f8f938d9c
art::JNI::*GetIntArrayRegion(_JNIEnv, _jintArray*, int, int, int*) 0x0000007f8bddcea0
art::CheckJNI::GetPrimitiveArrayRegion(char const*, art::Primitive::Type, _JNIEnv*, _jarray*, int, int, void*) 0x0000007f8bbf07fc
<unknown> 0x0000007f750c0aec
<unknown> 0x0000007f750c0708
topcodes.TopCode[] topcodes.TopCodesScanner.searchTopCodesNative(int, int, int[]) 0x0000007f7844218c
art_quick_invoke_stub 0x0000007f8bbb6ca8
art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x0000007f8bbc5b80
artInterpreterToCompiledCodeBridge 0x0000007f8bf64574
bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x0000007f8bd3fc48
art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue) 0x0000007f8bb76e44
art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*) 0x0000007f8bd1d9c4
artQuickToInterpreterBridge 0x0000007f8bfd4944
art_quick_to_interpreter_bridge 0x0000007f8bbc0a28
<unknown> 0x0000007f8bbc0b90
我搜索过类似的问题。提前致谢。
解决方案
auto image_data_size = env->GetArrayLength(image_data);
jint image_data_buf[image_data_size];
如果您在编译时不知道大小,请不要创建 C 样式的数组。
请参阅:为什么 C++ 允许非动态分配的可变长度数组?
改为使用std::vector<jint> image_data_buf(image_data_size)
。
推荐阅读
- java - 供应 id 的 Java 返回文章库
- python - 如何在jupyter笔记本中执行eof
- python - 用python将句子列表拆分为单词列表
- java - 切换按钮元素消失但动画完成后突然重新出现
- java - 如何将字符串值转换为数字
- c++ - 如何在我的代码中找到(并删除)需要管理员权限的位置?
- google-sheets - 使工作表在指定单元格中输入行号
- laravel - 我最近在我的 laravel 项目中使用了 JCrop,但是虽然我选择了一张照片并加载了它,但我得到了验证错误 image is requred
- material-ui - const primary = red[500]; 之间有什么不同?// #F44336 const 重音 = red['A200']; // #F44336?
- laravel - 带有 laravel 框架的推荐系统