Skip Menu |

This queue is for tickets about the Devel-DumpTrace CPAN distribution.

Report information
The Basics
Id: 77673
Status: resolved
Priority: 0/
Queue: Devel-DumpTrace

People
Owner: Nobody in particular
Requestors: gsullivan [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.15
Fixed in: (no value)



Subject: Infinite loop when tracing external module
Devel::DumpTrace seems to get stuck in an infinite loop when it drills down into an external module. This problem happens when I try to trace inside the Number::Format CPAN module. However, this problem does not occur when I trace inside the Carp Core module. I have enclosed a simple script (num.pl) that uses Number::Format. When I trace with the following command, the command never seems to end, and it repeatedly displays the same lines of output: perl -d:DumpTrace=+Number::Format num.pl I have also enclosed an excerpt of the output (num.txt). This problem does not seem to be covered in the "BUGS AND LIMITATIONS" section of the Devel::DumpTrace POD. Devel::DumpTrace behaves as expected if I do something similar with Carp. The command ends quickly with the expected output. There is no infinite loop: perl -d:DumpTrace=+Carp -MCarp -e 'carp 12345' I am using the latest versions of Devel::DumpTrace and Number::Format: perl -v This is perl 5, version 12, subversion 2 (v5.12.2) built for x86_64-linux perl -MDevel::DumpTrace -le 'print $Devel::DumpTrace::VERSION' 0.15 perl -MNumber::Format -le 'print $Number::Format::VERSION' 1.73 By the way, I find Devel::DumpTrace to be a very useful debugging tool. It has helped me to more quickly identify bugs in my code. Thanks, Gene
Subject: num.txt
>>> num.pl:2:[__top__]: print Number::Format::format_number(5555), "\n"; >>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:316:[_get_self]: unless (ref $_:(5555)[0] && UNIVERSAL::isa($_:(5555)[0], "Number::Format")) { >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:406:[new]: my $type:'Number::Format' = shift @_:('Number::Format'); >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:407:[new]: my %args:() = @_:('Number::Format'); >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:410:[new]: my $me:{} = {}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:412:[new]: my $locale_values:{'decimal_point'=>'.'} = localeconv(); >>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:414:[new]: my $arg; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:416:[new]: while(my($arg:'n_sep_by_space', $default:1) = each %$DEFAULT_LOCALE:{'giga_suffix'=>'G';'decimal_fill'=>0;'decimal_point'=>'.';'p_cs_precedes'=>1;'mega_suffix'=>'M';'p_sep_by_space'=>1;'grouping'=>undef;'n_sep_by_space'=>1;'thousands_sep'=>',';'neg_format'=>'-x';'mon_decimal_point'=>'.';'int_curr_symbol'=>'USD';'negative_sign'=>'-';'mebi_suffix'=>'MiB';'currency_symbol'=>"\$";'kilo_suffix'=>'K';'mon_thousands_sep'=>',';'decimal_digits'=>2;'p_sign_posn'=>1;'gibi_suffix'=>'GiB';'n_cs_precedes'=>1;'int_frac_digits'=>2;'mon_grouping'=>undef;'n_sign_posn'=>1;'positive_sign'=>'';'frac_digits'=>2;'kibi_suffix'=>'KiB'}) { >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:418:[new]: $me:{'n_sep_by_space'=>1}->{$arg:'n_sep_by_space'} = (exists $locale_values:{'decimal_point'=>'.'}->{$arg:'n_sep_by_space'} >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:422:[new]: foreach $_:'n_sep_by_space' ($arg:'n_sep_by_space', uc $arg:'n_sep_by_space', "-$arg", uc "-$arg") { >>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: next unless defined $args:(){$_:'n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-n_sep_by_space'} next unless defined $args:(){$_:'N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-N_SEP_BY_SPACE'} next unless defined $args:(){$_:'-n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:undef} next unless defined $args:(){$_:'-N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:418:[new]: WHILE: (my($arg:'mebi_suffix', $default:'MiB') = each %$DEFAULT_LOCALE:{'giga_suffix'=>'G';'decimal_fill'=>0;'decimal_point'=>'.';'p_cs_precedes'=>1;'mega_suffix'=>'M';'p_sep_by_space'=>1;'grouping'=>undef;'n_sep_by_space'=>1;'thousands_sep'=>',';'neg_format'=>'-x';'mon_decimal_point'=>'.';'int_curr_symbol'=>'USD';'negative_sign'=>'-';'mebi_suffix'=>'MiB';'currency_symbol'=>"\$";'kilo_suffix'=>'K';'mon_thousands_sep'=>',';'decimal_digits'=>2;'p_sign_posn'=>1;'gibi_suffix'=>'GiB';'n_cs_precedes'=>1;'int_frac_digits'=>2;'mon_grouping'=>undef;'n_sign_posn'=>1;'positive_sign'=>'';'frac_digits'=>2;'kibi_suffix'=>'KiB'}) $me:{'mebi_suffix'=>'MiB';'n_sep_by_space'=>1}->{$arg:'mebi_suffix'} = (exists $locale_values:{'decimal_point'=>'.'}->{$arg:'mebi_suffix'} >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:422:[new]: foreach $_:'mebi_suffix' ($arg:'mebi_suffix', uc $arg:'mebi_suffix', "-$arg", uc "-$arg") { >>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: next unless defined $args:(){$_:'mebi_suffix'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-mebi_suffix'} next unless defined $args:(){$_:'MEBI_SUFFIX'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-MEBI_SUFFIX'} next unless defined $args:(){$_:'-mebi_suffix'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:undef} next unless defined $args:(){$_:'-MEBI_SUFFIX'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:418:[new]: WHILE: (my($arg:'n_sep_by_space', $default:1) = each %$DEFAULT_LOCALE:{'giga_suffix'=>'G';'decimal_fill'=>0;'decimal_point'=>'.';'p_cs_precedes'=>1;'mega_suffix'=>'M';'p_sep_by_space'=>1;'grouping'=>undef;'n_sep_by_space'=>1;'thousands_sep'=>',';'neg_format'=>'-x';'mon_decimal_point'=>'.';'int_curr_symbol'=>'USD';'negative_sign'=>'-';'mebi_suffix'=>'MiB';'currency_symbol'=>"\$";'kilo_suffix'=>'K';'mon_thousands_sep'=>',';'decimal_digits'=>2;'p_sign_posn'=>1;'gibi_suffix'=>'GiB';'n_cs_precedes'=>1;'int_frac_digits'=>2;'mon_grouping'=>undef;'n_sign_posn'=>1;'positive_sign'=>'';'frac_digits'=>2;'kibi_suffix'=>'KiB'}) $me:{'mebi_suffix'=>'MiB';'n_sep_by_space'=>1}->{$arg:'n_sep_by_space'} = (exists $locale_values:{'decimal_point'=>'.'}->{$arg:'n_sep_by_space'} >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:422:[new]: foreach $_:'n_sep_by_space' ($arg:'n_sep_by_space', uc $arg:'n_sep_by_space', "-$arg", uc "-$arg") { >>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: next unless defined $args:(){$_:'n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-n_sep_by_space'} next unless defined $args:(){$_:'N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-N_SEP_BY_SPACE'} next unless defined $args:(){$_:'-n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:undef} next unless defined $args:(){$_:'-N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:418:[new]: WHILE: (my($arg:'n_sep_by_space', $default:1) = each %$DEFAULT_LOCALE:{'giga_suffix'=>'G';'decimal_fill'=>0;'decimal_point'=>'.';'p_cs_precedes'=>1;'mega_suffix'=>'M';'p_sep_by_space'=>1;'grouping'=>undef;'n_sep_by_space'=>1;'thousands_sep'=>',';'neg_format'=>'-x';'mon_decimal_point'=>'.';'int_curr_symbol'=>'USD';'negative_sign'=>'-';'mebi_suffix'=>'MiB';'currency_symbol'=>"\$";'kilo_suffix'=>'K';'mon_thousands_sep'=>',';'decimal_digits'=>2;'p_sign_posn'=>1;'gibi_suffix'=>'GiB';'n_cs_precedes'=>1;'int_frac_digits'=>2;'mon_grouping'=>undef;'n_sign_posn'=>1;'positive_sign'=>'';'frac_digits'=>2;'kibi_suffix'=>'KiB'}) $me:{'mebi_suffix'=>'MiB';'n_sep_by_space'=>1}->{$arg:'n_sep_by_space'} = (exists $locale_values:{'decimal_point'=>'.'}->{$arg:'n_sep_by_space'} >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:422:[new]: foreach $_:'n_sep_by_space' ($arg:'n_sep_by_space', uc $arg:'n_sep_by_space', "-$arg", uc "-$arg") { >>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: next unless defined $args:(){$_:'n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-n_sep_by_space'} next unless defined $args:(){$_:'N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-N_SEP_BY_SPACE'} next unless defined $args:(){$_:'-n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:undef} next unless defined $args:(){$_:'-N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:418:[new]: WHILE: (my($arg:'n_sep_by_space', $default:1) = each %$DEFAULT_LOCALE:{'giga_suffix'=>'G';'decimal_fill'=>0;'decimal_point'=>'.';'p_cs_precedes'=>1;'mega_suffix'=>'M';'p_sep_by_space'=>1;'grouping'=>undef;'n_sep_by_space'=>1;'thousands_sep'=>',';'neg_format'=>'-x';'mon_decimal_point'=>'.';'int_curr_symbol'=>'USD';'negative_sign'=>'-';'mebi_suffix'=>'MiB';'currency_symbol'=>"\$";'kilo_suffix'=>'K';'mon_thousands_sep'=>',';'decimal_digits'=>2;'p_sign_posn'=>1;'gibi_suffix'=>'GiB';'n_cs_precedes'=>1;'int_frac_digits'=>2;'mon_grouping'=>undef;'n_sign_posn'=>1;'positive_sign'=>'';'frac_digits'=>2;'kibi_suffix'=>'KiB'}) $me:{'mebi_suffix'=>'MiB';'n_sep_by_space'=>1}->{$arg:'n_sep_by_space'} = (exists $locale_values:{'decimal_point'=>'.'}->{$arg:'n_sep_by_space'} >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:422:[new]: foreach $_:'n_sep_by_space' ($arg:'n_sep_by_space', uc $arg:'n_sep_by_space', "-$arg", uc "-$arg") { >>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: next unless defined $args:(){$_:'n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-n_sep_by_space'} next unless defined $args:(){$_:'N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:'-N_SEP_BY_SPACE'} next unless defined $args:(){$_:'-n_sep_by_space'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:424:[new]: FOREACH: {$_:undef} next unless defined $args:(){$_:'-N_SEP_BY_SPACE'}; >>>>> /lib/perl5/site_perl/5.12.2/Number/Format.pm:418:[new]: WHILE: (my($arg:'n_sep_by_space', $default:1) = each %$DEFAULT_LOCALE:{'giga_suffix'=>'G';'decimal_fill'=>0;'decimal_point'=>'.';'p_cs_precedes'=>1;'mega_suffix'=>'M';'p_sep_by_space'=>1;'grouping'=>undef;'n_sep_by_space'=>1;'thousands_sep'=>',';'neg_format'=>'-x';'mon_decimal_point'=>'.';'int_curr_symbol'=>'USD';'negative_sign'=>'-';'mebi_suffix'=>'MiB';'currency_symbol'=>"\$";'kilo_suffix'=>'K';'mon_thousands_sep'=>',';'decimal_digits'=>2;'p_sign_posn'=>1;'gibi_suffix'=>'GiB';'n_cs_precedes'=>1;'int_frac_digits'=>2;'mon_grouping'=>undef;'n_sign_posn'=>1;'positive_sign'=>'';'frac_digits'=>2;'kibi_suffix'=>'KiB'})
Subject: num.pl
use Number::Format; print Number::Format::format_number(5555), "\n";
Gene, Thank you very much for the well-thought-out bug report. Your test script contains a loop using the `each` hash iterator, and the Devel::DumpTrace module is calling `keys` on the same hash and resetting the iterator. The fix is an off-label use of the Storable::dclone function to create a copy of the hash to work with in a way that does not reset the iterator. I solicited this fix from http://stackoverflow.com/questions/10921221/ and would probably not have come up with it on my own. I'll get a new release out shortly. Enjoy, Marty O'Brien
Uploaded v0.16 to PAUSE. We employ an off-label use of the Storable::dclone function to create a working copy of a hash without resetting a pre-existing `each` iterator on that hash. Note that Storable::dclone does not work on data structures that contain CODE or GLOB values, so this issue is still NOT fixed when %hash contains CODE or GLOB values. In principle, it should be possible to create a different function modeled after Storable::dclone that can return the keys of a hash without upsetting the existing iterator, while being agnostic about the hash values. I'll consider such a function for v0.17. Not marked as resolved because of the outstanding issue with CODE and GLOB hash values.
I created a new module Hash::SafeKeys with methods to get hash contents without resetting the internal iterator. I plugged it into Devel::DumpTrace and confirmed that it works. Hash::SafeKeys has been uploaded to PAUSE. When it starts showing up on the CPAN mirrors, I'll upload v0.17 of Devel::DumpTrace and mark this issue as resolved.
v0.17 released. This issue is resolved.