Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C++] segfault die verdwijnt door valgrind te gebruiken

Pagina: 1
Acties:

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 16:51
Ik ben bezig met een programma waarbij het LZW compressie en decompressie algoritme wordt gebruikt. Op zich werkt dat best goed, alleen zit ik met een extreem wazige bug die ik niet op kan lossen.

In de decompressie-functie wordt er gebruik gemaakt van een Map (int, string) (en een Trie) om de dictionary op te slaan. In de loop die de input verwerkt wordt er een lookup gedaan:

C++:
1
k = dict.find(input)->second;


Dit gaat meestal goed, totdat in sommige testfiles er ineens een segmentation fault optreedt.
Door het toevoegen van debug output kwam ik erachter dat er een corrupte string terug komt uit de map in zeldzame gevallen. Als ik kijk hoe lang die string is dan kom ik uit op een string van lengte 134695976. Het verbaast mij niet dat dit een segfault oplevert natuurlijk, maar hoe het komt, ik heb geen idee.

Toen ik met valgrind wilde gaan kijken wat er precies gebeurde bij de segfault merkte ik echter nog iets veel vreemders. Het gebruikt van valgrind zorgt ervoor dat het programma een foutloze outputfile wegschrijft. Het gaat dus helemaal goed ineens. Heeft iemand een idee wat er hier aan de hand is? Ik snap het echt niet meer op het moment.

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ah, de welbekende "Heisenbug" ;).

Klinkt als een uninitialized variabele, die door het gebruik van valgrind toevallig wel goed geïnitialiseerd wordt (eigenlijk wordt die variabele natuurlijk alsnog niet geïnitialiseerd, maar het geheugen heeft toevallig al een goede waarde)

[ Voor 29% gewijzigd door .oisyn op 13-12-2007 22:23 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Tux schreef op donderdag 13 december 2007 @ 22:00:
Door het toevoegen van debug output kwam ik erachter dat er een corrupte string terug komt uit de map in zeldzame gevallen.
Debug output? Waarom start je niet gewoon de debugger en kijk je dan wat er aan de hand is?

  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 16:51
Met een debugger krijg ik ook al niet veel meer inzicht in wat er fout gaat. Daar komt de segfault ook ineens uit de lucht vallen zonder enige waarschuwing (zelfs als ik instructie voor instructie erdoorheen loop en ongeveer elke variabele e.d. bekijk).

Ik heb trouwens geen variable kunnen vinden die uninitialized was.

Heb nu een ranzige hack erin gemaakt om alle strings met een idiote lengte gewoon te negeren. Dat werkt voorlopig. Eerst drie andere hardnekkige bugs op zien te sporen :(

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


  • citegrene
  • Registratie: Februari 2006
  • Laatst online: 02-11 03:00
'\0' aan het eind van een string toevoegen?
of heb je wellicht ergens een lengte -1 of iets dergelijks staan?
en wat doe je met k in bovenstaande regel? Check je daarna nog of k wel iets terug geeft.

[ Voor 29% gewijzigd door citegrene op 13-12-2007 23:59 ]


  • ATS
  • Registratie: September 2001
  • Laatst online: 28-11 20:56

ATS

Zonder je code gezien te hebben lijkt het erop alsof je het resultaat van dict.find() gebruikt zonder te controleren of dat resultaat wel geldig is. Wat als input niet gevonden wordt? Of weet je zeker dat dat niet voor kan komen?

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 16:51
De inleesfunctie geeft -1 terug als ik EOF bereikt heb. Maar het gaat al eerder fout bij een dictionary code 1812 in het geval van het bestand dat ik nu test. Daarna komen nog enkele tientallen tekens.

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


  • citegrene
  • Registratie: Februari 2006
  • Laatst online: 02-11 03:00
misschien dat je kan laten zien hoe, je het bestand inleest.

  • ATS
  • Registratie: September 2001
  • Laatst online: 28-11 20:56

ATS

Tux schreef op vrijdag 14 december 2007 @ 00:10:
De inleesfunctie geeft -1 terug als ik EOF bereikt heb. Maar het gaat al eerder fout bij een dictionary code 1812 in het geval van het bestand dat ik nu test. Daarna komen nog enkele tientallen tekens.
Ik bedoelde niet wat er gebeurt als je een EOF tegen komt, maar wat er gebeurt in de regel code die je post op het moment dat de variabele "input" niet voorkomt in je dictionairy "dict". Dan derefence je een invalide pointer lijkt me. Of weet je zeker dat "input" écht in "dict" zit (bijvoorbeeld omdat je dat vlak voor die regel controleerd)?
Wat ik me ook af vroeg: wat doe je uiteindelijk met de string k? Doe je er toevallig iets mee waarmee je de dict zelf kapot zou kunnen maken? Zonder meer code te zien zit ik natuurlijk ook maar wat te gissen...

[ Voor 21% gewijzigd door ATS op 14-12-2007 07:10 ]

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Tux schreef op donderdag 13 december 2007 @ 23:39:
Met een debugger krijg ik ook al niet veel meer inzicht in wat er fout gaat. Daar komt de segfault ook ineens uit de lucht vallen zonder enige waarschuwing (zelfs als ik instructie voor instructie erdoorheen loop en ongeveer elke variabele e.d. bekijk).
Dan kijk je naar de inhoud van je segfault, en desnoods op assembly nivo. Segfaults komen niet uit de lucht vallen; er is altijd een geheugenaccess voor nodig. Welk adres, en waar komt het vandaan?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1