@@ -532,7 +532,7 @@ BEGIN
532
532
use vars qw( $VERSION $header) ;
533
533
534
534
# bump to X.XX in blead, only use X.XX_XX in maint
535
- $VERSION = ' 1.80 ' ;
535
+ $VERSION = ' 1.81 ' ;
536
536
537
537
$header = " perl5db.pl version $VERSION " ;
538
538
@@ -2033,19 +2033,12 @@ sub _DB__handle_c_command {
2033
2033
# Qualify it to the current package unless it's
2034
2034
# already qualified.
2035
2035
$subname = $package . " ::" . $subname
2036
- unless $subname =~ / ::/ ;
2036
+ unless $subname =~ / ::/ ;
2037
2037
2038
- # find_sub will return "file:line_number" corresponding
2039
- # to where the subroutine is defined; we call find_sub,
2040
- # break up the return value, and assign it in one
2041
- # operation.
2042
- ( $file , $i ) = ( find_sub($subname ) =~ / ^(.*):(.*)$ / );
2043
-
2044
- # Force the line number to be numeric.
2045
- $i = $i + 0;
2038
+ my ($file , $line ) = eval { subroutine_first_breakable_line($subname ) };
2046
2039
2047
2040
# If we got a line number, we found the sub.
2048
- if ($i ) {
2041
+ if ($line ) {
2049
2042
2050
2043
# Switch all the debugger's internals around so
2051
2044
# we're actually working with that file.
@@ -2055,22 +2048,13 @@ sub _DB__handle_c_command {
2055
2048
# Mark that there's a breakpoint in this file.
2056
2049
$had_breakpoints {$filename } |= 1;
2057
2050
2058
- # Scan forward to the first executable line
2059
- # after the 'sub whatever' line.
2060
- $max = $#dbline ;
2061
- my $_line_num = $i ;
2062
- while ($dbline [$_line_num] == 0 && $_line_num< $max )
2063
- {
2064
- $_line_num++;
2065
- }
2066
- $i = $_line_num;
2067
- } # # end if ($i)
2068
-
2069
- # We didn't find a sub by that name.
2051
+ $i = $line ;
2052
+ } # # end if ($line)
2070
2053
else {
2071
- print $OUT " Subroutine $subname not found. \n " ;
2054
+ print $OUT $@ ;
2072
2055
next CMD;
2073
2056
}
2057
+
2074
2058
} # # end if ($subname =~ /\D/)
2075
2059
2076
2060
# At this point, either the subname was all digits (an
@@ -5389,6 +5373,65 @@ sub subroutine_filename_lines {
5389
5373
return (find_sub($subname ) =~ / ^(.*):(\d +)-(\d +)$ / );
5390
5374
} # # end sub subroutine_filename_lines
5391
5375
5376
+ =head2 subroutine_first_breakable_line(subname)
5377
+
5378
+ Attempts to find the filename and first breakable line by execution
5379
+ order for the subroutine specified by C<subname > .
5380
+
5381
+ If this isn't possible, such as when debugging with C<miniperl > , finds
5382
+ the first breakable line by line order for the subroutine specified by
5383
+ C<subname > .
5384
+
5385
+ Return the filename and breakable line number:
5386
+
5387
+ my ($file, $line) = subroutine_first_breakable_line(subname);
5388
+
5389
+ Throws an error message if C<subname > cannot be found or is not
5390
+ breakable.
5391
+
5392
+ =cut
5393
+
5394
+ sub _first_breakable_via_B {
5395
+ my ( $subname ) = @_ ;
5396
+
5397
+ my $cv = do {
5398
+ no strict " refs" ;
5399
+ *$subname {CODE };
5400
+ };
5401
+ ref $cv eq " CODE"
5402
+ or return ;
5403
+
5404
+ eval { require B; 1 }
5405
+ or return ;
5406
+
5407
+ my $bcv = B::svref_2object($cv );
5408
+
5409
+ $bcv -> XSUB
5410
+ and die " Cannot break on XSUB $subname \n " ;
5411
+
5412
+ for (my $op = $bcv -> START; !$op -> isa(" B::NULL" ); $op = $op -> next) {
5413
+ $op -> name eq " dbstate"
5414
+ and return ( $op -> file, $op -> line, $op -> line );
5415
+ }
5416
+
5417
+ return ;
5418
+ }
5419
+
5420
+ sub subroutine_first_breakable_line {
5421
+ my ( $subname ) = @_ ;
5422
+
5423
+ my ($file , $line ) = _first_breakable_via_B($subname );
5424
+ unless ($file ) {
5425
+ # at the very least this allows miniperl to debug
5426
+ ( $file , my ($s , $e ) ) = subroutine_filename_lines($subname )
5427
+ or die " Subroutine $subname not found.\n " ;
5428
+
5429
+ $line = breakable_line_in_filename($file , $s , $e );
5430
+ }
5431
+
5432
+ return ($file , $line );
5433
+ }
5434
+
5392
5435
=head3 break_subroutine(subname) (API)
5393
5436
5394
5437
Places a break on the first line possible in the specified subroutine. Uses
@@ -5401,16 +5444,14 @@ sub break_subroutine {
5401
5444
my $subname = shift ;
5402
5445
5403
5446
# Get filename, start, and end.
5404
- my ( $file , $s , $e ) = subroutine_filename_lines($subname )
5405
- or die " Subroutine $subname not found.\n " ;
5406
-
5447
+ my ( $file , $line ) = subroutine_first_breakable_line($subname );
5407
5448
5408
5449
# Null condition changes to '1' (always true).
5409
5450
my $cond = @_ ? shift (@_ ) : 1;
5410
5451
5411
5452
# Put a break the first place possible in the range of lines
5412
5453
# that make up this subroutine.
5413
- break_on_filename_line_range( $file , $s , $e , $cond );
5454
+ break_on_filename_line_range( $file , $line , $line , $cond );
5414
5455
5415
5456
return ;
5416
5457
} # # end sub break_subroutine
0 commit comments