controllare se l'indirizzo è corretto mmap'ed
-
22-09-2019 - |
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 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. stat()
. Tuttavia la vita vera mostra a me che segfault ancora può essere sollevata in rari situtaions. #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;
}
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.