|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
[C] Segmentation fault su memoria condivisa
Salve a tutti, ormai sto infestando questa sezione con i miei post ma non so a chi altro rivolgermi per dei chiarimenti quindi... sopportatemi
![]() Veniamo al dunque, il programma seguente si compila correttamente ma mi dà un segmentation fault a tempo d'esecuzione. In pratica io voglio creare un segmento di memoria condivisa da utilizzare come un array (in modo tale che possano accedervi il processo padre e i processi figli) ma mi dà quell'errore lì. Qualcuno può dirmi come mai? grazie Codice:
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/stat.h> #include <unistd.h> int *automobili; int *direzione; int main (int argc, char* argv[]) { int autom, direz, N; N=10; if (autom=shmget(IPC_PRIVATE, N*sizeof(pid_t), 0666) <0) perror("Errore nella creazione del segmento di memoria condivisa 'automobili'"); automobili=(int *) shmat (autom, 0, SHM_RND); if (direz=shmget(IPC_PRIVATE, N*sizeof(int), 0666) <0) perror("Errore nella creazione del segmento di memoria condivisa 'direzione'"); direzione=(int *) shmat (direz, 0, SHM_RND); automobili[0]=3; automobili[1]=getpid(); printf("%d %d", automobili[0], automobili[1]); } Ultima modifica di VegetaSSJ5 : 12-07-2004 alle 16:12. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Nulla di grave, il classico problema hardware tra la sedia e la tastiera
![]() Codice:
--- segfault.c.org 2004-07-12 17:29:06.000000000 +0200 +++ segfault.c 2004-07-12 17:29:40.000000000 +0200 @@ -14,9 +14,9 @@ int main (int argc, char* argv[]) { int autom, direz, N; N=10; - if (autom=shmget(IPC_PRIVATE, N*sizeof(pid_t), 0666) <0) perror("Errore nella creazione del segmento di memoria condivisa 'automobili'"); + if ((autom=shmget(IPC_PRIVATE, N*sizeof(pid_t), 0666)) <0) perror("Errore nella creazione del segmento di memoria condivisa 'automobili'"); automobili=(int *) shmat (autom, 0, SHM_RND); - if (direz=shmget(IPC_PRIVATE, N*sizeof(int), 0666) <0) perror("Errore nella creazione del segmento di memoria condivisa 'direzione'"); + if ((direz=shmget(IPC_PRIVATE, N*sizeof(int), 0666)) <0) perror("Errore nella creazione del segmento di memoria condivisa 'direzione'"); direzione=(int *) shmat (direz, 0, SHM_RND); automobili[0]=3; automobili[1]=getpid();
__________________
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 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
nb non compilate MAI con -Wall, mi raccomando
![]()
__________________
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 |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
grazie ilsensine! cmq il problema non ero io ma l'editor kate che mi segnava come ultima parentesi quella che tu poi hai aggiunto
![]() come mai non bisogna mai compilare com -Wall?? |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Io compilo _sempre_ con -Wall (e per la produzione con -Wall -Werror).
__________________
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: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
ilsensine ti ringrazio molto, sei il mio angelo custode, tuttavia ci sono per me dei misteri inspiegabili tipo il seguente: il padre stampa il valore giusto di automobili[i] invece il figlio no
Codice:
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/stat.h> #include <unistd.h> int *automobili; int *direzione; void funzione (int N); int main (int argc, char* argv[]) { int autom, direz, N; N=10; if ((autom=shmget(IPC_PRIVATE, N*sizeof(pid_t), 0666)) <0) perror("Errore"); automobili=(int *) shmat (autom, 0, SHM_RND); if ((direz=shmget(IPC_PRIVATE, N*sizeof(int), 0666)) <0) perror("Errore"); direzione=(int *) shmat (direz, 0, SHM_RND); funzione(3); } void funzione (int N) { int i; pid_t padre=getpid(); for (i=0; i<N; i++) { if (getpid()==padre) { if ((automobili[i]=(int)fork()) < 0) perror("Errore generando l'automobile"); if (getpid()==padre) printf("\nPADRE, automobili[%d]= %d\n\n", i, automobili[i]); } if (getpid()!=padre) { printf("\nAUTO %d, automobili[%d]= %d", i, i, automobili[i]); i=N; } } } Codice:
for (i=0; i<N; i++) { pid_t pid=fork(); if (pid==0) printf("figlio %d dopo fork %d %d\n", i, automobili[0], automobili[1]); else printf("padre dopo fork %d %d\n", automobili[0], automobili[1]); if (pid==0) { automobili[0]=140; automobili[1]=(int)getpid(); printf("Figlio %d dopo assegnamento %d %d\n", i, automobili[0], automobili[1]); } else { printf("padre dopo assegnamento %d %d\n", automobili[0], automobili[1]); automobili[0]=111; automobili[1]=(int)getpid(); printf("padre dopo riassegnamento %d %d\n", automobili[0], automobili[1]); } if (pid==0) { sleep(1); printf("figlio %d dopo riassegnamento %d %d\n", i, automobili[0], automobili[1]); i=N; } } } ![]() Ultima modifica di VegetaSSJ5 : 13-07-2004 alle 13:47. |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Codice:
if (getpid()==padre) { if ((automobili[i]=(int)fork()) < 0) perror("Errore generando l'automobile"); if (getpid()==padre) printf("\nPADRE, automobili[%d]= %d\n\n", i, automobili[i]); } if (getpid()!=padre) { printf("\nAUTO %d, automobili[%d]= %d", i, i, automobili[i]); i=N; }
__________________
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: Apr 2000
Città: Roma
Messaggi: 15625
|
Codice:
--- race.c.org 2004-07-13 15:26:25.000000000 +0200 +++ race.c 2004-07-13 15:33:06.000000000 +0200 @@ -6,6 +6,7 @@ #include <sys/shm.h> #include <sys/stat.h> #include <unistd.h> +#include <sched.h> int *automobili; int *direzione; @@ -24,10 +25,13 @@ void funzione (int N) { int i; + pid_t val; pid_t padre=getpid(); for (i=0; i<N; i++) { if (getpid()==padre) { - if ((automobili[i]=(int)fork()) < 0) perror("Errore generando l'automobile"); + if((val = fork())<0) perror("fork"); + if(val) automobili[i] = val; // Fix prima race + else sched_yield(); // Fix seconda race!! if (getpid()==padre) printf("\nPADRE, automobili[%d]= %d\n\n", i, automobili[i]); } if (getpid()!=padre) {
__________________
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 |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
grazie ilsensine.
puoi dirmi cosa sono le race condition? che cosa fa la funzione sched_yeld? |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
allora mi sono informato (google
![]() race condition: "Le race condition sono gli errori piu' comuni nella programmazione multithreaded o multiprocesso. Una race condition si verifica quando una assunzione fatta dal programmatore che non dovrebbe cambiare per un dato lasso di tempo, cambia per forza...." fonte sched_yield(): pone il processo chiamante allo stato READY. puoi dirmi quali sono le race condition nel mio caso? quale utilità può avere porre il processo figlio allo stato ready? Ultima modifica di VegetaSSJ5 : 13-07-2004 alle 19:18. |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quando invochi la fork, normalmente il controllo passa al neonato processo child. Non c'è una regola per stabilire chi deve continuare (padre o figlio), ma su linux normalmente si preferisce così. Se questo accade, il figlio continua mentre la fork del padre non è ancora ritornata (in quanto il controllo è passato al figlio). Il figlio quindi continua per la sua strada e...legge automobili[i].
>> Domanda: se il fork del padre ancora non è ritornato, cosa c'è dentro automobili[i]? ![]() sched_yield è documentato nelle pagine man, che ti consiglio di leggere ![]()
__________________
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 |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
![]() ![]() ![]() |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:36.