Gå til hovedindhold
Version2 it for professionelle
Forsiden

Hovedmenu

  • It-nyheder
  • Blogs
  • It-job
  • It-firmaer
  • Whitepapers
  • Opret bruger
  • Log ind
Du kan logge ind med din e-mail-adresse
Der er forskel på store og små bogstaver i adgangskoden.
Glemt adgangskode?
Se kommentarer (28)
Emner

Andre strategier til debugging af C/C++ kode på Linux?

Af Peter Toft 18. april 2010 kl. 14:17

Jeg sidder og debugger en store klump C/C++ kode på en Linux-maskine - ca. 500.000 linier vel. Jeg er ved at være lidt muggen fordi mine normale debugging-værktøjer ikke giver hjælp om problemet. Lad mig lige forklare lidt mere om hvad jeg normalt laver af ulykker og hvordan jeg finder problemets rod. Jeg laver en del kode i C/C++ med malloc/new-kode og jeg har en sjat modul-tests, som kører fint. Der er "styr på" at al hukommelse frigives fint efter brug i de tilfælde.

Jeg har nu en segmenteringsfejl, hvor der er nul hjælp til hvor det sker. gdb/ddd har ingen "backtrace" information (kør "bt" efter fejlen sker) og ddd melder endda intern fejl. Jeg har prøvet at indkredse fejlen med

  • valgrind/valkyrie - som køre programmet uden ændringer. Langsomt med normalt super godt til at vise allokeringsfejl.
  • purify - kommercielt program, som ændrer link-fasen og instrumenterer koden.
  • insure++ - kommercielt program, som reelt omskriver koden og så oversætter den. For hver array-adgang indsættes kode som checker at index er lovligt eller ej. Og tilsvarende laves tonsvis af andre godt checks.

Her står jeg med fejl, som ikke findes med nogen af ovenstående. Er der nogle tools, som jeg har overset til "heavy"-debugging? Jeg er nok ikke interesseret i statisk kode-analyse her - kun dynamisk kodeanalyse.

Jeg er på vej til at rulle tilbage til gode gamle "printf" ![Eksternt billede](http://www.version2.dk/uploads/smil3dbd4d6422f04.gif" alt=")

Alle kommentarer modtages med stor interesse!

/pto

Send Tweet
Udskriv
Billede af Peter ToftOm Peter Toft

Peter Toft er senior specialist hos Renesas Mobile og har blogget om open source og Linux siden Version2's begyndelse. Blogger også jævnligt om andre sjove teknologi-områder.

Follow @petertoft

Kommentarer (28)

Opret en konto eller log ind for at følge indhold på Version2 - og bliv opdateret via e-mail eller rss

Følg kommentarer
Jonas Hansen 18. apr. 2010 - 16.15
 
gdb burde give mere

Bruger du fork eller lignende som kan forvirre gdb?

gdb burde altså kunne fortælle dig hvor i memory segfault'en sker.

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Peter Tofts billede
Peter Toft 18. apr. 2010 - 20.02
 
Re: gdb burde give mere

Nej - der er ikke forks i min kode.
Jeg har nu fået gdb til at fortælle om en fejl i 0x090c140e in colon_greater ()
at ...build-gcc-4.2.4/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_iterator.h:652

... og ingen oplagt kobling til min egen kode.

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Jacob Christian Munch-Andersen 18. apr. 2010 - 20.40
 
Godt det ikke er mig

Hvor i alverden får man 500000 linjer kode, samt det utaknemmelige job at debugge skidtet fra?

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Peter Tofts billede
Peter Toft 18. apr. 2010 - 22.04
 
Re: Godt det ikke er mig

Det er faktisk 750.000 linier - det meste er autogenereret fra et udviklingsværktøj vi bruger

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
michael rasmussen 18. apr. 2010 - 22.52
 
Re: Godt det ikke er mig

Debugge autogenereret kode er en lidet missundelsværdig aktivitet:-) Held og lykke (du behøver det!)

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Morten Andersen 18. apr. 2010 - 22.53
 
Lidt tips

Hvilken type segmenteringsfejl - adresse 0x0 eller noget mere obskurt?

Af det du har kopieret kunne det se ud til at fejlen udløses i C standardbiblioteket. Dog undrer referencen til colon_greater mig, da der kun er ganske få hits på dette navn via Google (ingen i Google code) - så ville tro det kommer andetsteds fra. Måske dette er et clue?

Viser gdb virkelig ikke et trace af call stacken? Det undrer mig meget - men i så fald kan du blive nødt til at gå stakken igennem manuelt og 'bladre tilbage' til du finder en instruktionspointer der ligger indenfor din egen kode.

Selvom fejlen udløses i C standardbiblioteket er den jo nok i den kaldende kode. Evt. i parametrene til selve kaldet eller også via memory corruption i omkringliggende kode. Nu siger du godt nok du bruger en del værktøjer til at checke for dette. Men i hvert fald valgrind (har ikke erfaring med de andre programmer) laver ikke boundschecking på arrays allokeret på stakken ligesom en del andre typer fejl der kan lede til memory corruption heller ikke altid fanges.

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Peter Tofts billede
Peter Toft 19. apr. 2010 - 00.11
 
Re: Lidt tips

Hej Morten - der kom kun det ud du ser ovenfor. Hvad mener du konkret med bladre tilbage?

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Poul-Henning Kamps billede
Poul-Henning Kamp 19. apr. 2010 - 00.38
 
ptrace/strace/ktrace

Prøv at køre programmet med en syscall-tracer og se hvad det/de sidste syscalls før crashet er, det giver ofte et ret godt indtryk af hvor i koden du var da det væltede.

Poul-Henning

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
michael rasmussen 19. apr. 2010 - 00.40
 
Re: Lidt tips

Har du prøvet en anden version af GCC? Måske anvender det autogenererede kode funktionalitet, der har været deprecated længe, og som helt er forsvundet i din version af GCC, så derfor: Kan programmet køre, hvis det er oversat med GCC-3.4?

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Lasse Reinholt 19. apr. 2010 - 03.06
 
Re: Lidt tips
Hej Morten - der kom kun det ud du ser ovenfor. Hvad mener du konkret med bladre tilbage?

Nogle gange er stacken corrupted/overskrevet (fx ved at skrive udover et lokalt array), så kan gdb ikke vise nogen backtrace.

Du kunne så dumpe stackindholdet manuelt og lede efter begyndelsen på en tidligere stack frame, fx ved at kikke efter en kodeadresse, og sætte gdb til at anvende denne.

Ellers er der kun én udvej: http://www.mcdcareers.co.uk/html/apply.htm

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Rasmus Kaae 19. apr. 2010 - 08.05
 
debug?

Har du prøvet at kigge i koden og indkredse rent logisk hvor du antager fejlen opstår. Når du har gjort det kan du med fordel steppe igennem via debuggeren :)

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Frederik Ellehøj 19. apr. 2010 - 08.27
 
colon_greater ()

Det lugter af et STL problem. Har du prøvet at benytte checked STL? Det kunne være du kunne fange fejlen på den måde.

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Kim Djernæs 19. apr. 2010 - 08.40
 
Signal handlers

Jeg udvikler normalt på x86 men target-platformen er noget andet.
Derfor har jeg altid sat signal handlers op for seg-faults etc.
Jeg har så implementeret stack rewind til de forskellige platforme skrevet til log-fil.
Det kan jeg så holde op imod mapfilen uanset platform og uanset om det er i test/udviklings-sammenhæng eller i released kode (I sidstnævnte opstår der jo aldrig fejl :-)).

Men... efter som GDB ikke kan hjælpe er du jo nok ude i en vild-faret pointer eller noget stack-korruption.

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Bob Hagenstrup 19. apr. 2010 - 11.12
 
Compiler

Du kunne prøve at skifte compiler. Man kan få gratis trial af ICC til Linux.

Bruger du STL helpers/extensions til GDB?

Hvis ikke så kunne du kigge på GCC 4.5 som har fået indbygget support for python prettyprinters til debugging af STL kode. Se GCC 4.5 changelog på http://gcc.gnu.org/gcc-4.5/changes.html

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Lasse Makholm 19. apr. 2010 - 12.09
 
-O?

Du bygger ikke med optimering, vel?

Prøv evt. gdb og/eller gcc i nyere/ældre/anderledes version(er)...

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Lasse Makholm 19. apr. 2010 - 12.16
 
Assumptions...

Iøvrigt er det jo slet ikke sikkert at fejlen er i "din" kode... Det ville ikke være første gang at en klump autogenereret kode sender gcc på eventyr...

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
bo jensen 19. apr. 2010 - 14.51
 
Shared objects

Jeg har oplevet et lignende symptom med segfaults/debugger problemer.

.. i mit tilfælde var der uoverensstemmelse mellem header for shared objects og den '.so' der blev loaded.

.. check library path.
.. kør ldconfig ved ændringer.

( undskyld hvis det var trivielt, men symptomerne lignede meget )

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Thorbjørn Andersen 19. apr. 2010 - 18.55
 
Måske er jeg bare Windows-agtig

Dog ville jeg sandsynligvis prøve at debugge med et gui-værktøj som kdevelop - og sætte breakpoints og se hvor langt koden når.

(Umiddelbart ville jeg forestille mig, at det gik hurtigere end printf metoden, hvor man hele tiden skal rette og genkompilere ....)

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
michael rasmussen 19. apr. 2010 - 19.46
 
Re: Måske er jeg bare Windows-agtig

Hvorfor ikke blot Kgdb?

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Kim Nielsen 19. apr. 2010 - 22.09
 
Re: ptrace/strace/ktrace

Eller også hvis programmet er multitrådet kan man feks. bruger http://i1.dk/mta/. Det har jeg brugt et par gange

/Kim

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Mogens Dybæk Christensen 19. apr. 2010 - 22.31
 
Kodegenerator - ny eller velkendt

Hvor meget erfaring har du med det tool, der har genereret koden? Modenhed?

Måske duer det bare ikke? ;-)

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Peter Andreasen 19. apr. 2010 - 23.00
 
Re: Lidt tips

Std. disclaimer^Wexcuse: jeg sidder til daglig med PowerPC så det der x86 er lidt rustent. Men altså. Hvis nu vi har

[code=c]
bool evil()
{
intx=(int)alloca(1);
*(x+11)=0;
__asm("ud2");
}

void no()
{
evil();
}

void _do()
{
no();
}

void google()
{
_do();
}

int main()
{
google();
}

[/code]

så ser det sådan her ud hos mig:

[code=text]
petera-segarally:~/txy$ g++ -o t -g t.c
petera-segarally:~/txy$ gdb ./t
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".

(gdb) run
Starting program: /home/petera/txy/t

Program received signal SIGILL, Illegal instruction.
evil__Fv () at t.c:5
5 __asm("ud2");
(gdb) bt
#0 evil__Fv () at t.c:5
#1 0x00000000 in ?? ()
(gdb)
[/code]

Og så er gode dyr som bekendt rådne. Men hvis vi gør som Lasse og Morten foreslår:

[code=text]
(gdb) x/16x $ebp
0xbfaf8fa8: 0xbfaf8fb8 0x00000000 0xb7ff8ff4 0x080497fc
0xbfaf8fb8: 0xbfaf8fc8 0x0804851b 0xbfaf9064 0xb7ff8ff4
0xbfaf8fc8: 0xbfaf8fd8 0x0804853b 0xb7e41c8c 0xb7f63ff4
0xbfaf8fd8: 0xbfaf8fe8 0x0804855b 0x00000000 0xb7ff8cc0
(gdb) info symbol 0x0804851b
_do(void) + 11 in section .text
(gdb) info symbol 0x0804853b
google(void) + 11 in section .text
(gdb) info symbol 0x0804855b
main + 11 in section .text
(gdb)
[/code]

.. kan vi spadsere igennem stakken. Selv går vi glip af den stakframe som blev overskrevet, men vi har da "main", "google", "_do", XXXX og "evil". Så måske vi kan regne XXXX ud fra konteksten :-).

Bemærk at på $ebp begynder en kæde af links ned igennem stakken. Lige efter links'ne i kæden ligger den tilhørende kode adresse (kan nemt kendes da den hedder 0x080.... som synes at være der min kode ligger i dag).

Selvfølgelig kan der være sket mange andre ting i dit tilfælde. Men ovenstående illustrerer forhåbentlig hvad der menes med at gå stakken igennem manuelt.

Åhh. Nu er jeg spændt på hvad Version2's kommentar-system gør ved mine fine kode snippets :-)....

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Peter Tofts billede
Peter Toft 19. apr. 2010 - 23.40
 
Re: Måske er jeg bare Windows-agtig

kgdb og kdevelop er ligesom ddd frontends til gdb - dvs. man kan ca få lige så meget stack og kalde info i dem alle. Jeg ved godt at der er lidt forskelle, men ca...

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Peter Tofts billede
Peter Toft 19. apr. 2010 - 23.42
 
Re: -O?

Optimering er altid giftigt - nogle gange forsvinder der kode og variable, som bare ikke må forsvinde. Det er jeg med på og har smidt det ud

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Lars Tørnes Hansen 19. apr. 2010 - 23.58
 
Strategier til debugging

Det lyder simpelt, men prøv at static compile programmet og uden optimeringer.

strace (tracing af systemkald) med Ubuntu:
http://manpages.ubuntu.com/manpages/karmic/man1/strace.1.html
Nu er du er ikke lige newbie ud i programmering, men der er god hjælp her til andre som måtte læse med og vil bruge strace:
https://wiki.ubuntu.com/Strace

Kig i i log filer: syslog, messages, og user.log i /var/log.

Bruger dit program for meget RAM lukker kernen dit program ned. 'for meget' er relativt til mængden af fri hukommelse.

Tror du at fejlen har noget med kernen at gøre, så kør (som root):
echo N > /proc/sys/kernel/printk
for at få mere debugging information ud af kernen.
N er et tal er mellem 0 til 8 incl. ( er flest debugging beskeder. 0 er kun de mest kritiske beskeder.

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Morten Andersen 20. apr. 2010 - 14.55
 
Bladre tilbage og colon_greater

Lasse og Peter's beskrivelser er gode forklaringer af hvad jeg mente med 'bladre tilbage' :)

Jeg studser stadigvæk over det der colon_greater(), har du fået kigget mere på det?

Jeg har iøvrigt før været ude for at debuggeren har oplyst et forkert funktionsnavn som synderen (i.e. maskinkodeinstruktionen der udløste fejlen befandt sig ikke kodemæssigt i den oplyste funktion). Hvordan det kan ske er mig en gåde, men har aldrig haft tid til at undersøge det nærmere. Antageligt er der tale om fejl i debuggeren eller om en meget uheldig korruption af stack der fører til forkert fortolkning fra debuggerens side. Alternativt korruption af debuggerens memory-strukturer.

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Peter Tofts billede
Peter Toft 21. apr. 2010 - 23.11
 
Got it ...

Jeg har nu vundet. I mit tilfælde havde jeg en stabil kodebase - hvorefter jeg havde lavet en solid mængde ændringer i noget plain C/C++ kode OG en lille ændring i noget "andet" som skal autogenereres og linkes ind i min kode.

Efter 10 timers debug-øvelse, der kørte efter melodien;
* Hvad melder valgrind/valkyrie?
* Melder purify noget andet?
* Hvad melder Insure++?
* Flere unit tests
* Fuld clean up i memory space etc.
* Forsøg med at allokere mindre hukommelse og lignende
* Reducere mine ændringer ned mod den kendte valide tilstande af koden.

Desværre brugte jeg det meste af tiden i min kode, men i sidste del - hvor jeg trækker mine ændringer ud en for en, pludselig stod jeg med nul ændringer i min kode og kun lille ændring i noget "andet".

Det "andet" var ude af min kontrol og det har været stabilt i de sidste 5+ år. Men her endte jeg med en testcase, som skal riples ud til nogle andre glade kodedrenge som sikkert bliver glade for at få en fejltest i deres kode i noget de helt sikkert har glemt alt om :)

Jeg vil gerne takke jer alle - og en masse offline mails fra mange spændende personer - angående emnet.

/pto

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Morten Andersen 4. maj. 2010 - 20.11
 
colon_greater

Godt det er løst. Mon ikke colon_greater befandt sig i "det andet" (som sikkert er parser-relateret).

  • Stem op 0
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer

Tilføj kommentar

Opret en konto eller log ind for at følge indhold på Version2 - og bliv opdateret via e-mail eller rss

Følg kommentarer
Log ind herunder eller opret en bruger for at skrive kommentarer
Du kan logge ind med din e-mail-adresse
Der er forskel på store og små bogstaver i adgangskoden.
Glemt adgangskode?

Seneste nyt

Teenager står frem: Derfor hackede jeg Version2

Udgivet 17. maj 16.40Opdateret 17. maj 16.40

Fredagshumor: Sådan ser indbakkens pestilenser ud i virkeligheden

Udgivet 17. maj 15.00Opdateret 17. maj 15.00

New Zealand dropper softwarepatenter

Udgivet 17. maj 14.09Opdateret 17. maj 14.09

Microsoft gemmer udspekuleret jobanonnce på Bing

Udgivet 17. maj 11.35Opdateret 17. maj 11.35

Ny wifi-standard med gigabit-hastighed er en gave til it-chefen

Udgivet 17. maj 10.54Opdateret 17. maj 10.54

Flere it-nyheder »

Tilmeld dig Version2's it-nyhedsbrev og vind den nye iPad.

Seneste debat

  1. Teenager står frem: Derfor hackede jeg Version2

    32 comments.
    Last update 4 timer 13 minutter
    Skrevet af Jesper Hedemann
  2. Retten er sat: Kusine stævner fætter om familiedomænet

    33 comments.
    Last update 6 timer 53 minutter
    Skrevet af Jesper Lund
  3. CPR.dk affejer hacker-video på Youtube som uinteressant: "Vi er sikre nok"

    10 comments.
    Last update 11 timer 19 minutter
    Skrevet af Hans-Michael Varbæk
  4. Microsofts talknusere: Danmark vinder Melodi Grand Prix

    9 comments.
    Last update 12 timer 6 minutter
    Skrevet af Jacob Smedegård
  5. Hackere på Version2

    14 comments.
    Last update 12 timer 8 minutter
    Skrevet af Hans-Michael Varbæk
  6. Hvorfor blev min disk fyldt op?

    20 comments.
    Last update 13 timer 36 minutter
    Skrevet af Peter Toft
  7. New Zealand dropper softwarepatenter

    6 comments.
    Last update 14 timer 46 minutter
    Skrevet af Jørgen Henningsen
  8. Sådan kommunikerer du uden at afsløre din identitet

    23 comments.
    Last update 1 dag 1 time
    Skrevet af Kristian Klausen

Mere debat »

Information

  • Kontakt redaktionen
  • Job- og annoncesalg
  • Teknisk support
  • Om Version2
  • Brugerbetingelser
  • Cookie- & privatlivspolitik

Aktuelle emner

  • Agil udvikling
  • Business Intelligence
  • Cloud computing
  • Intranet
  • It-sikkerhed
  • NemID
  • Open source CMS
  • Projektledelse
  • Scrum
  • Sharepoint intranet
  • Storage
  • Ubuntu
  • Virtualisering
  • Windows 8
  • Windows Server 2012
  • iOS 6
  • iPhone 5

Tjenester

  • iPhone-app
  • RSS-feeds
Følg @version2dk
Tilmeld dig Version2's it-nyhedsbrev og vind den nye iPad.

Version2 udgives af

  • Mediehuset Ingeniøren A/S work Trekronergade 26 2500 Valby
  • Tlf. work 33265300