Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Devel::YCallTrace -- noch ein anderes Werkzeug ...

Devel::YCallTrace -- noch ein anderes Werkzeug zur Analyse von Perl Programmen

Elena Bolshakova

March 14, 2013
Tweet

More Decks by Elena Bolshakova

Other Decks in Programming

Transcript

  1. Automatischer Debugger • man führt die Programm aus • nötige

    Logdateien werden automatisch speichern • dann kann man die Logdateien lesen und prüfen
  2. “Automatishe Debuggers” auf CPAN Devel::CallChecker Devel::CallParser Devel::CallStack Devel::CallTrace Devel::Calltree Devel::DTrace

    Devel::DumpTrace Devel::DumpTrace::PPI Devel::Optrace Devel::PrettyTrace Devel::RemoteTrace Devel::SimpleTrace Devel::Spy Devel::STrace Devel::Trace Devel::TraceCalls Devel::Trace::Cwd Devel::Trace::Fork Devel::Trace::Method Devel::TraceMethods Devel::Trace::More Devel::TraceSubs Devel::TraceUse Devel::TraceVars Devel::TrackObjects Runops::Recorder Runops::Trace ...
  3. Devel::RemoteTrace “Attachable call trace of perl scripts” Verlangsamung: sehr bedeutend

    + use Devel::RemoteTrace; > netcat ­u ­l 9999 > kill ­USR2 <pid>
  4. Devel::RemoteTrace – Bericht [18952] ./sudoku­solver.pl:264: my %index; [18952] ./sudoku­solver.pl:265: my

    %digit; [18952] ./sudoku­solver.pl:266: for my $j (@$s){ [18952] ./sudoku­solver.pl:267: my $ind = $g­>[$j]; [18952] ./sudoku­solver.pl:268: next SUBSET if $board­>{$ind}­>{content}; [18952] ./sudoku­solver.pl:264: my %index; [18952] ./sudoku­solver.pl:265: my %digit; [18952] ./sudoku­solver.pl:266: for my $j (@$s){ [18952] ./sudoku­solver.pl:267: my $ind = $g­>[$j]; [18952] ./sudoku­solver.pl:268: next SUBSET if $board­>{$ind}­>{content}; [18952] ./sudoku­solver.pl:269: $index{$ind} = 1; [18952] ./sudoku­solver.pl:270: for my $d (keys %{$board­>{$ind}­ >{hypothesis}}) { [18952] ./sudoku­solver.pl:270: for my $d (keys %{$board­>{$ind}­ >{hypothesis}}) { [18952] ./sudoku­solver.pl:271: next if $board­>{$ind}­>{hypothesis}­ >{$d} == 0; [18952] ./sudoku­solver.pl:272: $digit{$d} = 1; [18952] ./sudoku­solver.pl:271: next if $board­>{$ind}­>{hypothesis}­ >{$d} == 0;
  5. Devel::TraceSubs Verlangsamung: ~20x vervolgt Aufrufen der Subroutinen warnings: defined(%hash) is

    deprecated Modification of non­creatable array value attempted
  6. Devel::TraceSubs - Initialisierung +use Devel::TraceSubs; + my $dbg = Devel::TraceSubs­>new(

    + verbose => 0, + pre => '>', + post => '<', + level => '~', + params => 1, + wrap => ['<!­­', '­­>'], + ); + $dbg­>trace('main::');
  7. Devel::TraceSubs - Bericht <!--~~> main::fib( ''4'' )--> at sample_scripts/fib.pl line

    32 <!--~~~> main::fib( '3' )--> at sample_scripts/fib.pl line 42 <!--~~~~> main::fib( '2' )--> at sample_scripts/fib.pl line 42 <!--~~~~< main::fib => 1--> at sample_scripts/fib.pl line 42 <!--~~~~> main::fib( '1' )--> at sample_scripts/fib.pl line 42 <!--~~~~< main::fib => 1--> at sample_scripts/fib.pl line 42 <!--~~~< main::fib => 2--> at sample_scripts/fib.pl line 42 <!--~~~> main::fib( '2' )--> at sample_scripts/fib.pl line 42 <!--~~~< main::fib => 1--> at sample_scripts/fib.pl line 42
  8. Devel::TraceSubs – Bericht 2 <!--~~> main::read_board--> at ./sudoku-solver.pl line 27

    <!--~~< main::read_board--> at ./sudoku-solver.pl line 27 <!--~~> main::print_board( '{'33' => {'content' => '','type' => 'solution','hypothesis' => {'6' => 1,'3' => 1,'7' => at ./sudoku-solver.pl line 33 <!--~~< main::print_board => <void>--> at ./sudoku-solver.pl line 33 <!--~~> main::solve( '{'33' => {'content' => '','type' => 'solution','hypothesis' => {'6' => 1,'3' => 1,'7' => 1,'9' at ./sudoku-solver.pl line 34 <!--~~~> main::generate_groups--> at ./sudoku-solver.pl line 126 <!--~~~< main::generate_groups--> at ./sudoku-solver.pl line 126 <!--~~~> main::generate_subsets--> at ./sudoku-solver.pl line 127 <!--~~~< main::generate_subsets--> at ./sudoku-solver.pl line 127 <!--~~~> main::explain_hypothesis( '{'33' => {'content' => '','type' => 'solution','hypothesis' => {'6' => 1,'3' => 1 at ./sudoku-solver.pl line 131 ...
  9. Devel::CallTrace – Bericht ... main::explain_state (./sudoku­solver.pl:300­307) main::explain_hypothesis (./sudoku­solver.pl:310­317) main::rule_0 (./sudoku­solver.pl:186­202)

    main::explain (./sudoku­solver.pl:291­297) main::explain_state (./sudoku­solver.pl:300­307) main::explain_hypothesis (./sudoku­solver.pl:310­317) main::rule_0 (./sudoku­solver.pl:186­202) main::rule_1 (./sudoku­solver.pl:205­226) main::explain (./sudoku­solver.pl:291­297) main::explain (./sudoku­solver.pl:291­297) main::explain (./sudoku­solver.pl:291­297) main::explain_state (./sudoku­solver.pl:300­307) main::explain_hypothesis (./sudoku­solver.pl:310­317) main::rule_0 (./sudoku­solver.pl:186­202) ...
  10. Devel::CallStack – Bericht main::run 1 1 main::run,Data::Dumper::Dumper 2 1 main::run,Data::Dumper::Dumper,Data::Dumper::Dump

    3 1 main::run,Data::Dumper::Dumper,Data::Dumper::Dump,Data::Dumper::Dumpxs 4 1 main::run,Data::Dumper::Dumper,Data::Dumper::Dump,Data::Dumper::new 4 1 main::run,main::explain_hypothesis 2 1 main::run,main::explain_hypothesis,main::print_hypothesis 3 1 main::run,main::print_board 2 2 main::run,main::read_board 2 1 main::run,main::solve 2 1 main::run,main::solve,main::explain_hypothesis 3 141 main::run,main::solve,main::explain_hypothesis,main::print_hypothesis 4 141 main::run,main::solve,main::explain_state 3 140 main::run,main::solve,main::explain_state,main::print_board 4 140 main::run,main::solve,main::generate_groups 3 1 main::run,main::solve,main::generate_subsets 3 1 main::run,main::solve,main::rule_0 3 1339 ...
  11. Devel::Trace – Bericht ... >> ./sudoku­solver.pl:56: for my $i (

    1 .. 9 ){ >> ./sudoku­solver.pl:57: for my $j (1 .. 9){ >> ./sudoku­solver.pl:58: my $c = shift @arr; >> ./sudoku­solver.pl:59: if ($c eq '.'){ >> ./sudoku­solver.pl:66: $board­>{"$i$j"} = { >> ./sudoku­solver.pl:58: my $c = shift @arr; >> ./sudoku­solver.pl:59: if ($c eq '.'){ >> ./sudoku­solver.pl:66: $board­>{"$i$j"} = { >> ./sudoku­solver.pl:58: my $c = shift @arr; >> ./sudoku­solver.pl:59: if ($c eq '.'){ >> ./sudoku­solver.pl:63: hypothesis => { map { $_ => 1 } 1 .. 9 }, >> ./sudoku­solver.pl:60: $board­>{"$i$j"} = { >> ./sudoku­solver.pl:60: $board­>{"$i$j"} = { >> ./sudoku­solver.pl:60: $board­>{"$i$j"} = { ...
  12. Devel::TraceVars – Bericht ... >> ./sudoku­solver.pl 58: my $c =

    shift @arr; >> ./sudoku­solver.pl 59: if (8 eq '.'){ >> ./sudoku­solver.pl 66: HASH(0x13746d0)­>{"14"} = { >> ./sudoku­solver.pl 58: my $c = shift @arr; >> ./sudoku­solver.pl 59: if (. eq '.'){ >> ./sudoku­solver.pl 63: hypothesis => { map { $_ => 1 } 1 .. 9 }, >> ./sudoku­solver.pl 60: HASH(0x13746d0)­>{"15"} = { >> ./sudoku­solver.pl 60: HASH(0x13746d0)­>{"15"} = { >> ./sudoku­solver.pl 60: HASH(0x13746d0)­>{"15"} = { >> ./sudoku­solver.pl 60: HASH(0x13746d0)­>{"15"} = { >> ./sudoku­solver.pl 60: HASH(0x13746d0)­>{"15"} = { >> ./sudoku­solver.pl 60: HASH(0x13746d0)­>{"15"} = { >> ./sudoku­solver.pl 60: HASH(0x13746d0)­>{"15"} = { >> ./sudoku­solver.pl 58: my $c = shift @arr; ...
  13. Ist alles schon gut? Leider nicht • riesige Logdateien –

    schwierig zu lesen und grep'en – passt nicht für die große Programme • doch gibt es einige Informationen nicht – Werte der Variablen – ob die Subroutine ihre Parametern modifiziert hat – ...
  14. Devel::YCallTrace vervolgt Aufrufen der Funktionen Verlangsamung bis 50-100x prozedurale, objektorientirte

    und debugger Schnittstelle mod_perl kompatibel perl >= 5.8 kompatibel erfordet Aspect, Template::Toolkit, HTTP::Daemon gebraucht SQLite oder andere DB
  15. Plan B for live demo # Fibonacci numbers, recursively require

    Devel::YCallTrace; Devel::YCallTrace::init(); print fib($N); sub fib{ my ($N) = @_; if ($N <= 2 ){ return 1; } else { return fib($N­1) + fib($N­2); } }
  16. > ./fib.pl 8 21 > ./yct_view.pl Please contact me at:

    http://lena­ san­thinkpad:39539/ > firefox http://lena­san­ thinkpad:39539/
  17. Irgendwie im Quelltext einer Webdienst if( !production() && cookie('yct_debug') ){

    Devel::YCallTrace::init(...); Apache2::RequestUtil­>request­>pool ­>cleanup_register( sub { Devel::YCallTrace::finish(); } ); }