Domanda

Sto scrivendo un demone di alto carico che deve essere eseguito sul FreeBSD 8.0 e Linux. Lo scopo principale di demone è quello di passare i file che vengono richiesti per la loro identificazione. Identifier è convertito in formato nome / file locale tramite richiesta al db. E poi io uso mmap() sequenziale chiama a passare i blocchi di file con send().

Tuttavia a volte ci sono disadattamento di spazio in db e spazio sul file system (realsize

Sono stato con controllo di sicurezza prima di aperto per assicurare dimensioni con chiamata stat(). Tuttavia la vita vera mostra a me che segfault ancora può essere sollevata in rari situtaions.

Quindi, la mia domanda c'è un modo per verificare se il puntatore è accessibile prima dereferenziazione esso? Quando ho aperto nucleo in gdb, gdb dice che il dato indirizzo è fuori limite. Probabilmente c'è un'altra soluzione che qualcuno in grado di proporre.

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#define FILENAME        "./datafile"

int main()
{
    unsigned long i, j;

    srand(time(NULL));
    unsigned long pagesize = sysconf(_SC_PAGESIZE);

    unsigned long basesize = 4 * pagesize;
    unsigned long cropsize = 2 * pagesize;

    // create 4*pagesize sized file
    int f = creat(FILENAME, 0644);
    for (i = 0; i < basesize; i++) {
        unsigned char c = (unsigned char)rand();
        if (write(f, &c, 1) < 1) { perror("write"); break; }
    }
    close(f);

    f = open(FILENAME, O_RDONLY);

    // walk trough file
    unsigned char xor = 0;
    unsigned long offset = 0;
    for (j = 0; j < 4; j++) {
        // trunc file to 2*pagesize
        if (j == 2) truncate(FILENAME, cropsize);

        char *data = mmap(NULL, pagesize, PROT_READ, MAP_PRIVATE, f, offset);
        if (data == MAP_FAILED) { perror("mmap"); break; }
        printf("mmap: %lu@%lu for %i\n", pagesize, offset, f);

        for (i = 0; i < pagesize; i++) xor ^= data[i];

        offset += pagesize;
    }

    close(f);

    return 0;
}
È stato utile?

Soluzione

Naturalmente non posso provarlo da qui, ma ho il forte sospetto che basta un bug contabilità nel codice. Se si chiama mmap e passare in una dimensione, e ci riesce, non si dovrebbe ottenere SIGSEGV.

vi consiglio di applicare Valgrind alla tua ricerca.

Su molti sistemi Linux / proc / PID / mappe vi mostrerà quali regioni sono mappati con i permessi di accesso che cosa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top