<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="et">
	<id>http://www.lambda.ee/w/index.php?action=history&amp;feed=atom&amp;title=4._praktikum_-_Silumine_%28debugger%29</id>
	<title>4. praktikum - Silumine (debugger) - Redigeerimiste ajalugu</title>
	<link rel="self" type="application/atom+xml" href="http://www.lambda.ee/w/index.php?action=history&amp;feed=atom&amp;title=4._praktikum_-_Silumine_%28debugger%29"/>
	<link rel="alternate" type="text/html" href="http://www.lambda.ee/w/index.php?title=4._praktikum_-_Silumine_(debugger)&amp;action=history"/>
	<updated>2026-11-07T00:47:12Z</updated>
	<subtitle>Selle lehekülje redigeerimiste ajalugu</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>http://www.lambda.ee/w/index.php?title=4._praktikum_-_Silumine_(debugger)&amp;diff=9259&amp;oldid=prev</id>
		<title>Irve: Uus lehekülg: &#039;{{itv0020}} Labor on saadaval ka inglise keeles  See labor näitab kuidas saame programmi silumisprogrammi abil tema töö ajal lähemalt uurida....&#039;</title>
		<link rel="alternate" type="text/html" href="http://www.lambda.ee/w/index.php?title=4._praktikum_-_Silumine_(debugger)&amp;diff=9259&amp;oldid=prev"/>
		<updated>2012-09-27T13:34:46Z</updated>

		<summary type="html">&lt;p&gt;Uus lehekülg: &amp;#039;{{itv0020}} &lt;a href=&quot;/wiki/Exploring_Debugger_(ITI8510)&quot; title=&quot;Exploring Debugger (ITI8510)&quot;&gt;Labor on saadaval ka inglise keeles&lt;/a&gt;  See labor näitab kuidas saame programmi silumisprogrammi abil tema töö ajal lähemalt uurida....&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Uus lehekülg&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{itv0020}}&lt;br /&gt;
[[Exploring Debugger (ITI8510)|Labor on saadaval ka inglise keeles]]&lt;br /&gt;
&lt;br /&gt;
See labor näitab kuidas saame programmi silumisprogrammi abil tema töö ajal lähemalt uurida. Ühtlasi püüame pöördkomipleerida programmiga objdump.&lt;br /&gt;
&lt;br /&gt;
:debug - silumine&lt;br /&gt;
:decompilation - pöördkompileerimine&lt;br /&gt;
&lt;br /&gt;
== Kompileerimine ==&lt;br /&gt;
&lt;br /&gt;
Kuna kompilaator tahab vaikimisi ehitada kõige väiksema võimaliku käivituva faili (sellele lisaaega kulutamata), eemaldab ta failist info funktsioonide ja muutujate nimede kohta. (seda nimetatakse sümboltabeliks ([http://en.wikipedia.org/wiki/Symbol_table symbol table]). Sümboltabeli saame soovi korral faili alles jätta, kui kompileerimisel -g võtit kasutame.&lt;br /&gt;
&lt;br /&gt;
 gcc -g filename.c -o filename&lt;br /&gt;
&lt;br /&gt;
Siit ka vajadus ehitada edasiste kompileerimiste kiirendamiseks makefile. (Võtke selleks tõesti hetk, sest hoiate sellega tulevikus kokku aega ja närve)&lt;br /&gt;
&lt;br /&gt;
Miks vajame sümboltabelit? Debugger suudab selle abil silumise ajal väärtuslikku lisainfot pakkuda.&lt;br /&gt;
&lt;br /&gt;
Lühidalt: kui silud, kasuta -g võtit.&lt;br /&gt;
&lt;br /&gt;
== Siluja ==&lt;br /&gt;
&lt;br /&gt;
Kasutame käsureaprogrammi gdb - GNU Debugger. Tollel on ka graafiline liides, kuid selle üle X käima saamine on veidi keerulisem ja sinna me täna ei lähe. Oma arvutis võite sellega eksperimenteerida. GDB on väga võimas ja tegelikult ka üllatavalt lihtne kasutada.&lt;br /&gt;
&lt;br /&gt;
* [http://sources.redhat.com/gdb/current/onlinedocs/gdb.html GDB manuaal]&lt;br /&gt;
* Abi saamiseks võid gdb-s kirjutada &amp;quot;help&amp;quot; või &amp;quot;help &amp;#039;&amp;#039;käsunimi&amp;#039;&amp;#039;&amp;quot;. See meenutab käske ja nende süntaksit. Käske on väga palju, aga sellest ehmatada ei tasu, sest reaalselt kasutad neist nagunii väga väikest hulka.&lt;br /&gt;
&lt;br /&gt;
Kompileeritud programmi jooksutamiseks kirjuta:&lt;br /&gt;
 gdb programminimi&lt;br /&gt;
&lt;br /&gt;
Avaneb käsurida (gdb) ja midagi muud ei juhtugi. Programm ootab, et määraksid katkestuspunktid (breakpoint) ja vaatlejad (watches) ja kirjutaksid käsu &amp;quot;run&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Programmist väljumiseks kirjuta: &lt;br /&gt;
 quit&lt;br /&gt;
&lt;br /&gt;
== Programmi jooksutamine ==&lt;br /&gt;
&lt;br /&gt;
Ometi ei taha me väljuda. Programmi gdb-s käimalaskmiseks kirjutame käsu:&lt;br /&gt;
 run&lt;br /&gt;
&lt;br /&gt;
Programm jookseb kuni katkestad selle CTRL-C abil (mispuhul seiskub programm kusiganes ta parajasti oli ning saad tema mälupilti sellel ajahetkel uurida), programm lõpetab või jookseb kokku (&amp;#039;&amp;#039;Segmentation fault&amp;#039;&amp;#039;). Kokkujooksmine on selgelt kõige huvitavam, sest saad uurida kus see juhtus ning tutvuda stacki sisuga.&lt;br /&gt;
&lt;br /&gt;
Pärast &amp;quot;run&amp;quot; käsku võid lisada ka programmi argumendid.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039;: Jooksuta gdb abil mingi programm, siis jooksuta programm, mis jookseb kokku ja vaata mis juhtub.&lt;br /&gt;
&lt;br /&gt;
== Peatuspunktid ==&lt;br /&gt;
&lt;br /&gt;
Programmi teatud kohas peatamiseks võid sellele enne käivitamist katkestuspunkte lisada. Nendeks võivad olla funktsiooninimed, reanumbrid või koguni mõne kindla faili kindlad read. Vajadusel võid oma programmi peatada isegi siis kui too püüab mõnel kindlal mäluaadressil olevat instruktsiooni jooksutada.&lt;br /&gt;
&lt;br /&gt;
* break &amp;#039;&amp;#039;function&amp;#039;&amp;#039;&lt;br /&gt;
* break &amp;#039;&amp;#039;linenumber&amp;#039;&amp;#039;&lt;br /&gt;
* break &amp;#039;&amp;#039;file:function&amp;#039;&amp;#039;&lt;br /&gt;
* break &amp;#039;&amp;#039;file:linenumber&amp;#039;&amp;#039;&lt;br /&gt;
* break *&amp;#039;&amp;#039;address&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Katkestuspunktide nägemiseks kirjuta:&lt;br /&gt;
 info break&lt;br /&gt;
&lt;br /&gt;
Kui vigu teed, saad neid kustutada (punktide numbrid saad käsuga &amp;quot;info break&amp;quot;):&lt;br /&gt;
 delete &amp;#039;&amp;#039;breakpoint number&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039;: Lisa katkestuspunkt, jooksuta programmi kuni see kätte jõuab.&lt;br /&gt;
&lt;br /&gt;
== Programmi uudistamine ==&lt;br /&gt;
&lt;br /&gt;
Sul peaks olema nüüd peatunud programm. Debugger on mälu vaatlemise tööriist: saad lugeda (ja muuta) muutujate sisu ja stacki.&lt;br /&gt;
&lt;br /&gt;
Kõige lihtsam viis sisu vaadelda on print:&lt;br /&gt;
 print &amp;#039;&amp;#039;variablename&amp;#039;&amp;#039;&lt;br /&gt;
 print array[2]&lt;br /&gt;
 print $eax&lt;br /&gt;
&lt;br /&gt;
Võid ka pointerite sisuga tutvuda kui *. märki kasutad. Print on nii sage käsk, et võid seda lühendada kirjutades lihtsalt &amp;#039;p&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 p $eax&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Vihje:&amp;#039;&amp;#039;&amp;#039; Võid mälu x käsuga (eXamine) uurida. Kõigi registrite vaatlemiseks kirjuta &amp;#039;info registers&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039;: Vaatle oma programmi muutujaid. Lisa programmi mõni struct ja püüa aru saada kuidas ja millisel moel selle andmeid hoitakse.&lt;br /&gt;
&lt;br /&gt;
== Mälu muutmine ==&lt;br /&gt;
&lt;br /&gt;
Muutujate väärtust on väga lihtne muuta. Võid selleks kasutada &amp;#039;print&amp;#039; käsku =-märgiga.&lt;br /&gt;
&lt;br /&gt;
 print x = 888&lt;br /&gt;
 p c = &amp;#039;\0&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kui muutuja väärtust näha ei soovi, võid kasutada ka &amp;#039;set&amp;#039; käsku:&lt;br /&gt;
&lt;br /&gt;
 set var x = 99&lt;br /&gt;
 set var c = EOF&lt;br /&gt;
&lt;br /&gt;
== Stack ==&lt;br /&gt;
&lt;br /&gt;
Stack esitatakse backtrace käsu puhul: see on inimloetav ning saad tulemuseks ridade numbrid ja iga stackikihi funktsiooninime:&lt;br /&gt;
 backtrace&lt;br /&gt;
&lt;br /&gt;
Kehtiva frame&amp;#039;i infot saad kirjutades: &lt;br /&gt;
 frame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039; Jooksuta programmi mille tulemuseks on segmentation fault (ehita üks selline). Jooksuta seda kuni ta kokku jookseb ja vaata kus ta seda tegi.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Vihje:&amp;#039;&amp;#039;&amp;#039; Mõne teise frame&amp;#039;i kohalike muutujate uurimiseks võid kasutada käsku &amp;#039;up&amp;#039;. See liigub mööda stacki kihte kõrgemale. Vaata mis juhtub kui kirjutad &amp;#039;up&amp;#039; ja siis &amp;#039;frame&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Liikumine ==&lt;br /&gt;
&lt;br /&gt;
Seisatud programmi saab jooksutada ka sammhaaval. Selleks on kaks käsku: &amp;#039;next&amp;#039; ja &amp;#039;step&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
* next - käivitab järgmise koodirea&lt;br /&gt;
* step - käivitab järgmise koodirea, aga &amp;#039;&amp;#039;astub&amp;#039;&amp;#039; sisse ka erinevatesse funktsioonidesse&lt;br /&gt;
* continue - jätkab tavapärast käivitumist&lt;br /&gt;
&lt;br /&gt;
Kui tahad teada millisel real viibid:&lt;br /&gt;
 list&lt;br /&gt;
&lt;br /&gt;
Käsule list võid lisada ka rea numbri; siis näed tollel konkreetsel real olevat koodi.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;Vihje&amp;#039;&amp;#039;: võid ka ühe protsessorikäsu (instruction) jooksutada; selleks on käsud: &amp;#039;stepi&amp;#039; ja &amp;#039;nexti&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039;: Jooksuta peatuspunktidega programmi: püüa tuvastada mis erinevus on käskudel &amp;#039;step&amp;#039; ja &amp;#039;next&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Watchpoint ==&lt;br /&gt;
&lt;br /&gt;
Programmi saab seisata ka siis kui mõne muutuja väärtus muutub. Neid nimetatakse &amp;#039;&amp;#039;watchpoint&amp;#039;&amp;#039;ideks (nalja pärast võite öelda näiteks jõllik):&lt;br /&gt;
 watch &amp;#039;&amp;#039;variablename&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039;: Lisa muutujale &amp;#039;&amp;#039;watchpoint&amp;#039;&amp;#039; ja vaata kuidas see rakendub. Käivitumise jätkamiseks kasuta käsku &amp;#039;continue&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Pöördkompileerimine ==&lt;br /&gt;
&lt;br /&gt;
Saad muuta protsessorisse söödetavad numbrid loetavaks assemblerkoodiks:&lt;br /&gt;
 disas&lt;br /&gt;
 disas &amp;#039;&amp;#039;functionname&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039;: püüa pöördkompileerida mõnd lihtsat aritmeetikat tegevat funktsiooni. Vaata kuidas kasutatakse stacki enne arvutust ning kuidas seda funktsioonist lahkumise eel töödeldakse.&lt;br /&gt;
&lt;br /&gt;
Pöördkompileerida saad ka programmi &amp;#039;objdump&amp;#039; abil.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ülesanne&amp;#039;&amp;#039;&amp;#039;: Pöörkompileeri programm: kuidas erineb tulemus gdb &amp;quot;disas&amp;quot; käsust? Testi objdump erinevaid võtmeid, mida &amp;quot;man objdump&amp;quot; pakub.&lt;br /&gt;
&lt;br /&gt;
== Järeldused ==&lt;br /&gt;
&lt;br /&gt;
Kui mõistad kuidas stacki hallatakse, muutub assembler oluliselt arusaadavamaks. Võid suvalise kompileeritud programmi tagasi assembleriks muuta, kuid tulemus on  ilma lähteteksti ja sümboltabelita üsna kole (proovi näiteks ls käsu puhul)&lt;br /&gt;
&lt;br /&gt;
Võid proovida kirjutada funktsiooni, milles on kaks funktsiooni &amp;#039;&amp;#039;first&amp;#039;&amp;#039; väljub ja &amp;#039;&amp;#039;second&amp;#039;&amp;#039; teeb midagi huvitavat. Võid muuta &amp;quot;main&amp;quot; funktsiooni nii, et selle &amp;#039;call&amp;#039; instruktsioon kutsub &amp;#039;&amp;#039;first&amp;#039;&amp;#039; asemel välja funktsiooni &amp;#039;&amp;#039;second&amp;#039;&amp;#039;. Sul ei pea selleks olema lähtekoodi. Samuti võid otsida mõne &amp;#039;jmp&amp;#039; käsu ning vahetada selle aadressi sinna kus teine funktsioon välja kutsutaks. 4 baidi muutmine käivituvas failis võib palju muuta.&lt;br /&gt;
&lt;br /&gt;
Loodetavasti olid eksperimendid valgustava iseloomuga.&lt;/div&gt;</summary>
		<author><name>Irve</name></author>
	</entry>
</feed>