
我编写了一个简单的Android本机函数,该函数获取文件名和更多参数,并通过映射(mmap)内存来读取文件.
因为它是mmap,所以我真的不需要调用“ read()”,所以我只是从mmap()返回的地址使用memcpy().
但是,在某个地方我得到了SIGSEGV,可能是因为我试图访问不允许的内存.但是我不明白为什么,我已经要求映射所有文件的内存!
我正在附上我的代码和出现的错误:
编辑
我修复了无限循环,但在读取了25001984个字节后仍然得到SIGSEGV.
该函数适用于这些参数:
jn_bytes = 100,000,000
jbuffer_size = 8192
Jshared = jpopulate = jadvice = 0
voID Java_com_def_benchmark_Benchmark_testMmapRead(jnienv* env, jobject javaThis, Jstring jfile_name, unsigned int jn_bytes, unsigned int jbuffer_size, jboolean Jshared, jboolean jpopulate, jint jadvice) { const char *file_name = env->GetStringUTFChars(jfile_name, 0); /* *** start count *** */ int fd = open(file_name, O_RDONLY); //get the size of the file size_t length = lseek(fd, 0L, SEEK_END); lseek(fd, 0L, SEEK_SET); length = length>jn_bytes?jn_bytes:length; // man 2 mmap: MAP_POPulATE is only supported for private mapPings since linux 2.6.23 int flags = 0; if (Jshared) flags |= MAP_SHARED; else flags |= MAP_PRIVATE; if(jpopulate) flags |= MAP_POPulATE; //int flags = MAP_PRIVATE; int * addr = reinterpret_cast<int *>(mmap(NulL, length , PROT_READ, flags , fd, 0)); if (addr == MAP_Failed) { __androID_log_write(ANDROID_LOG_ERROR, "NDK_FOO_TAG", strerror(errno)); return; } int * initaddr = addr; if(jadvice > 0) madvise(addr,length,jadvice==1?(MADV_SEQUENTIAL|MADV_WILLNEED):(MADV_DONTNEED)); close(fd); char buffer[jbuffer_size]; voID *ret_val = buffer; int read_length = length; while(ret_val == buffer || read_length<jbuffer_size) {/*****GETTING SIGSEGV SOMWHERE HERE IN THE WHILE************/ ret_val = memcpy(buffer, addr,jbuffer_size); addr+=jbuffer_size; read_length -= jbuffer_size; } munmap(initaddr,length); /* stop count */ env->ReleaseStringUTFChars(jfile_name, file_name);}和错误日志:
15736^done(gdb) 15737 info signal SIGSEGV&"info signal SIGSEGV\n"~"Signal Stop\tPrint\tPass to program\tDescription\n"~"SIGSEGV Yes\tYes\tYes\t\tSegmentation fault\n"15737^done(gdb) 15738-stack-List-arguments 0 0 015738^done,stack-args=[frame={level="0",args=[]}](gdb) 15739-stack-List-locals 015739^done,locals=[](gdb) 解决方法:
这里有个大问题:
addr+=jbuffer_size;您通过sizeof(int)* jbuffer_size个字节增加了addr,而您只想将其增加jbuffer_size个字节.
我的猜测是系统上的sizeof(int)为4,因此您在整个循环的大约25%时间内崩溃,因为每次迭代时addr的增量都增加了4倍.
总结以上是内存溢出为你收集整理的android-mmap之后在memcpy中获取分段错误SIGSEGV全部内容,希望文章能够帮你解决android-mmap之后在memcpy中获取分段错误SIGSEGV所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)