13
回答
android5.0以上版本调用jni崩溃
注册华为云得mate10,2.9折抢先购!>>>   
在Android调用这个接口总会出现Fatal signal 11 (SIGSEGV), code 1。。。错误

log如下:

02-29 20:34:12.302: E/Test(16577): Step1:Function:init_config_from_xml,type:8
02-29 20:34:12.302: E/Test(16577): Step4:InputBuf:
02-29 20:34:12.302: E/Test(16577): Step6:InputArray:
02-29 20:34:12.302: E/Test(16577): Step7:nCount:1
02-29 20:34:12.302: E/Test(16577): nLen:60,60,0,0,0
02-29 20:34:12.302: E/Test(16577): szData:0,8
02-29 20:34:12.302: E/Test(16577): malloc:0
02-29 20:34:12.302: E/Test(16577): pCurrentData=pInputData0
02-29 20:34:12.302: E/Test(16577): Step8:InputComplete
02-29 20:34:12.302: E/Test(16577): Step9:Output:0
02-29 20:34:12.302: E/Test(16577): Step10:DeleteLocalRef-inputBuf
02-29 20:34:12.302: E/Test(16577): Delete0
02-29 20:34:12.302: E/Test(16577): pTemp -519989872
02-29 20:34:12.302: E/Test(16577): pTemp nextNode 0
02-29 20:34:12.302: E/Test(16577): Delete1
02-29 20:34:12.302: E/Test(16577): Delete2
02-29 20:34:12.302: E/Test(16577): Delete3:-519989872
02-29 20:34:12.302: E/Test(16577): FreeParent
02-29 20:34:12.302: E/Test(16577): strFunction:-6926528---------190056080
02-29 20:34:12.302: E/Test(16577): Step12:FreeComplete
02-29 20:34:13.342: E/Test(16577): Step1:Function:init_config_from_xml,type:0
02-29 20:34:13.342: E/Test(16577): Step4:InputBuf:
02-29 20:34:13.342: E/Test(16577): Step6:InputArray:
02-29 20:34:13.342: E/Test(16577): Step7:nCount:1
02-29 20:34:13.342: E/Test(16577): nLen:118,118,0,0,0
02-29 20:34:13.342: E/Test(16577): szData:0,8
02-29 20:34:13.342: E/Test(16577): malloc:0
02-29 20:34:13.342: E/Test(16577): pCurrentData=pInputData0
02-29 20:34:13.342: E/Test(16577): Step8:InputComplete
02-29 20:34:13.342: E/Test(16577): Step9:Output:0
02-29 20:34:13.342: E/Test(16577): Step10:DeleteLocalRef-inputBuf
02-29 20:34:13.342: E/Test(16577): Delete0
02-29 20:34:13.342: E/Test(16577): pTemp -519989872
02-29 20:34:13.342: E/Test(16577): pTemp nextNode 0
02-29 20:34:13.342: E/Test(16577): Delete1
02-29 20:34:13.342: E/Test(16577): Delete2
02-29 20:34:13.342: E/Test(16577): Delete3:-519989872
02-29 20:34:13.342: E/Test(16577): FreeParent
02-29 20:34:13.342: E/Test(16577): strFunction:-6926512---------190056080
02-29 20:34:13.342: E/Test(16577): Step12:FreeComplete
02-29 20:34:14.412: E/Test(16577): Step1:Function:init_config_from_xml,type:1
02-29 20:34:14.412: E/Test(16577): Step4:InputBuf:
02-29 20:34:14.412: E/Test(16577): Step6:InputArray:
02-29 20:34:14.412: E/Test(16577): Step7:nCount:1
02-29 20:34:14.412: E/Test(16577): nLen:45,45,0,0,0
02-29 20:34:14.412: E/Test(16577): szData:0,8
02-29 20:34:14.412: E/Test(16577): malloc:0
02-29 20:34:14.412: E/Test(16577): pCurrentData=pInputData0
02-29 20:34:14.412: E/Test(16577): Step8:InputComplete
02-29 20:34:14.412: E/Test(16577): Step9:Output:0
02-29 20:34:14.412: E/Test(16577): Step10:DeleteLocalRef-inputBuf
02-29 20:34:14.412: E/Test(16577): Delete0
02-29 20:34:14.412: E/Test(16577): pTemp -519989872
02-29 20:34:14.412: E/Test(16577): pTemp nextNode 65536261
02-29 20:34:14.412: A/libc(16577): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x3e80109 in tid 16577 (com.jpt.mds.c90)


接口源码如下:


jint
JNICALL Java_com_jpt_mds_core_ProtocolJNI_initProtocolConfig(JNIEnv* env,
		jobject thiz,
		jstring strFunction,
		jint type,
		jbyteArray szInput)
{
	int nResult = 0;
	int nType = type;
	const char* szFunction = (*env)->GetStringUTFChars(env, strFunction, 0);
	LOGE("Step1:Function:%s,type:%d",szFunction,type);

	if( handle == NULL ){
		LOGE("Step2:","handle == NULL");
		return nResult;
	}
	int (*fun)(int,void*);
	fun=(int(*)(int,void*))dlsym(handle,szFunction);
	if (fun==NULL)
	{
		LOGE("Step3:Error:%s,",dlerror());
		exit(-2);
	}

	jbyte* inputBuf = (jbyte*)(*env)->GetByteArrayElements(env,szInput,NULL);
	LOGE("Step4:InputBuf:%s",(const char*)inputBuf);

	//输出参数
	//	jmethodID outputInit = (*env)->GetMethodID(env,clazz_output, "<init>", "()V");
	//	if (NULL == outputInit) {
	//		return 0;
	//	}
	//	// 实例化类对象
	//	jobject jOutObject = (*env)->NewObject(env,clazz_output, outputInit);


	//重新组装链表
	STRUCT_CHAIN_DATA_INPUT* pInputData = (STRUCT_CHAIN_DATA_INPUT*)malloc( sizeof(int) );
	pInputData->pcData = NULL;
	pInputData->pNextNode = NULL;
	STRUCT_CHAIN_DATA_INPUT* pCurrentData = NULL;
	int nPos = 0;
	int nCount = 0;
	int i,n,m;
	byte* btArray = (byte*)inputBuf;
	LOGE("Step6:InputArray:%s",(const char*)btArray);

	nCount = btArray[0] & 0xFF;
	nCount |= ((btArray[1] << 8) & 0xFF00);
	nCount |= ((btArray[2] << 16) & 0xFF0000);
	nCount |= ((btArray[3] << 24) & 0xFF000000);

	nPos += 4;
	LOGE("Step7:nCount:%d",nCount);

	for( n = 0; n < nCount; n ++ ){

		char* szData = NULL;
		int nLen = 0;
		nLen = btArray[nPos] & 0xFF;
		nLen |= ((btArray[nPos + 1] << 8) & 0xFF00);
		nLen |= ((btArray[nPos + 2] << 16) & 0xFF0000);
		nLen |= ((btArray[nPos + 3] << 24) & 0xFF000000);
		LOGE("nLen:%d,%d,%d,%d,%d",nLen,btArray[nPos],btArray[nPos + 1],btArray[nPos + 2],btArray[nPos + 3]);
		nPos += 4;

		szData = (char*)malloc( nLen + 1 );
		memset(szData,0,nLen + 1);
		memcpy(szData,btArray + nPos,nLen);
		LOGE("szData:%c,%d",szData[0],nPos);
		nPos += nLen;
		LOGE("malloc:%d",n);
		if( n == 0 && pInputData != NULL ){
			pInputData->iLen = nLen;
			pInputData->pcData = szData;

			pCurrentData = pInputData;
			LOGE("pCurrentData=pInputData%d",n);
		}
		else if( n > 0 && n < nCount && pCurrentData != NULL ){
			STRUCT_CHAIN_DATA_INPUT* pTmp = (STRUCT_CHAIN_DATA_INPUT*)malloc( sizeof(STRUCT_CHAIN_DATA_INPUT) );
			pTmp->iLen = nLen;
			pTmp->pcData = szData;
			pTmp->pNextNode = NULL;

			pCurrentData->pNextNode = pTmp;
			pCurrentData = pTmp;
			LOGE("pCurrentData %d",pTmp);
		}
	}

	LOGE("Step8:InputComplete");
	//调用函数
	nResult = (*fun)(nType,pInputData);
	LOGE("Step9:Output:%d",nResult);
	//byte数组转
	//释放缓存

	(*env)-> ReleaseByteArrayElements(env, szInput,(jbyte *)inputBuf, 0);
	inputBuf = NULL;
	LOGE("Step10:DeleteLocalRef-inputBuf");

	//释放链表
	STRUCT_CHAIN_DATA_INPUT* pTemp = pInputData;
		while ( pTemp != NULL )
		{
			LOGE("Delete0");
			LOGE("pTemp %d",pTemp); STRUCT_CHAIN_DATA_INPUT* pTemp1 = (STRUCT_CHAIN_DATA_INPUT*)pTemp->pNextNode;
			LOGE("pTemp nextNode %d",pTemp1);
			LOGE("Delete1");
			if ( pTemp->pcData != NULL )
			{
				LOGE("Delete2");
				free(pTemp->pcData);
				pTemp->pcData = NULL;
			}
			LOGE("Delete3:%d",(int)pTemp);
			free(pTemp);
			LOGE("FreeParent");
			pTemp = pTemp1;
		}
	pInputData = NULL;
	LOGE("strFunction:%d--------%d", strFunction, szFunction);
	(*env)->ReleaseStringUTFChars(env, strFunction, szFunction);
	szFunction = NULL;
	LOGE("Step12:FreeComplete");
	return nResult;
} 



举报
tsmaomaoyu
发帖于2年前 13回/2K+阅
共有13个答案 最后回答: 2年前

我的意思是你申请了一个sizeof(int),比如说大小为4,也就是申请了4字节的空间,libc返回给你一个指向这4字节起始位置的指针,你把他赋值给 (STRUCT_CHAIN_DATA_INPUT*)类型的pInputData,然后就拿这个pInputData当 STRUCT_CHAIN_DATA_INPUT进行操作,你贴的代码里没有此结构的定义,但看代码中对其使用

    pInputData->pcData = NULL;

    pInputData->pNextNode = NULL;

可以猜测这个结构的size一定大于int型的size,那么当你使用pInputData->pNextNode时他指向的地址其实已经超出了你申请的那4个字节的大小,其内容是不确定的,如果这块内存没有被分配出去,或分配出去,但申请他的程序在你的程序运行过程没有对此内存做修改,则你的问题不会出问题,否则就有问题了


在5.0以前的系统都没问题,但从打印信息来看,5.0以后的系统,C++变量的地址都是负值,不知道和这个有没有关系,求大神解答
Android5.0之前是java和本地库各用一个堆栈空间,5.0以后强制ART模式运行,两个共享同一个堆栈了,会不会是这里问题,代码没处理好导致堆栈泄露了

红圈部分next的值本应该为0,结果不为0导致下面异常,这个方法一共调用五次,这个错误一般出现在第三次调用,也有时候出现在别的地方

不用看了,在OSC上问问题要@几个高手的,不然被正确解答的机率是很低的,我以前一直傻乎乎的问,到最后TMD都是自答自问
--- 共有 1 条评论 ---
tsmaomaoyu。。。 卧槽,还有这规矩呢,我是实在解决不了了,想在这上面碰碰运气呢还 2年前 回复
 pTmp->pNextNode   这个要全部  = null。应该和 内存初始化值有关系
--- 共有 1 条评论 ---
tsmaomaoyu大神,请看我下面回复,还有一个情况就是,如果我把手机上这个应用卸载了,重新debug安装apk,全部七次调用都可以通过,会在后面出错。。。 2年前 回复

引用来自“超级IT”的评论

 pTmp->pNextNode   这个要全部  = null。应该和 内存初始化值有关系

我把所有的指针都用最笨的办法初始化了一遍,结果还一样,而且基本上都是第三次调用这个接口的时候出问题,从调试看,每次调用的时候传过来的参数都没问题,我也怀疑可能是内存泄露或者是数组越界了,但他基本上都固定在第三次出错,我就有点不确定了,太稳定了

  我把所有的指针都用最笨的办法初始化了一遍,结果还一样,而且基本上都是第三次调用这个接口的时候出问题,从调试看,每次调用的时候传过来的参数都没问题,我也怀疑可能是内存泄露或者是数组越界了,但他基本上都固定在第三次出错,我就有点不确定了,太稳定了


内存问题是肯定的。代码规范一下 


这这里pTemp pTemp1泄露了


顶部