Jni string空串跨模块使用崩溃注意事项
2015-12-03 10:12
429 查看
前言:
结论:不允许跨模块返回一个空的string类型。
例子:当前有两个模块A,B,在不同的库文件中
using namespace A
{
std::string GetString()
{
std::string str = "";
return str;
}
}
using namespace B
{
void GetResult()
{
std::string str = A::GetString();
}
}
一旦调用GetResult,就会发生错误,按照崩溃的信息
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xdeadbaad
Abort message: 'invalid address or address of corrupt block 0x358e4 passed to dlfree'
r0 00000000 r1 f7643dec r2 deadbaad r3 00000000
r4 000358e4 r5 f76450f8 r6 aaff3000 r7 e41a28c4
r8 12d080e0 r9 ab00b490 sl 12d46500 fp 12d46500
ip 00000080 sp fffddb48 lr f7614fe7 pc f7614fe8 cpsr 600f0030
d0 0000000000000000 d1 6120726f2073736c
d2 6f20737365726466 d3 707572726f632072
d4 ab1e7e80ab1e7e80 d5 0000000000000000
d6 00740065004e002e d7 006b0072006f0077
d8 0000000000000000 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 0000000000000000 d17 0000278c00000000
d18 6ffeabe86ffeabe8 d19 6ffeabe86ffeabe8
d20 6ffeabe86ffeabe8 d21 6ffeabe86ffeabe8
d22 6ffeabe86ffeabe8 d23 6ffeabe86ffeabe8
d24 6ffeabe86ffeabe8 d25 6ffeabe86ffeabe8
d26 6ffeabe86ffeabe8 d27 6ffeabe86ffeabe8
d28 6ffeabe86ffeabe8 d29 6ffeabe86ffeabe8
d30 6ffeabe86ffeabe8 d31 6ffeabe86ffeabe8
scr 60000011
backtrace:
#00 pc 00028fe8 /system/lib/libc.so (dlfree+1239)
#01 pc 0000f2c3 /system/lib/libc.so (free+10)
#02 pc 0000c630 /data/app/cn.test/lib/arm/libnative.so
大致猜测为当GetString退出当前的模块A作用域,就已经释放了string指向的内存空间,当GetResult函数调用结束的时候,重新释放导致了问题的出现。
在这里如果在同一个模块(同一个库文件)使用,就是GetString和GetResult处于同一个模块,就不会有任何的问题。
或者GetString中定义的str不是一个空字符串,也不会有任何的问题。
目前在java层,jstring 为空,传递给jni层出现错误:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb38800ec
r0 00000002 r1 0000002e r2 ffffffd0 r3 b6d0f2f0
r4 b6d0f2e8 r5 b38b0f6c r6 b4cc2000 r7 b3880000
r8 b4cc9008 r9 b6d02594 sl 00000001 fp 00000000
ip b38800b8 sp be8e53a8 lr b6ce434b pc b6ce13ca cpsr 200f0030
d0 0000000000000000 d1 0000000000000000
d2 000003e800000000 d3 0000000000000014
d4 424831a6528a632c d5 5aea5aea5aea52e9
d6 5aea5aea5aea5aea d7 5aea5aea5aea5aea
d8 0000000000000000 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 0000043800000780 d17 0000000100000004
d18 0000004800000002 d19 0000000400000000
d20 0000000000000033 d21 0000000000000000
d22 0000000000000000 d23 4ffd51265a458900
d24 0000000000000001 d25 0001000100050005
d26 8003800380078007 d27 0023002300030003
d28 0000000000000000 d29 0000000000000000
d30 0000000000000000 d31 0000000000000000
scr 80000012
backtrace:
#00 pc 000553ca /system/lib/libc.so (ifree+49)
#01 pc 00058347 /system/lib/libc.so (je_free+374)
#02 pc 0000fe1f /data/app/test/lib/arm/libnative.so
#03 pc 0000ac61 /data/app/test/lib/arm/libnative.so
已经开始进展的活动:在Linux跨模块测试string空串问题,没有重现,说明Linux没有这个问题,而Android采用的C库是GOOGLE编写的,应该是string的源码处理上有问题,但是在同一个模块是不会有这个问题,而是在跨模块才会有这个问题,又将注意力转移到编译器优化上。
结论:不允许跨模块返回一个空的string类型。
例子:当前有两个模块A,B,在不同的库文件中
using namespace A
{
std::string GetString()
{
std::string str = "";
return str;
}
}
using namespace B
{
void GetResult()
{
std::string str = A::GetString();
}
}
一旦调用GetResult,就会发生错误,按照崩溃的信息
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xdeadbaad
Abort message: 'invalid address or address of corrupt block 0x358e4 passed to dlfree'
r0 00000000 r1 f7643dec r2 deadbaad r3 00000000
r4 000358e4 r5 f76450f8 r6 aaff3000 r7 e41a28c4
r8 12d080e0 r9 ab00b490 sl 12d46500 fp 12d46500
ip 00000080 sp fffddb48 lr f7614fe7 pc f7614fe8 cpsr 600f0030
d0 0000000000000000 d1 6120726f2073736c
d2 6f20737365726466 d3 707572726f632072
d4 ab1e7e80ab1e7e80 d5 0000000000000000
d6 00740065004e002e d7 006b0072006f0077
d8 0000000000000000 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 0000000000000000 d17 0000278c00000000
d18 6ffeabe86ffeabe8 d19 6ffeabe86ffeabe8
d20 6ffeabe86ffeabe8 d21 6ffeabe86ffeabe8
d22 6ffeabe86ffeabe8 d23 6ffeabe86ffeabe8
d24 6ffeabe86ffeabe8 d25 6ffeabe86ffeabe8
d26 6ffeabe86ffeabe8 d27 6ffeabe86ffeabe8
d28 6ffeabe86ffeabe8 d29 6ffeabe86ffeabe8
d30 6ffeabe86ffeabe8 d31 6ffeabe86ffeabe8
scr 60000011
backtrace:
#00 pc 00028fe8 /system/lib/libc.so (dlfree+1239)
#01 pc 0000f2c3 /system/lib/libc.so (free+10)
#02 pc 0000c630 /data/app/cn.test/lib/arm/libnative.so
大致猜测为当GetString退出当前的模块A作用域,就已经释放了string指向的内存空间,当GetResult函数调用结束的时候,重新释放导致了问题的出现。
在这里如果在同一个模块(同一个库文件)使用,就是GetString和GetResult处于同一个模块,就不会有任何的问题。
或者GetString中定义的str不是一个空字符串,也不会有任何的问题。
目前在java层,jstring 为空,传递给jni层出现错误:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb38800ec
r0 00000002 r1 0000002e r2 ffffffd0 r3 b6d0f2f0
r4 b6d0f2e8 r5 b38b0f6c r6 b4cc2000 r7 b3880000
r8 b4cc9008 r9 b6d02594 sl 00000001 fp 00000000
ip b38800b8 sp be8e53a8 lr b6ce434b pc b6ce13ca cpsr 200f0030
d0 0000000000000000 d1 0000000000000000
d2 000003e800000000 d3 0000000000000014
d4 424831a6528a632c d5 5aea5aea5aea52e9
d6 5aea5aea5aea5aea d7 5aea5aea5aea5aea
d8 0000000000000000 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 0000043800000780 d17 0000000100000004
d18 0000004800000002 d19 0000000400000000
d20 0000000000000033 d21 0000000000000000
d22 0000000000000000 d23 4ffd51265a458900
d24 0000000000000001 d25 0001000100050005
d26 8003800380078007 d27 0023002300030003
d28 0000000000000000 d29 0000000000000000
d30 0000000000000000 d31 0000000000000000
scr 80000012
backtrace:
#00 pc 000553ca /system/lib/libc.so (ifree+49)
#01 pc 00058347 /system/lib/libc.so (je_free+374)
#02 pc 0000fe1f /data/app/test/lib/arm/libnative.so
#03 pc 0000ac61 /data/app/test/lib/arm/libnative.so
已经开始进展的活动:在Linux跨模块测试string空串问题,没有重现,说明Linux没有这个问题,而Android采用的C库是GOOGLE编写的,应该是string的源码处理上有问题,但是在同一个模块是不会有这个问题,而是在跨模块才会有这个问题,又将注意力转移到编译器优化上。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android NDK开发之:配置环境的详解
- Android开发的IDE、ADT、SDK、JDK、NDK等名词解释
- Android提高之使用NDK把彩图转换灰度图的方法
- Android使用Jni实现压力锅数据检测效果示例
- JAVA中JNI的简单使用分享
- c++ mk文件出错Jni调用产生java.lang.UnsatisfiedLinkError错误解决方法
- 解析Java的JNI编程中的对象引用与内存泄漏问题
- 探讨:如何在NDK中呼叫Java的class
- 安卓应用开发通过java调用c++ jni的图文使用方法
- Java调用c++库
- Android App 增量更新实例(Smart App Updates)
- 每周总结20130814——Android NDK环境的搭建和使用,YUV420SP格式图像的处理
- Android NDK开发简介
- Android NDK开发之Jni的数据类型
- Android NDK pthreads详细使用
- Android Studio中NDK开发傻瓜教程(CMake)
- JNI_Android项目中调用.so动态库实现详解