line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Debug::FaultAutoBT; |
2
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
39040
|
use 5.00503; |
|
4
|
|
|
|
|
16
|
|
|
4
|
|
|
|
|
162
|
|
4
|
|
|
|
|
|
|
|
5
|
4
|
|
|
4
|
|
24
|
use strict; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
116
|
|
6
|
|
|
|
|
|
|
#use warnings; |
7
|
|
|
|
|
|
|
|
8
|
4
|
|
|
4
|
|
20
|
use File::Spec::Functions; |
|
4
|
|
|
|
|
18
|
|
|
4
|
|
|
|
|
360
|
|
9
|
4
|
|
|
4
|
|
22
|
use Config; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
190
|
|
10
|
4
|
|
|
4
|
|
3992
|
use Symbol; |
|
4
|
|
|
|
|
4576
|
|
|
4
|
|
|
|
|
506
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
require DynaLoader; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
@Debug::FaultAutoBT::ISA = qw(DynaLoader); |
15
|
|
|
|
|
|
|
$Debug::FaultAutoBT::VERSION = '0.02'; |
16
|
|
|
|
|
|
|
bootstrap Debug::FaultAutoBT $Debug::FaultAutoBT::VERSION; |
17
|
|
|
|
|
|
|
|
18
|
4
|
|
|
4
|
|
26
|
use constant COMMAND_FILE => 'gdb-command'; |
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
344
|
|
19
|
4
|
|
|
4
|
|
22
|
use constant CORE_FILE_BASE => 'core.backtrace.'; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
2910
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub new { |
22
|
3
|
|
|
3
|
1
|
3240
|
my ($class, %attrs) = @_; |
23
|
3
|
|
33
|
|
|
119
|
my $self = bless \%attrs, ref($class)||$class; |
24
|
3
|
|
|
|
|
48
|
$self->init(); |
25
|
3
|
|
|
|
|
21
|
return $self; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub init { |
29
|
3
|
|
|
3
|
0
|
10
|
my $self = shift; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# verify that the 'dir' attribute is set and the dir is writable |
32
|
3
|
50
|
33
|
|
|
191
|
die "must specify a 'dir' attribute" |
33
|
|
|
|
|
|
|
unless exists $self->{dir} && length $self->{dir}; |
34
|
3
|
50
|
|
|
|
126
|
die "the dir $self->{dir} must be writable" |
35
|
|
|
|
|
|
|
unless -w $self->{dir}; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# set/verify the 'exec_path' attribute |
38
|
3
|
50
|
|
|
|
28
|
if (exists $self->{exec_path}) { |
39
|
0
|
0
|
|
|
|
0
|
die "exec_path: $self->{exec_path} is not found" |
40
|
|
|
|
|
|
|
unless -e $self->{exec_path}; |
41
|
0
|
0
|
|
|
|
0
|
die "exec_path: $self->{exec_path} is not executable" |
42
|
|
|
|
|
|
|
unless -x $self->{exec_path}; |
43
|
0
|
|
|
|
|
0
|
$self->{exec_path_in} = $self->{exec_path}; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
else { |
46
|
3
|
|
|
|
|
26
|
$self->inteli_guess_exec_path(); |
47
|
3
|
50
|
|
|
|
22
|
die "cannot figure out the executable path, ", |
48
|
|
|
|
|
|
|
"set the 'exec_path' attribute" |
49
|
|
|
|
|
|
|
unless exists $self->{exec_path_in}; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# set/verify the 'command_path_in' attribute |
54
|
3
|
50
|
|
|
|
18
|
if (exists $self->{command_path}) { |
55
|
|
|
|
|
|
|
# the file should already exist and include the gdb commands |
56
|
0
|
0
|
|
|
|
0
|
die "command_path: cannot read $self->{command_path}" |
57
|
|
|
|
|
|
|
unless -r $self->{command_path}; |
58
|
0
|
|
|
|
|
0
|
$self->{command_path_in} = $self->{command_path}; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
else { |
61
|
|
|
|
|
|
|
# use the default file and write it |
62
|
3
|
|
|
|
|
53
|
$self->{command_path_in} = catfile $self->{dir}, COMMAND_FILE; |
63
|
3
|
|
|
|
|
20
|
$self->write_gdb_command_file(); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# set/verify the 'command_path_base_in' attribute |
67
|
3
|
50
|
|
|
|
20
|
if (exists $self->{core_path_base}) { |
68
|
|
|
|
|
|
|
# try to create a file using this base |
69
|
3
|
|
|
|
|
120
|
my $try_path = $self->{core_path_base} . "00000"; |
70
|
3
|
|
|
|
|
17
|
my $fh = Symbol::gensym(); |
71
|
3
|
50
|
|
|
|
338
|
if (open $fh, ">$try_path") { |
72
|
3
|
|
|
|
|
31
|
close $fh; |
73
|
3
|
|
|
|
|
315
|
unlink $try_path; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
else { |
76
|
0
|
|
|
|
|
0
|
die "core_path_base: $self->{core_path_base} doesn't seem to ", |
77
|
|
|
|
|
|
|
"be suitable as a base for the path that can be written to"; |
78
|
|
|
|
|
|
|
} |
79
|
3
|
|
|
|
|
19
|
$self->{core_path_base_in} = $self->{core_path_base}; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
else { |
82
|
|
|
|
|
|
|
# use the default file and write it |
83
|
0
|
|
|
|
|
0
|
$self->{core_path_base_in} = catfile $self->{dir}, CORE_FILE_BASE; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# set/verify the 'debugger' attribute |
87
|
|
|
|
|
|
|
# NOOP now |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub write_gdb_command_file { |
92
|
3
|
|
|
3
|
0
|
9
|
my $self = shift; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
#XXX: should we die here? |
95
|
|
|
|
|
|
|
#die "$self->{command_path_in} already exists, delete first" |
96
|
|
|
|
|
|
|
# if -e $self->{command_path_in}; |
97
|
|
|
|
|
|
|
#warn "creating $self->{command_path_in} for user ".(getpwuid($>))[0]."\n"; |
98
|
3
|
|
|
|
|
30
|
my $fh = Symbol::gensym(); |
99
|
3
|
50
|
|
|
|
191229
|
open $fh, ">$self->{command_path_in}" |
100
|
|
|
|
|
|
|
or die "can't open $self->{command_path_in} for writing: $!"; |
101
|
3
|
|
|
|
|
150
|
print $fh <
|
102
|
|
|
|
|
|
|
bt |
103
|
|
|
|
|
|
|
kill |
104
|
|
|
|
|
|
|
quit |
105
|
|
|
|
|
|
|
EOI |
106
|
3
|
|
|
|
|
248
|
close $fh; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub inteli_guess_exec_path { |
110
|
3
|
|
|
3
|
0
|
14
|
my $self = shift; |
111
|
|
|
|
|
|
|
|
112
|
3
|
50
|
|
|
|
125
|
if (-x $^X) { |
|
|
0
|
|
|
|
|
|
113
|
3
|
|
|
|
|
25
|
$self->{exec_path_in} = $^X; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
elsif (-e '/proc/self/exe') { |
116
|
|
|
|
|
|
|
# linux? |
117
|
0
|
|
|
|
|
0
|
my $path = readlink("/proc/self/exe"); |
118
|
0
|
0
|
|
|
|
0
|
$self->{exec_path_in} = $path if -e $path; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
else { |
121
|
0
|
0
|
|
|
|
0
|
$self->{exec_path_in} = $Config{perlpath} if -x $Config{perlpath}; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub ready { |
126
|
3
|
|
|
3
|
1
|
31
|
my $self = shift; |
127
|
|
|
|
|
|
|
#warn "calling @$self{qw(exec_path_in command_path_in core_path_base_in)}"; |
128
|
3
|
|
|
|
|
102
|
set_segv_action($self->{exec_path_in}, |
129
|
|
|
|
|
|
|
$self->{command_path_in}, |
130
|
|
|
|
|
|
|
$self->{core_path_base_in}); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
DESTROY { |
134
|
3
|
|
|
3
|
|
2273994
|
my $self = shift; |
135
|
|
|
|
|
|
|
# XXX: test that this actually works, since we die here! |
136
|
|
|
|
|
|
|
# cleanup the autogenerated file if we have created it |
137
|
|
|
|
|
|
|
#unlink $self->{command_path_in} unless exists $self->{command_path}; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
1; |
141
|
|
|
|
|
|
|
__END__ |