[C/Linux => Minix] double free or corruption

Pagina: 1
Acties:
  • 53 views sinds 30-01-2008

  • Comp_Lex
  • Registratie: Juni 2005
  • Laatst online: 22:47
Hallo,

ik ben momenteel bezig met het schrijven van een shell onder Linux welke binnenkort wordt getest onder Minix 3.

Ik heb veel zaken al aan de praat, zoals I/O redirection, backgrounding ("&"), etc, maar het enige wat ik niet goed aan de praat krijg is het opzetten van een pijplijn tussen n processen. Ik krijg namelijk bij het herleiden de volgende foutmelding:

*** glibc detected *** double free or corruption (!prev): 0x0804b108 ***

Hieronder staat het voorbeeld in het boek Operating Systems van Tanenbaum:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define STD_INPUT 0
#define SD_OUTPUT 1
pipeline(process1, process2)
char *process1, *process2
int fd[2];

pipe(&fd[0]);
if (fork() != 0) {
  close(fd[0]);
  close(STD_OUTPUT);
  dup(fd[1]);
  close(fd[1]);
  execl(process1, process1, 0);
} else {
  close(fd[1]);
  close(STD_OUTPUT);
  dup(fd[0]);
  close(fd[0]);
  execl(process2, process2, 0);
}


Hierboven staat een beetje code voor communicatie tussen twee processen middels een pipe, maar dit is niet wat ik wil hebben, want het moet werken voor n processen zonder de exec in de parent process, omdat de shell dan vervangen wordt door een ander proces (je bent je shell kwijt). Wat ik dus doe is het volgende. Ik maak een char pointer array die naar alle commando's wijzen die 1 voor 1 in het child gedeelte worden uitgevoerd. Ik maak sowieso gebruik van een filedescriptor array die 2 maal zo groot is als het aantal commando's, zodat tussen de processen door wel alles gebuffered blijft met het pipe commando waarna alles weer afgesloten wordt en zowel stdin als stdout gedupt wordt zodat het alles weer teruggezet wordt naar het oude situatie.

Hieronder staat mijn code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
if (commandIndex == 0) {
                        pipe(&fd[0]);
                        pipe(&fd[2]);
                        stdoutfd = dup(STDOUT);
                        stdinfd = dup(STDIN);
                }
                else {
                        pipe(&fd[(commandIndex + 1) * 2]);
                }
                                
                if (fork() != 0) {
                        close(fd[commandIndex * 2]);
                        close(STDOUT);
                        dup(fd[(commandIndex * 2) + 1]);
                        close(fd[(commandIndex * 2) + 1]);
                        if ((background == 0) && (commandIndex == (maxPipe + 1))) {
                                waitpid(-1, &status, 0);
                        }
                }
                else {
                        close(fd[(commandIndex * 2) + 1]);
                        close(STDIN);
                        dup(fd[commandIndex * 2]);
                        close(fd[commandIndex * 2]);
                        if (commandIndex < (maxPipe + 1)) {
                                close(fd[(commandIndex + 1) * 2]);
                                close(STDOUT);
                                dup(fd[((commandIndex + 1) * 2) + 1]);
                                close(fd[((commandIndex + 1) * 2) + 1]);
                        }
                        else {
                                close(fd[((commandIndex + 1) * 2) + 1]);
                                dup(stdoutfd);    
                        }
                        execve(command, parameters, NULL);
                }
                close(fd[((commandIndex + 1) * 2)]);
                dup(stdinfd);


De foutmelding treedt op zodra de close functie direct onder de fork aangeroepen wordt.

EDIT:

ik kom er net achter dat close niks veroorzaakt. De foutmelding treedt direct na de fork op. Waarschijnlijk gaat er dan iets mis in het child gedeelte.

EDIT2:

De parameterlijst wordt dubbel gealloceerd. Waarschijnlijk gaat er dan iets fout als het gefreed wordt.

[ Voor 3% gewijzigd door Comp_Lex op 27-12-2007 01:01 ]


  • Comp_Lex
  • Registratie: Juni 2005
  • Laatst online: 22:47
Ik heb alles voor elkaar gekregen. Mijn shell ondersteunt nu ook pipes. Ik ga niet zeggen wat ik precies gedaan heb om er voor te zorgen dat niet iedereen klakkeloos mijn code gaat overnemen, maar ik kan wel zeggen dat de bovenstaande code redelijk fout is.

  • KopjeThee
  • Registratie: Maart 2005
  • Niet online
Comp_Lex schreef op zaterdag 29 december 2007 @ 00:50:
...Ik ga niet zeggen wat ik precies gedaan heb om er voor te zorgen dat niet iedereen klakkeloos mijn code gaat overnemen...
Off-topic:
Op zich gebeurt het vaker dat iemand na oplossing van een probleem (al dan niet met hulp van anderen), niet de gehele oplossing post. Maar wat nog minder vaak gebeurd, is dat dit argument wordt aangedragen. Je wilt wel dat bezoekers van dit forum je helpen bij dit probleem, waarna je de eventuele hints "klakkeloos" kunt toepassen. Maar als je zelf iets "briljants" verzint, dan mag opeens niemand het meer weten. Het wekt bij mij een beetje de indruk dat je vooral informatie/kennis wilt halen en niet wilt brengen. Een dergelijk houding lijkt mij slecht voor dit forum.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-01 23:51

NMe

Quia Ego Sic Dico.

Met KopjeThee. Als dit je instelling is dan moet je dat zelf weten, maar dan hoop ik maar dat dit je laatste topic in Programming was. Een forum is tweezijdig; we scratch your back, you scratch ours. Als je liever eenzijdige communicatie hebt zoek je maar een ander medium...

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Dit topic is gesloten.