|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Nov 2005
Messaggi: 70
|
Errore apertura file creato
//Apertura del file sala.txt
file_sala = open("sala.txt",O_RDWR|O_CREAT,0660); if (file_sala == -1) { printf("Errore nell'apertura del File\n"); exit(-1); } //Mapping del file sala.txt nello spazio di indirizzamento del processo server int filelen = lseek(file_sala, 0, SEEK_END); txt = (Posto*)mmap(0, filelen, PROT_READ|PROT_WRITE, MAP_SHARED, file_sala, 0); if(txt == NULL){ printf("Mapping del file sala.txt fallito, si prega di verificare il problema\n"); exit(-1); } Perchè mi da errore? ![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Perché non descrivi l'errore che ti da e il tipo di test che stai facendo?
nb(1) ovviamente il check su mmap è sbagliato. NULL è un valore legittimo. Se la mmap fallisce, ritorna MAP_FAILED (ovverio ~0) nb(2) In caso di errore, usa perror. Ad es: Codice:
file_sala = open("sala.txt",O_RDWR|O_CREAT,0660); if (file_sala == -1) { perror("open"); exit(-1); }
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Nov 2005
Messaggi: 70
|
l' errore che mi da è quello sul file mapping.
Ossia se mi apro il file in quella modalità mi da errore il file mapping("Mapping del file sala.txt fallito"). Se il file lo creo manualmente non mi da questo tipo di errore e tutto funziona; con quali modalità devo aprire il file o con quali devo fare il file mapping? Ciao e grazie ![]() |
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Nov 2005
Messaggi: 70
|
Problema risolto
Sono un imbecille Grazie comunque a tutti ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Ti ho già detto che il confronto
if(txt == NULL) è sbagliato; devi confrontare con MAP_FAILED. Mi sembra impossibile che, nel tuo caso, la mmap ritorna NULL comunque. Quindi riscrivi il codice così e controlla quello che dice: Codice:
if(txt == MAP_FAILED){ perror("mmap"); exit(-1); }
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Non sapevo che mmap ritornasse NULL se la regione da mappare ha dimensione 0. Molto astuto, così becchi subito accessi erronei da parte del codice.
Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Sul fatto, come dici tu, che una regione di grandezza 0 non dovrebbe essere acceduta, è vero ma dipende da cosa ci devi fare. Supponiamo: Codice:
int filelen = lseek (...); txt = (Posto*)mmap (...); if (txt != MAP_FAILED) { for (i=0; i<filelen; i++) { ...utilizzo di txt... } } Quindi o ti fai un exception handling (non so come ma in qualche modo), oppure testi se txt è NULL, oppure ancora, più a monte, testi se filelen è zero e a questo punto non fai neanche la mmap e fai altro. Tra l'altro mi sembra stupido che la mmap possa restituire MAP_FAILED (-1). Tutte le principali funzioni (almeno che io conosco) che restituiscono un puntatore, ritornano un NULL in caso di errore (es. malloc, strchr, strstr, fgets, ecc...).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#9 |
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
Codice:
goku@big:/tmp$ cat mmap_test.c #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> int main(void) { int filelen; void *map; int fd = open("sala.txt", O_RDWR | O_CREAT, 0660); if (fd == -1) { perror("open()"); exit(1); } filelen = lseek(fd, 0, SEEK_END); map = mmap(0, filelen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { perror("mmap()"); close(fd); exit(1); } puts("mapped file!"); close(fd); munmap(map, filelen); return 0; } goku@big:/tmp$ gcc mmap_test.c -o mmap_test -Wall goku@big:/tmp$ ./mmap_test mmap(): Invalid argument goku@big:/tmp$ echo pinocchio ha fatto colazione >>sala.txt goku@big:/tmp$ ./mmap_test mapped file! goku@big:/tmp$ |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#11 | |
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
Quote:
Per curiosita' ho provato anche su una Gentoo aggiornata con lo stesso risultato postato sopra. |
|
![]() |
![]() |
![]() |
#12 | |||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Quote:
Quote:
Codice:
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/mman.h> int main(int argc, char **argv) { char *map = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); if(map==MAP_FAILED) { perror("mmap"); exit(-1); } sprintf(map, "sto scrivendo all'indirizzo 0x%08lx!!\n", (unsigned long) map); write(fileno(stderr), map, strlen(map)); return 0; }
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|||
![]() |
![]() |
![]() |
#13 | ||
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quote:
![]() Desidero precisare che pur conoscendo di nome la funzione mmap(), non l'avevo mai usata (prima di fare le prove per questo thread). Quindi per evitare di "fare notte" vorrei precisare che: 1) Il puntatore NULL (0x0) è, per definizione, un puntatore non valido, usato oltretutto da una caterba di funzioni per segnalare un errore. L'accesso all'indirizzo 0x0 causa quindi, generalmente, un segmentation fault. 2) Che esista una funzione "particolare" come la mmap (che opera a livello di sistema sulla mappatura della memoria) solo sui sistemi Linux/Unix e che ti mappa un blocco di memoria all'indirizzo 0x0 ... beh, questa, come direbbe qualcuno ... è un'altra storia! Non lo sapevo ![]() ![]()
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
||
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Il fatto che all'indirizzo 0 ci puoi trovare "qualcosa di valido", non è una semplice alchimia del mio programmino. Gli x86 in modalità reale, se non ricordo male, hanno il vettore di interruzioni all'indirizzo 0 (verificabile tramite qualsiasi DOS); alcuni processori hanno memoria _fisica_ di un qualche tipo all'indirizzo 0 (ad es. lo StrongARM ha la flash), che coincide con la memoria vista dal programma se operi senza mmu. In queste situazioni, se scrivi su NULL non ottieni necessariamente un segfault (forse qualcosa di meno divertente ![]()
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#15 | ||
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quote:
![]() Quindi per riassumere. Il puntatore NULL per convenzione non è valido, ed è quindi buona norma testare puntatori, ecc... prima dell'utilizzo. La mmap() e architetture hardware particolari sono da trattare a parte.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
||
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
un strchr su una regione ottenuta con mmap è un bug, a meno che non hai verificato preventivamente (ad es. con strnlen) che la regione termina con '\0'. Puoi andare in segfault anche se il file non è vuoto; basta che sia allineato alla pagina, non contenga zeri, e non contenga il carattere che stai cercando con strchr. Per queste applicazioni (ovvero con dati forniti "dall'esterno", ad es. letti da un file) meglio memchr.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:19.