LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (35) - Vestavěný debugger

Dnes převážně o možných příkazech debuggeru.

7.6.2006 06:00 | Jiří Václavík | Články autora | přečteno 13981×

Chyby v programech mohou být dvojího druhu. Syntaktické, na ty nás upozorní překladač, nebo logické. Laděním rozumíme hledání a odstraňování logických chyb. Nejčastějším nástrojem pro ladění jsou ladící tisky nebo debugger.

Občas za nás také vyřeší mnoho práce pragma warnings (případně přepínač -w), který upozorňuje na sice syntakticky správné, ale nečekané zápisy.

Vestavěnný debugger

Když spustíme Perl s přepínačem -d, program poběží v režimu debugger. Debuggerem rozumíme nástroj, který postupně krok po kroku prochází program, vypisuje informace o stavu proměnných v určitých okamžicích a umožňuje tak snadněji hledat chyby.

Ovládání vestavěného debuggeru

Abychom si mohli ukázat základní příkazy debuggeru, vytvoříme si krátký, ale pokud možno různorodý program. Dále budeme pracovat s následujícím kódem v souboru program.pl.

#!/usr/bin/env perl
use strict;

my $prumer;

$prumer = nacti_data();

pis_vysledky($prumer);


sub nacti_data {
    my $prumer;
    print "Zadej prumer: ";
    $prumer = <STDIN> until ($prumer > 0);
    return $prumer;
}

sub pis_vysledky {
    printf "Obvod kruhu: %6.2f\n", PI()*$_[0];
    printf "Obsah kruhu: %6.2f\n", PI()*($_[0]/2)**2;
}

sub PI() {
    return 4*atan2(1, 1);
}

Nyní spusťme program.pl v debuggeru.

$ perl -d program.pl

Loading DB routines from perl5db.pl version 1.27
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(program.pl:4):        my $prumer;
  DB<1> 

Debugger čeká na naše příkazy. Ale než-li se k nim dostaneme, objasněme si ještě význam promptu. Poslední dva řádky se skládají z několika údajů.

  • main - jméno aktuálního balíku
  • program.pl - jméno souboru
  • 4 - číslo aktuálního řádku (řádky #!/usr/bin/env perl, use strict;, případně prázdné řádky jsou vynechány)
  • my $prumer; - aktuální řádek laděného souboru
  • <1> - číslo příkazu pro debugger

Nápověda

Příkazem h se objeví seznam příkazů. Nápovědu k jednotlivým příkazům získáme příkazem h příkaz. Kompletní nápovědu získáme příkazem h h, případně |h h.

Výpis kódu laděného programu

Příkaz l vypisuje 10 řádků programu od aktuální pozice. Dalším zadáním příkazu l se zobrazí opět 10 řádků, ale až od místa, kde minulý výpis skončil.

  DB<1> 
4==>    my $prumer;
5
6:      $prumer = nacti_data();
7
8:      pis_vysledky($prumer);
9
10
11
12      sub nacti_data {
13:         my $prumer;
  DB<1> 

Pokud chceme vidět 6. řádek a nic okolo, použijme příkaz l 6.

  DB<1> l 6
6:      $prumer = nacti_data();
  DB<2> 

Je též možné určit řádky od do (příkaz l od-do, například pro řádky 2 až 6 l 2-6). Podobně lze získat daný počet řádků od dané pozice. Například příkaz l 3+5 znamená zobraz 3. řádek a dalších 5 za ním). K zobrazení deseti předcházejících řádků máme příkaz -.

  DB<2> l 1-5
1       #!/usr/bin/env perl
2:      use strict;
3
4==>    my $prumer;
5
  DB<3> 

Řetězec ==> za číslem řádku v každém víceřádkovém výpisu ukazuje aktuální řádek. Deset řádků okolo aktuálního vypíšeme příkazem v.

  DB<3> v
1       #!/usr/bin/env perl
2:      use strict;
3
4==>    my $prumer;
5
6:      $prumer = nacti_data();
7
8:      pis_vysledky($prumer);
9
10
  DB<3> 

Hledání v kódu programu

Debugger umožňuje hledat výskyty zadaého řetězce ve zdrojovém kódu. Směrem dopředu se hledá příkazem /řetězec/ a zpět příkazem ?řetězec?. Koncové / případně ? není povinné.

  DB<4> /prumer
8:      pis_vysledky($prumer);

  DB<5> /prumer
13:         my $prumer;

  DB<6> ?prumer
8:      pis_vysledky($prumer);

  DB<7> 

Krokování

Příkaz s je jedním z vůbec nejzákladnějších příkazů debuggeru. Po jeho zadání se provede příkaz a řádek kódu se zároveň vypíše. Vykonává se skutečně jen jediný příkaz i přesto, že je řádek vypisován pokaždé celý (na řádku může být více než jeden příkaz). Pokud debugger narazí na podprogram, provádí se od prvního řádku stejně, jakoby byl rozepsán v hlavním programu.

Podobnou funkci jako s má příkaz n. Chová se stejně až na to, že volání podprogramu bere jako každý jiný příkaz a nevstupuje do něj.

Prázdný příkaz (stisk ENTER) zopakuje poslední příkaz s nebo n.

  DB<7> s
main::(program.pl:6):       $prumer = nacti_data();
  DB<7> 
main::nacti_data(program.pl:13):        my $prumer;
  DB<7> 
main::nacti_data(program.pl:14):        print "Zadej prumer: ";
  DB<7> 
main::nacti_data(program.pl:15):        $prumer = <STDIN> until ($prumer > 0);
  DB<7> 
Zadej prumer: 25
main::nacti_data(program.pl:16):        return $prumer;
  DB<7> n
main::(program.pl:8):     pis_vysledky($prumer);
  DB<7> 
Obvod kruhu:  78.54
Obsah kruhu: 490.87
Debugged program terminated.  Use q to quit or R to restart,
  use O inhibit_exit to avoid stopping after program termination,
  h q, h R or h O to get additional info.
  DB<7> 

Z výpisu je hezky vidět, že debugger data vypisuje a přijímá stejně jako kdybychom program normálně spustili.

Pokud krokujeme v podprogramu a chceme, aby se zbytek kódu v něm provedl už bez krokování, slouží k tomu příkaz r.

Dalším příkazem, který provádí kód je c [číslo_řádku|podprogram]. Ten provede program až po daný řádek nebo začátek daného podprogramu. c bez parametru provádí program do příští zarážky a nebo, pokud za aktuální pozicí žádná zarážka není, tak do konce. Restartujeme tedy provádění příkazem R a zkusíme provést vše až do 8. řádku.

  DB<7> R
...
  DB<7> c 8
Zadej prumer: 12
main::(deb.pl:8):       pis_vysledky($prumer);
  DB<8> 

Příkaz c program provádí, ale implicitně nezobrazuje zdrojový kód. Příkazem t aktivujeme trasovací režim a poté už bude každý provedený příkaz vypisován.

Výpis hodnot

Pomocí příkazu p se tiskne hodnota proměnné na výstup. Aktuální hodnotu proměnné $prumer dostaneme takto.

  DB<6> p "prumer=$prumer"
prumer=12

  DB<7> 

Dalšími příkazy k výpisu proměnných jsou X, V a x. X vypisuje proměnné definované v aktuálním balíku, V proměnné v balíku, uvedeném jako parametr.

Příkaz x umí znázornit složitější strukturu. Je však třeba předat mu odkaz, protože v opačném případě zobrazí pouze výčet prvků.

  DB<44> x \%hash
0  HASH(0x8171874)
   'klic1' => 'hodnota1'
   'klic2' => 'hodnota2'
   'klic3' => 'hodnota3'
  DB<45> 

Příkaz S vypisuje dostupné podprogramy. Bez parametru vypíše všechny. Jako parametr přijímá název balíčku (o balíčcích budeme hovořit hned po debuggingu).

  DB<3> S main
main::BEGIN
main::PI
main::nacti_data
main::pis_vysledky
  DB<4> 

Všechny používané moduly zobrazíme příkazem M.

Nastavení proměnných

Příkazem o zobrazíme seznam proměnných debuggeru a jejich hodnoty. Změnu některé proměnné provedeme příkazem o proměnná=hodnota.

Zarážky

Lze nastavit, aby se skript normálně vykonával do určitého místa, které je označeno zarážkou a poté se zastavil a čekal na další příkazy. Zarážku definujeme příkazem b číslo_řádku (zarážka se nastaví na číslo_řádku) nebo b název_podprogramu (zarážka se nastaví na první příkaz v zadaném podprogramu). Máme-li definované zarážky, zadáme příkaz c. Program se vykoná do řádku, na kterém je 1. zarážka a zastaví se. Dále můžeme opět krokovat nebo znovu stisknout c a dostat se na další zarážku.

Takto jsme definovali zarážky, které budou zarážkami za všech okolností. Lze ale definovat zarážku, která bude zarážkou jen pokud bude platit nějaká podmínka. Například zadáme-li příkaz b 9 $p > 150, bude zarážka aktivní jen v případě, že na jejím místě bude hodnota proměnné $p větší než 150.

Zarážky se mažou podobným způsobem, jen se místo b používá příkaz B. Všechny zarážky smažeme příkazem B *.

  DB<1> b 7
  DB<2> b pis_vysledky
  DB<3> l 1-30
...
6
7:b     $prumer = nacti_data();
8
...
20      sub pis_vysledky {
21:b        printf "Obvod kruhu: %6.2f\n", PI()*$_[0];
22:         printf "Obsah kruhu: %6.2f\n", PI()*($_[0]/2)**2;
...
  DB<4> c
main::(deb.pl:7):       $prumer = nacti_data();
  DB<4> c
Zadej prumer: 12
main::pis_vysledky(deb.pl:21):      printf "Obvod kruhu: %6.2f\n", PI()*$_[0];
  DB<4> c
Obvod kruhu:  37.70
Obsah kruhu: 113.10
Debugged program terminated.  Use q to quit or R to restart,
  use O inhibit_exit to avoid stopping after program termination,
  h q, h R or h O to get additional info.
  DB<4> 

Akce

Akce je příkaz Perlu, který se provede na určitém řádku. Je to v podstatě zařazení nového kódu do programu. Příkaz na vytvoření akce je ve formátu a číslo_řádku příkaz.

Akce se maže příkazem A číslo_řádku, všechny akce potom A *.

  DB<3> a 9 print "PRUMER: $prumer";
  DB<4> n
main::(deb.pl:7):       $prumer = nacti_data();
  DB<4> 
Zadej prumer: 54
main::(deb.pl:9):       pis_vysledky($prumer);
PRUMER: 54
  DB<4> 

Proměnné pod kontrolou

Pomocí tzv. sledovaných výrazů (watch-expressions) si je možné nechat automaticky vypisovat hodnotu proměnné, jakmile se tato proměnná změní. Nastavuje se příkazem w proměnná.

Kontrolu proměnné smažeme W proměnná, všechny už tradičně přidáním hvězdičky - W *.

  DB<3> w $prumer
  DB<4> n
main::(deb.pl:5):       my $prumer;
  DB<4> 
main::(deb.pl:7):       $prumer = nacti_data();
  DB<4> 
Zadej prumer: 21
Watchpoint 0:   $prumer changed:
    old value:  ''
    new value:  '21
'
main::nacti_data(deb.pl:20):        return $prumer;
  DB<4> 

Přehled nastavení

Abychom se v zarážkách, akcích a sledovaných výrazech neztratili, je zde příkaz L, který zobrazí všechna jejich nastavení.

  DB<26> L
deb.pl:
 6:     $prumer = nacti_data();
   break if (1)
 13:        my $prumer;
   action:  $vysledek=15
 23:        printf "Obvod kruhu: %6.2f\n", PI()*$_[0];
   break if ($prumer > 100)
Watch-expressions:
 $stav
 $vysledek
  DB<26> 

Historie příkazů

Kurzorové šipky slouží k pohybu v historii příkazů.

Navíc stejně jako v shellech je tu k dispozici vykřičník. Příkaz ! n provádí ntý příkaz a !! opakuje poslední příkaz. Parametrem vykřičníku může být i řetězec. V takovém případě je vykonán poslední příkaz, který na řetězec začíná.

Posledních n příkazů historie vypíšeme příkazem H -n. Historie se maže příkazem H *.

Stejně jako v shellech navíc funguje tabulátorová expanze.

Externí příkaz shellu se spouští pomocí !!příkaz_shellu.

Příkaz promptu

Lze nastavit, aby se spolu s promptem vždy zároveň provedl nějaký příkaz Perlu nebo debuggeru. V případě příkazů Perlu máme 2 možnosti - příkaz se může provádět před nebo po promptu.

příkaz Perlu

Příkaz těsně před promtem se nastavuje zadáním < příkaz. Potřebujeme-li takových příkazů víc, další se přídává pomocí << příkaz. Příkazem < se zobrazí zdrojový kód všech takto nastavených příkazů.

To samé ale až po promptu se nastavuje stejně, jen za < nahradíme >.

příkaz debuggeru

Pro definici příkazu se používá příkaz {, jinak je mechanizmus analogický příkazům Perlu. V tomto případě nemá význam jestli je příkaz před nebo po manuálním zadání.

Aliasy

Pomocí příkazu = si je možné nastavit u často používaných příkazů aliasy. Vytvoříme si příkaz prumer, který bude mít stejný význam jako p "prumer=$prumer".

  DB<25> = prumer p "prumer=$prumer"
prumer = p "prumer=$prumer"
  DB<26> prumer
prumer=11

  DB<27> 

Všechny nastavené aliasy zobrazíme příkazem =.

Příkazy Perlu

Do promptu lze normálně psát i příkazy Perlu. U víceřádkových je nutné psát vždy před nový řádek zpětné lomítko.

  DB<10> for (1..5) { \
  cont: print "CYKLUS: $_\n" \
  cont: }
CYKLUS: 1
CYKLUS: 2
CYKLUS: 3
CYKLUS: 4
CYKLUS: 5

  DB<11> 

Modul Devel::DProf

Nakonec ještě zkusíme spustit program tímto příkazem.

$ perl -d:DProf program.pl

V aktuálním adresáři se vytvořil soubor tmon.out. Obsahuje informace, týkající se zatížení procesoru, které je pak schopen zobrazit příkaz dprofpp. Můžeme tak zjistit například náročnost jednotlivých podprogramů. Je též možné oba příkazy spojit a volat dprofpp -u -p program.pl. Více informací například v manuálu.

V příštím dílu se podíváme na grafické debuggery, které lze použít pro ladění programů psaných v Perlu.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

20.5.2018 17:45 /Redakce Linuxsoft.cz
Ve čtvrtek 31. května 2018 připravuje webový magazín BusinessIT ve spolupráci s Best Online Média s.r.o. pátý ročník odborné konference Firemní informační systémy 2018. Akce proběhne v kongresovém centru Vavruška (palác Charitas), Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 15 hod. odpoledne. Konference je zaměřena na efektivní využití firemních informačních systémů a na to, jak plně využít jejich potenciál. Podrobnější informace na webových stránkách konfrence.
Přidat komentář

14.5.2018 7:28 /František Kučera
Květnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 17. 5. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: Audio – zvuk v GNU/Linuxu.
Přidat komentář

7.5.2018 16:20 /František Kučera
Na stránkách spolku OpenAlt vyšla fotoreportáž Pražské srazy 2017 dokumentující srazy za uplynulý rok. Květnový pražský sraz na téma audio se bude konat 17. 5. 2018 (místo a čas ještě upřesníme).
Přidat komentář

17.4.2018 0:46 /František Kučera
Dubnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 4. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tématem tohoto srazu bude OpenStreetMap (OSM) aneb svobodné mapy.
Přidat komentář

16.3.2018 22:01 /František Kučera
Kulatý OpenAlt sraz v Praze oslavíme klasicky: u limonády a piva! Přijďte si posedět, dát si dobré jídlo a vybrat z mnoha piv do restaurace Kulový blesk, který najdete v centru Prahy nedaleko metra I. P. Pavlova na adrese Sokolská 13, Praha 2. Sraz se koná ve čtvrtek 22. března a začínáme v 18:00. Heslo: OpenAlt. Vezměte s sebou svoje hračky! Uvítáme, když si s sebou na sraz vezmete svoje oblíbené hračky. Jestli máte nějaký drobný projekt postavený na Arduinu, nějakou zajímavou elektronickou součástku, či třeba i pěkný úlovek z crowdfundingové akce, neváhejte. Oslníte ostatní a o zábavu bude postaráno.
Přidat komentář

13.2.2018 0:41 /František Kučera
Únorový pražský sraz OpenAltu se koná 15. 2. 2018 a tentokrát se vydáme na návštěvu do jednoho pražského datacentra. Sejdeme se v 17:50 v severovýchodní části nástupiště tramvajové zastávky Koh-I-Noor. Po exkurzi se přesuneme do restaurace U Pštrosa (Moskevská 49), kde probereme tradiční témata (svobodný software a hardware, DIY, CNC, SDR, 3D tisk…) a tentokrát bude k vidění i IoT brána od The Things Network.
Přidat komentář

11.2.2018 23:11 /Petr Ježek
Hledáte lehký a rychlý prolížeč PDF souborů? Pokud vás již omrzelo čekat na načítání stránek či jiné nešvary, zkuste xreader.
Přidat komentář

11.2.2018 20:35 /Redakce Linuxsoft.cz
Třetí ročník odborné IT konference na téma Cloud computing v praxi proběhne ve čtvrtek 1. března 2018 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 16 hod. odpoledne. Konference o trendech v oblasti cloud computingu nabídne i informace o konkrétních možnostech využívání cloudů a řešení vybraných otázek souvisejících s provozem IT infrastruktury.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

20.2.2018 18:48 / Ivan Majer
portal

20.2.2018 15:57 / Jan Havel
Jak využíváte služby cloudu v podnikání?

16.1.2018 1:08 / Ivan Pittner
verejna ip od o2 ubuntu

15.1.2018 17:26 / Mira Harvalik
Re: Jak udělat HTML/Javascript swiping gallery do mobilu?

30.12.2017 20:16 / Michal Knoll
odmocnina

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2018) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze