/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
strncmp segfault
Fra : Christoffer Olsen


Dato : 31-05-04 09:52

Hey

Jeg sidder lige og forbereder mig til eksamen i nogen kompiler-grej.

I den forbindelse prøver jeg at køre et løsningsforslag til en
tidligere opgave, der vist nok er blevet lavet på en windows-maskine
med bison og gcc (Jeg prøver at kompilere på en linux-box).

Mit problem er at strncmp segfaulter første gang den skal returnere
false, indtil da har det gået meget godt, her er koden for searchRes:

int searchRes()
{
int i = 0 ;

for ( i = 0 ; strncmp(yytext,resArray[i],99)!=0 && i<nextRes; i++);
if ( i < nextRes )
return resToken[i] ; /* found */
else return -1;
}

searchRes() når at blive kaldt 3 gange før, hvor den returnerer true,
med følgende ord:

int
main
int

og så går den ned på 'i', som er det fjerde ord.

Det hele stammer fra programstumpen:

int main()
{
int i;
...
...
}

Mit spørgsmål går egentlig på hvordan dælen det kan lade sig gøre at
strcmp bliver syg, når dens argumenter ser ud til at være ok?

Jeg tror ikke det er min maskine, jeg har også prøvet på en af mine
venners freebsd-maskine.

Her er backtrace fra gdb, yytext er et array og resArray er et array
af char*:

Breakpoint 1, searchRes () at te04a.y:452
452       for ( i = 0 ; strncmp(yytext,resArray[i],99)!=0 && i<nextRes; i++);
(gdb) print yytext
$4 = "i", '\0' <repeats 98 times>
(gdb) print resArray[i]
$5 = 0x40278ff8 "print"
(gdb) print nextRes
$6 = 6
(gdb) step

Program received signal SIGSEGV, Segmentation fault.
0x400a7c68 in strncmp () from /lib/tls/libc.so.6
(gdb) bt
#0  0x400a7c68 in strncmp () from /lib/tls/libc.so.6
#1  0x40166170 in timezone () from /lib/tls/libc.so.6
#2  0xbffff9a0 in ?? ()
#3  0x08049cc1 in searchRes () at te04a.y:452
#4  0x080495f5 in yylex () at te04a.y:237
#5  0x08048a29 in yyparse () at te04a.tab.c:1093
#6  0x08049f72 in main (argc=2, argv=0xbffffa14) at te04a.y:521

--
Mvh Christoffer


 
 
Byrial Jensen (31-05-2004)
Kommentar
Fra : Byrial Jensen


Dato : 31-05-04 10:43

Christoffer Olsen wrote:

> Mit problem er at strncmp segfaulter første gang den skal returnere
> false, indtil da har det gået meget godt, her er koden for searchRes:
>
> int searchRes()
> {
> int i = 0 ;
>
> for ( i = 0 ; strncmp(yytext,resArray[i],99)!=0 && i<nextRes; i++);
> if ( i < nextRes )
> return resToken[i] ; /* found */
> else return -1;
> }

Når i er lig nextRes laver du først en sammenligning, og returnerer
dernæst -1 uanset hvad sammenligningen gav som resultat.

> Mit spørgsmål går egentlig på hvordan dælen det kan lade sig gøre at
> strcmp bliver syg, når dens argumenter ser ud til at være ok?

Tja, man kunne forestille sig en eller form for hukommelse-relateret
fejl, f.eks. et bufferoverløb som er sket på et tidligere tidspunkt.
Sådanne ting kan vse sig på de underligste måder. Jeg ville prøve at
køre programmet under valgrind (http://valgrind.kde.org/) og se om det
fandt noget.

> Her er backtrace fra gdb, yytext er et array og resArray er et array
> af char*:
>
> Breakpoint 1, searchRes () at te04a.y:452
> 452 for ( i = 0 ; strncmp(yytext,resArray[i],99)!=0 && i<nextRes; i++);
> (gdb) print yytext
> $4 = "i", '\0' <repeats 98 times>
> (gdb) print resArray[i]
> $5 = 0x40278ff8 "print"
> (gdb) print nextRes
> $6 = 6
> (gdb) step
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x400a7c68 in strncmp () from /lib/tls/libc.so.6
> (gdb) bt
> #0 0x400a7c68 in strncmp () from /lib/tls/libc.so.6
> #1 0x40166170 in timezone () from /lib/tls/libc.so.6
> #2 0xbffff9a0 in ?? ()
> #3 0x08049cc1 in searchRes () at te04a.y:452
> #4 0x080495f5 in yylex () at te04a.y:237
> #5 0x08048a29 in yyparse () at te04a.tab.c:1093
> #6 0x08049f72 in main (argc=2, argv=0xbffffa14) at te04a.y:521

Christoffer Olsen (31-05-2004)
Kommentar
Fra : Christoffer Olsen


Dato : 31-05-04 11:39

Byrial Jensen <bjensen@nospam.dk> writes:

> Christoffer Olsen wrote:
>
> > Mit problem er at strncmp segfaulter første gang den skal returnere
> > false, indtil da har det gået meget godt, her er koden for searchRes:
> > int searchRes()
> > {
> > int i = 0 ;
> > for ( i = 0 ; strncmp(yytext,resArray[i],99)!=0 && i<nextRes; i++);
> > if ( i < nextRes )
> > return resToken[i] ; /* found */
> > else return -1;
> > }
>
> Når i er lig nextRes laver du først en sammenligning, og returnerer
> dernæst -1 uanset hvad sammenligningen gav som resultat.

Ja, og når jeg retter den falder det hele i hak. :)

Jeg rettede det til:

for ( i = 0 ; i<nextRes; i++)
if (strncmp(yytext,resArray[i],99)==0)
break;
if ( i < nextRes )
return resToken[i] ; /* found */
else return -1;

Det er vel egentlig nok bare at bytte rundt på de to...

> Tja, man kunne forestille sig en eller form for hukommelse-relateret
> fejl, f.eks. et bufferoverløb som er sket på et tidligere
> tidspunkt. Sådanne ting kan vse sig på de underligste måder. Jeg ville
> prøve at køre programmet under valgrind (http://valgrind.kde.org/) og
> se om det fandt noget.

Det var det så, Tak for hjælpen.

--
Mvh
Christoffer Olsen

http://my.opera.com/dev/discussion/openweb/20030206/

Byrial Jensen (31-05-2004)
Kommentar
Fra : Byrial Jensen


Dato : 31-05-04 11:48

Christoffer Olsen wrote:
> Byrial Jensen <bjensen@nospam.dk> writes:
>>Christoffer Olsen wrote:
>>
>>>Mit problem er at strncmp segfaulter første gang den skal returnere
>>>false, indtil da har det gået meget godt, her er koden for searchRes:
>>>int searchRes()
>>>{
>>> int i = 0 ;
>>> for ( i = 0 ; strncmp(yytext,resArray[i],99)!=0 && i<nextRes; i++);
>>> if ( i < nextRes )
>>> return resToken[i] ; /* found */
>>> else return -1;
>>>}
>>
>>Når i er lig nextRes laver du først en sammenligning, og returnerer
>>dernæst -1 uanset hvad sammenligningen gav som resultat.
>
> Ja, og når jeg retter den falder det hele i hak. :)
>
> Jeg rettede det til:
>
> for ( i = 0 ; i<nextRes; i++)
> if (strncmp(yytext,resArray[i],99)==0)
> break;
> if ( i < nextRes )
> return resToken[i] ; /* found */
> else return -1;
>
> Det er vel egentlig nok bare at bytte rundt på de to...

Ja, det havde været nok.

Jeg ville returnere med det samme efter at havde fundet et resultat for
at undgå at have (i < nextRes) sammenligningen 2 steder:
[Advarsel: utestet kode]

for (int i = 0 ; i < nextRes ; ++i)
{
if (strncmp (yytext, resArray[i], 99) == 0)
{
return resToken[i];
}
}
return -1; // Not found

Søg
Reklame
Statistik
Spørgsmål : 177459
Tips : 31964
Nyheder : 719565
Indlæg : 6408176
Brugere : 218881

Månedens bedste
Årets bedste
Sidste års bedste