【Android】JNI报错 non-zero capacity for nullptr pointer分析

【Android】JNI报错 non-zero capacity for nullptr pointer分析

  • 背景
    某天,运行Android App时程序报错。

    Abort message: 'JNI DETECTED ERROR IN APPLICATION: non-zero capacity for nullptr pointer: 1
    in call to NewDirectByteBuffer
    from *****

  • 出错部分,调用了 NewDirectByteBuffer(原生JNI函数),创建了一块Buffer。pData是指针类型,dataSize是地址的大小。

cpp 复制代码
byteBuffer = env->NewDirectByteBuffer(pData, dataSize);

NewDirectByteBuffer对应的实现,在art/runtime/jni/jni_internal.cc中。实现如下。

cpp 复制代码
static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
if (capacity < 0) {
  JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
								   capacity);
  return nullptr;
}
if (address == nullptr && capacity != 0) {
  JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
								   "non-zero capacity for nullptr pointer: %" PRId64, capacity);
  return nullptr;
}

// At the moment, the capacity of DirectByteBuffer is limited to a signed int.
if (capacity > INT_MAX) {
  JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
								   "buffer capacity greater than maximum jint: %" PRId64,
								   capacity);
  return nullptr;
}
jlong address_arg = reinterpret_cast<jlong>(address);
jint capacity_arg = static_cast<jint>(capacity);

jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
								WellKnownClasses::java_nio_DirectByteBuffer_init,
								address_arg, capacity_arg);
return static_cast<JNIEnvExt*>(env)->self_->IsExceptionPending() ? nullptr : result;
}

通过分析上面代码,可以看出来。当传入的地址,不为NULL,且申请的Size大于0的时候。会报错non-zero capacity for nullptr

因为,既然申请一段空间,那么就不应该用非空的地址去申请。

  • 综上

对应到出问题的地方。排查pData为NULL或者dataSzie不为0的情况,即可解决该问题。

cpp 复制代码
byteBuffer = env->NewDirectByteBuffer(pData, dataSize);
相关推荐
摘星编程34 分钟前
【RAG+LLM实战指南】如何用检索增强生成破解AI幻觉难题?
android·人工智能
火柴就是我1 小时前
学习一些常用的混合模式之BlendMode. dst
android·flutter
遥不可及zzz1 小时前
解决 Google Play 提示的 16KB 内存页面大小对齐问题:通过升级 Android Gradle 插件(AGP)
android
SmartRadio2 小时前
在MT8791 5G硬件平台上舍弃安卓系统-运行OpenWRT系统
android·5g·mt8791
虫小宝2 小时前
导购APP高可用数据库设计:主从分离与分库分表在返利系统中的应用
android·数据库
我命由我123452 小时前
Android Jetpack Compose - TopAppBar、BottomAppBar、Scaffold
android·java·java-ee·kotlin·android studio·android jetpack·android-studio
REDcker3 小时前
Android WebView 升级 - WebViewUpgrade 库使用详解
android·华为·harmonyos·webview
我命由我123453 小时前
Android Studio - Android Studio 去除 import 的未使用的类
android·java·ide·学习·java-ee·android studio·学习方法
ii_best3 小时前
安卓/ios脚本开发辅助工具按键精灵横纵坐标转换教程
android·开发语言·ios·安卓
BD_Marathon3 小时前
SpringMVC——5种类型参数传递
android·java·数据库