Debugging. Tore Berg Hansen, TISIP



Like dokumenter
1. Å lage programmer i C++

1. Å lage programmer i C++

Del 4 Noen spesielle C-elementer

Dagens tema: Enda mer MIPS maskinkode

Hvordan en prosessor arbeider, del 1

Tilstandsmaskiner kalles på engelsk for Finite State Machines.

Argumenter fra kommandolinjen

Finne ut om en løsning er helt riktig og korrigere ved behov

TDT4102 Prosedyreog objektorientert programmering Vår 2016

1. NetBeans IDE: Lage en enkel mobilapplikasjon

2 Om statiske variable/konstanter og statiske metoder.

Finne ut om en løsning er helt riktig og korrigere ved behov

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

Programmeringsspråket C Del 3

Kom i gang med programmering i Java

Kapittel 1 En oversikt over C-språket

Programmeringsspråket C Del 3

2 Om statiske variable/konstanter og statiske metoder.

oppgavesett 4 INF1060 H15 Øystein Dale Hans Petter Taugbøl Kragset September 22, 2015 Institutt for informatikk, UiO

Programmering i C++ Løsningsforslag Eksamen høsten 2005

TDT4110 Informasjonsteknologi, grunnkurs Uke 35 Introduksjon til programmering i Python

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

Programmeringsspråket C Del 3

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Dagens tema: 12 gode råd for en kompilatorskriver

Programmeringsspråket C Del 3

Læringsmål og pensum. v=nkiu9yen5nc

En oppsummering (og litt som står igjen)

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Introduksjon til DARK assembly

Obligatorisk Innlevering 2

Soloball. Introduksjon. Steg 1: En roterende katt. Sjekkliste. Skrevet av: Geir Arne Hjelle

Oppbygningen av en datamaskin Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

NOTAT (pensum!) Javas klasse-filer, byte-kode og utførelse. INF 5110, 10/5-2011, Stein Krogdahl

Sprettende ball Introduksjon Processing PDF

TDT4102 Prosedyre og Objektorientert programmering Vår 2015

Øving 0 - Xcode TDT4102

TDT4110 Informasjonsteknologi grunnkurs: Uke 41: «Matlab programs» (kapittel 6)

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Operativsystemer og grensesnitt

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

INF5110. Oblig 2 presentasjon

Dagens tema INF2270. Cs preprosessor. Separat kompilering av C funksjoner. C og minnet. Dag Langmyhr,Ifi,UiO: Forelesning 5. februar 2007 Ark 1 av 15

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Dagens tema: 12 gode råd for en kompilatorskriver. Sjekking av navn. Lagring av navn. Hvordan finne et navn?

Kanter, kanter, mange mangekanter

INF Obligatorisk innlevering 5

INF Uke 10. Ukesoppgaver oktober 2012

Eivind Gard Lund. 24. Mars 2009 Foilene bygger på 2009 utgaven av Andreas Svendsen

NOTAT (pensum!) Javas klasse-filer, byte-kode og utførelse

7034 Trondheim - NTH 1.1 KILDEPROGRAM S KOMPILERING OG ASSEBMLERING S LENKING AV OBJEKTFILER S UTFØRELSE AV PROGRAMMET S.

TDT4110 Informasjonsteknologi grunnkurs: Kapittel 1 Introduksjon til Programmering og Python. Professor Alf Inge Wang

INF Oblig 2 semantikksjekk og kodegenerering

Program delegate. Lage et nytt prosjekt i Visual Studio

EGENDEFINERTE FUNKSJONER I SAS OG LITT OM OPEN SOURCE INTEGRASJON SAS FANS I STAVANGER , MARIT FISKAAEN (SAS INSTITUTE)

Programmeringsspråket C Del 2

MERK: DU MÅ IKKE PRØVE Å INSTALLERE PROGRAM- VAREN FØR DU HAR LEST DETTE DOKUMENTET.

Jentetreff INF1000 Debugging i Java

Forkurs INF1010. Dag 2. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 14.

Konvertering av klientdata fra Sticos A rsoppgjør 2011 til Total A rsoppgjør 2012

Litt om Javas class-filer og byte-kode

Programmeringsspråket C Del 2

Programmeringsspråket C Del 2

PLS PC-øving nr. 3 Global Label og Local Label, flagg og CJ

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

Fra Python til Java, del 2

1. Grunnleggende C Introduksjon til kurset og til C++ Innhold

Øving i Tornado og VxWorks

Løse reelle problemer

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Soloball. Steg 1: En roterende katt. Sjekkliste. Test prosjektet. Introduksjon. Vi begynner med å se på hvordan vi kan få kattefiguren til å rotere.

Dagens tema C, adresser og pekere

Ark 3 av 26. printf("i adresse %08x ligger b med verdien %d.\n", &b, b); printf("i adresse %08x ligger a med verdien %d.

Denne oppgaven innfører funksjoner, og viser hvordan vi kan skrive og teste funksjoner i Ellie.

Oversikt. Introduksjon Kildekode Kompilering Hello world Hello world med argumenter. 1 C programmering. 2 Funksjoner. 3 Datatyper. 4 Pekere og arrays

Programmeringsspråket C

INF uke 2. Inputt, beslutninger, kontrollflyt og prosedyrer

INF 1000 høsten 2011 Uke september

Den siste dagen. Pensumoversikt Hovedtanker i kurset Selvmodifiserende kode Overflyt Veien videre... Eksamen

TDT4102 Prosedyre og Objektorientert programmering Vår 2015

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Del 1 En oversikt over C-programmering

Sprettende ball. Introduksjon: Steg 1: Vindu. Sjekkliste. Skrevet av: Sigmund Hansen

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

Dagens tema. Datamaskinenes historie. De første moderne datamaskiner. Løsning. Menneskene har alltid prøvd å lage maskiner for å løse sine problemer.

Kom i gang 1: Lage en enkel tavle for å skrive

Om du allerede kjenner Scratch og har en Scratchbruker kan du gå videre til Steg 1.

Husk at du skal ha to vinduer åpne. Det ene er 'Python Shell' og det andre er for å skrive kode i.

HØYSKOLEN I OSLO, AVDELING FOR INGENIØRUTDANNING

Introduksjon...5. Systemkrav...7. For Windows...9

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet (kalt kildekoden): Hva er kompilering?

Viktig. Rettet i koden. Obligatorisk oppgave 2 Litt flere detaljer om semantikksjekk og kodegenerering. Semantikksjekk

Installere JBuilder Foundation i Mandrake Linux 10.0

Kanter, kanter, mange mangekanter. Introduksjon: Steg 1: Enkle firkanter. Sjekkliste. Skrevet av: Sigmund Hansen

Transkript:

Debugging Tore Berg Hansen, TISIP

Innhold Innledning... 1 Å kompilere og bygge et program for debugging... 1 Når debugger er i gang... 2 Symbolene i verktøylinjen... 3 Start på nytt... 3 Stopp debugging... 3 Avbryt... 3 Step over... 3 Step ut av... 3 Step inn i... 4 Vis neste setning... 4 QuickWatch... 4 Debugg vinduer... 4 Watch... 4 Variabler... 5 Registers... 5 Memory... 6 Call stack... 6 Dissassembly... 6 Andre menyvalg som berører debugger... 7 Et lite eksempel... 9 i

Innledning Debugging er prosessen med å lokalisere hvor i koden årsaken til at et program eventuelt feiler ligger. Deretter kan feil rettes. Debugging gjøres på programmer som ikke feiler under kompilering og lenking. Det vil si at programmer kjører, men leverer ikke forventede resultater. En debugger er et verktøy som kan hjelpe til med å lokalisere feilkildene. Med en debugger kan man kjøre et program linje for linje sette stopp-punkter (breakpoints) for så å kjøre programmet frem til disse overvåke innholdet i variabler sette nye verdier i varibler evaluere uttrykk endre kode For at man skal kunne gjøre dette i et program blir kode for debugging lagt til programmet. Dette gjør at programmer med debugger ikke vil være optimalisert verken for plass eller hastighet. Når programmer virker uten å feile vil man kompilere og bygge en frislippversjon som er optimalisert etter ønskede kriterier som kan være f.eks hastighet. Vi skal i dette notat se nærmere på debuggeren i Visual Studio. Den har de fleste muligheter vi kan ønska av en debugger. Å kompilere og bygge et program for debugging Visual Studio gir mulighet for å kompilere å bygge et program i to versjoner, enten for frislipp eller for debugging. Det bestemmer man ved å gå inn på menyvalget Build og deretter klikke på Set Active Configuration Da kommer denne dialogen opp som er selvforklarende. 1

Etter at konfigurasjon er valgt bruker man de samme kommandoer til å kompilere, bygge og kjøre. Skal man derimot debugge går man inn i Build menyen og klikker deretter på Start Debug. Da får man flere alternativer: Go programmet vil kjøre til slutt hvis det ikke er noen stopp-punkter. Step Into går til første linje i programmet og stopper. Run to Cursor kjører til der cursor står i kildekoden. Attach to Process - kobler debugger til en prosess som kjører. Prosessen kan så avbrytes og debugges. Det finnes også to andre muligheter. Man kan bruke spesielle funksjonstaster eller klikke på symboler på verktøylinjen. Funksjonstastene er F5 for Go, F11 for Step Into og CTRL-F10 for Run to Cursor. Symbolene i verktøylinjen er som vist på denne figuren: Bygg Stopp bygg Go Kompiler Kjør program Sett/fjern stopp-punkt Når debugger er i gang Når debugger er i gang vil menyvalget Debug overta for Build. Det kommer også opp en flytende verktøylinje for debugger som er et alternativ til menyvalget Debug. Verktøylinjen er vist i neste figur. 2

Bruk kode endring Avbryt Stopp debugging Vis neste setning Step inn i Step over Step ut av Start på nytt Run to Cursor QuickWatch Watch Registre Stakk Dissassembly Variabler Minne Åpning/lukking av vinduer Den flytende verktøylinjen kan dokkes. Vi skal se nærmere på hva som skjuler seg bak symbolene og dermed hva vi kan gjøre i debuggeren. Symbolene i verktøylinjen Her skal vi se på symbolene som ikke er behandlet tidligere. Start på nytt Begynner igjen på første linje i programmet hvor det stopper. Programmer lastes på nytt sli at alle verdier blir satt på nytt. Stopp-punkter beholdes. Stopp debugging Avslutter debugging. Programmet er klart til å starte på nytt. Avbryt Stopper programmet der det er i øyeblikket. Kan være nyttig hvis programmer kjører lenge. Step over Kjører en og en instruksjon i programmet. Når det treffes på en funksjon, blir den utført. Men man går ikke trinn for trinn i funksjonen. Step ut av Kjører ut av en funksjon. Stopper på instruksjonen rett etter kallet til funksjonen. Denne kan brukes for å hoppe kjapt ut av en funksjon etter å ha påvist at en feil ikke er inne i funksjonen. 3

Step inn i Går trinn for trinn gjennom programmet. Går også inn i en funksjon når den påtreffes og fortsetter trinn for trinn inne i funksjonen. Vis neste setning Viser neste setning i programkoden. Hvis kildekode ikke er tilgjengelig vises setningen i et dissassembly vindu. QuickWatch Viser QuickWatch vinduet hvor man kan legge inn utrykk. Dette er QuickWatch vinduet. Her har vi lagt inn uttrykket a*b og klikket på Recalculate. Hvis vi nå klikker på Add Watch vi utrykket bli lagt inn i Watch vinduet, hvor det kan overvåkes. Debugg vinduer Debuggeren har disse vinduene som man kan åpne eller lukke ved å klikke på symbolene i verktøylinjen: Watch Viser navn og verdier for variabler og utrykk. Man kan legge dette inn i fire forskjellige vinduer. På den måten kan man gruppere de data man ønsker å overvåke. Slik er det mulig å få bedre oversikt, f.eks hvis man skal overvåke mange data som kan være lokalisert til forskjellige moduler i programmet. Neste figur viser Watch vinduet. 4

Når en verdi skifter farge til rødt indikerer det en nylig endring i verdi. Vinduet har form av et regneark. Man kan sette inn på navn og verdier. Variabler Vinduet viser informasjon om variabler. Det er tre tagger. I Auto vises variabler brukt i nåværende og foregående setninger. Likeledes vises returverdier fra funksjoner. Locals har variabler som er lokale i den aktuelle funksjon man er inne i. This viser objektet pekt på av this. Her er et vindu fra en kjøring. Legg merke til hvordan tabeller vises. man kan ekspandere eller komprimere ved å klikke på + eller symbolene. En verdi angitt med rødt har nylig skiftet verdi. Registers Dette vinduet viser innholdet i CPU ens generelle registre og statusregistre. Derfor er innholdet avhengig av hvilken prosessor det kjøres på. Dette vinduer er interessant for de som driver med maskinnær programmering. Se figuren. 5

Memory Innholdet i datamaskinens lager (minne) vises i dette vinduet. Også dette vinduet er mest interessant ved maskinnær programmering. Call stack På norsk stakk. Det viser stakken med alle funksjonskall som er aktive. Sist kalte funksjon øverst. Legg også merke til at figuren viser at sist kalte funksjon inneholder et stopp-punkt og at programmet har stoppet der. Dissassembly. Her vises assembly kode for det kompilerte programmet. Kan være nyttig hvis kildekode ikke finnes. Det er også nyttig hvis det er flere kommandoer på samme linje i kildekode. I kildekoden kan man bare kjøre linje for linje, mens man i assemblerkoden kan kjøre kommando for kommando. 6

Figuren ovenfor viser et utsnitt av assembler koden for en funksjon hvor programmet er stoppet. Legg merke til at først kommer en linje fra kildekoden. Deretter følger assembly koden for denne linjen og så nest linje i kildekoden. I dette vinduet kan man gå kommando for kommando ved å klikke på Step inn i (Step Into). Andre menyvalg som berører debugger Edit og Breakpoints får frem denne dialogen: Den gir mulighet for å sette avanserte stopp-punkter i form av bl.a logiske uttrykk, som vist her 1. Man kan få programmet til å stoppe når 1 Under demonstrasjonen i klasserommet fikk vi ikke dette til å fungere. det skyldes at vi satte betingelsen før programmet var startet og ikke kvalifiserte uttrykket med aktuell fil. 7

en variabel endrer verdi når et uttrykk endrer verdi når et uttrykk er sant når første element i en tabell skifter verdi når første element i en tabell har en bestemt verdi når et bestemt element i en tabell skifter verdi når et hvilket som helst element i en tabell skifter verdi når et hvilket som av de n første elementene i en tabell skifter verdi når verdien i en peker sifter verdi når verdien i det det pekes på skifter verdi når en verdi i en bestemt lageradresse skifter verdi når e register endres når et registeruttrykk er sant Det er stort samme fremgangsmåte. Man klikker på Edit og deretter Breakpoints. Når dialogen spretter opp Data taggen. Uttrykk skrives inn i tekstboksen under Enter the expression to be evaluated. Klikk OK til slutt for å sette stopp-punktet. View og Debug Windows gir rask tilgang til de forskjellige vinduer. Tools, Options og Debug gir mulighet for å spesifisere forskjellige egenskaper for debuggeren. 8

Et lite eksempel Her er et veldig enkelt program. Det skal konvertere fra kilometer til engelske mile og nautiske mil. #include <iostream.h> int tilmile (double& kilometer); int tilnautiskmile (double& kilometer); void main( void ) { double antallkm; cout << "Sett inn antall km som skal konverteres --> "; cin>> antallkm; cout << antallkm << " km " << " er " << tilmile( antallkm ) << " engelske mile" << endl; cout << antallkm << " km " << " er " << tilnautiskmile( antallkm ) << " nautiske mil" << endl; } int tilmile( double& kilometer) { if (kilometer >= 0.0) { kilometer = kilometer / 1.609; return 1; } } return 0; int tilnautiskmile( double& kilometer) { if (kilometer >= 0.0) { kilometer = kilometer / 1.852; return 1; } } return 0; Konverteringen skjer i to forskjellige funksjoner. Vi kan tenke oss at disse funksjonene er skrevet av andre programmere og tilhører et bibliotek som vi har hentet de fra. Det vi tror er at resultatet av konverteringen returneres i funksjonen. Vi kjører programmet og får dette resultatet. 9

Dette er åpenbart feil. En inspeksjon av koden vil fort fortelle oss hvorfor, men la oss se hvordan vi kunne bruke debuggeren til å lokalisere feilkilden (buggen). Vi vil kjøre en test: Inndata 1km Forventet resultat 0.621504 mile og 0.539957 nautiske mil Setter stopp-punkter etter at data er lest inn og etter beregningene. I Watch vinduet vil vi overvåke verdien av konverteringene ed å se på uttrykkene antallkm / 1.609 og antallkm / 1.852 samt verdien av antallkm. Figuren viser situasjonen etter at programmer er stoppet ved første stopp-punkt. 10

Klikk her for å sette stopp-punkt Disse uttrykkene er skrevet direkte inn Så kjører vi frem til neste stopp-punkt og får denne situasjonen vist i et utsnitt. Det vi ser er at returverdien til funksjonen tilmile() er 1 og at antallkm har endret verdi. Det samme har uttrykkene. Så det er åpenbart at det er noe galt med funksjonene som gjør konverteringene. 11

Vi vil kikke nærmere på det som skjer i linjene som gjør utskriften og klikker på dissassemblervinduet. Neste utsnitt vier situasjonen etter at vi har gått trinn for trinn og stoppet etter kall til funksjonen tilnautiskmil(). Vi ser at uttrykkene igjen har skiftet verdi. Så det er i funksjonene det skjer. Dette får oss til å se nærmere på spesifikasjonene for funksjonene. De viser at den konverterte verdi returneres i argumentet ved referanseoverføring. Returverdien i funksjonen skal 12

indikere om det var en lovlig verdi eller ikke som ble overført. Det er den standard som er brukt. Vi kan altså ikke bruke funksjonene på den måten. Enten må vi lage nye funksjoner som foretar verdioverføring eller så må vi skrive om programmet slik at det bruker funksjonene riktig. I det første tilfelle må vi avvike en standard som gjelder og det bør vi antagelig ikke gjøre. Så i tillegg til å se på hvordan debuggeren kan brukes, ser vi også hvor viktig det er å sikre at man har forstått grensesnittet til funksjoner som skal gjenbrukes i nye sammenhenger. 13