问题
There are two cases where my code won't cause a segmentation fault:
- When I use Smart::Comments in at least one place
- Run through the debugger.
I've tracked it down to this call:
$action->{breakdown}
= join( ' '
, each_pair {
my ( $name, $length ) = @_;
return "x$length" if $name eq 'FILLER';
push @$field_list_ref, $name;
return "A$length";
} @$field_def_ref
);
where each_pair is defined in another module as:
sub each_pair (&@) {
my $block = shift;
return unless @_;
my $caller = caller();
my $aref = qualify( 'a', $caller );
my $bref = qualify( 'b', $caller );
my @results;
my $pairs = 0;
for ( my $index = 0; $index < $#_; $index += 2 ) {
$pairs++;
my @pair = @_[$index..($index+1)];
no strict 'refs';
local ( $$aref, $$bref ) = @pair;
push @results, $block->( @pair );
}
return wantarray || $pairs != 1 ? @results : shift @results;
}
- Now I know that I can just replace each_pair with List::MoreUtils::natatime (although I hear that has some bugs), they have just recently allowed this module into our environment, and I'm still interested in why this call is causing a segmentation fault--or what other Perl programmers due to debug segmentation faults.
I've lost a bit of time on this.
EDIT
I have other modules using this function, some expect to be able to use $a and $b, also it's working elsewhere in the same module, for another list. I can change this invocation of it, I can change it for this file, but changing it for every place that uses it successfully, is probably more changes than I would be allowed to make at this late hour.
回答1:
Segmentation faults are exceptionally rare in Perl. I can't recall the last time I encountered one.
Debuggers are intrusive enough that it's not particularly surprising that the code would behave differently there, though it's certainly frustrating. Smart::Comments uses source filters which (as we all know) are evil. Poking into the source for Smart::Comments, I see that it uses List::Util which normally uses an XS implementation. It's possible that List::Util is what "fixes" your problem. Try using List::Util directly but not Smart::Comments. That won't solve anything, but it might take the uncertainty of a source filter out of the equation.
Unfortunately, your problem seems to be not with the code itself but with unexpected interactions between different things. You can't really trigger a segmentation fault directly in Perl. The root must be in either perl itself or XS code. If you can reduce it to a small but complete sample others might be able to reproduce and isolate the problem.
回答2:
As to general debugging steps, you could always run the Perl interpreter under gdb. The chances of seeing anything educational aren't necessarily that hot, but I've done it a couple times, and it may have even helped once.
回答3:
I will echo chaos' concern with the each_pair function. What happens if you use the following implementation?
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
sub each_pair(&@);
my $field_def_ref = [ qw( FILLER 5 NOTFILLER 6 ) ];
my $field_list_ref;
print join(' ' => each_pair {
my ($name, $length) = @_;
return "x$length" if $name eq 'FILLER';
push @$field_list_ref, $name;
return "A$length";
} @$field_def_ref ), "\n";
print Dumper $field_list_ref;
sub each_pair( &@ ) {
my $code = shift;
my @results;
for my $i ( 0 .. $#_/2 ) {
push @results, $code->( shift, shift );
}
return @results;
}
__END__
回答4:
Segfaults can come from memory bugs in C written external modules bound with XS.
I recommend running your script in valgrind to spot the error:
valgrind perl ./yourfaultyscript.pl
回答5:
Well, I can't figure out why your each_pair() is doing this:
my $caller = caller();
my $aref = qualify( 'a', $caller );
my $bref = qualify( 'b', $caller );
or this:
no strict 'refs';
local ( $$aref, $$bref ) = @pair;
and referencing operations that require you to turn off strict refs seem immediately suspect in a segfaulting situation.
What happens if you disable all that?
来源:https://stackoverflow.com/questions/1172476/what-are-some-good-methods-or-steps-to-debug-a-segmentation-fault-in-perl