Segmentierungsfehler SIGSEGV wird nach mmap in memcpy abgerufen

Ich habe eine einfache native Android-Funktion geschrieben, die einen Dateinamen und einige weitere Argumente abruft und die Datei durch Mmapping (Mmap) ihres Speichers liest.

Da es sich um eine mmap handelt, muss ich nicht unbedingt "read ()" aufrufen, also memcpy () von der von der mmap () zurückgegebenen Adresse.

Aber irgendwo bekomme ich wahrscheinlich ein SIGSEGV, weil ich versuche, auf einen Speicher zuzugreifen, den ich nicht zugelassen habe. Aber ich verstehe nicht warum, ich habe bereits alle Dateien aufgefordert, zugeordnet zu werden!

Ich füge meinen Code und den Fehler hinzu, den ich erhalten habe:

BEARBEITEN

Ich habe die Endlosschleife behoben, erhalte aber immer noch SIGSEGV, nachdem 25001984 Bytes gelesen wurden. Die Funktion arbeitet mit den folgenden Argumenten: 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);
}

und das Fehlerprotokoll:

    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 0
15738^done,stack-args=[frame={level="0",args=[]}]
(gdb) 
15739-stack-list-locals 0
15739^done,locals=[]
(gdb) 

Antworten auf die Frage(3)

Ihre Antwort auf die Frage