summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/perl/lib/sigtrap.pm
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1996-08-19 10:13:38 +0000
committerJason Downs <downsj@cvs.openbsd.org>1996-08-19 10:13:38 +0000
commit14856225739aa48b6c9cf4c17925362b2d95cea3 (patch)
treedfd38f1b654fb5bbdfc38887c1a829b658e71530 /gnu/usr.bin/perl/lib/sigtrap.pm
parent77469082517e44fe6ca347d9e8dc7dffd1583637 (diff)
Import of Perl 5.003 into the tree. Makefile.bsd-wrapper and
config.sh.OpenBSD are the only local changes.
Diffstat (limited to 'gnu/usr.bin/perl/lib/sigtrap.pm')
-rw-r--r--gnu/usr.bin/perl/lib/sigtrap.pm79
1 files changed, 79 insertions, 0 deletions
diff --git a/gnu/usr.bin/perl/lib/sigtrap.pm b/gnu/usr.bin/perl/lib/sigtrap.pm
new file mode 100644
index 00000000000..e099ac46581
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/sigtrap.pm
@@ -0,0 +1,79 @@
+package sigtrap;
+
+=head1 NAME
+
+sigtrap - Perl pragma to enable stack backtrace on unexpected signals
+
+=head1 SYNOPSIS
+
+ use sigtrap;
+ use sigtrap qw(BUS SEGV PIPE SYS ABRT TRAP);
+
+=head1 DESCRIPTION
+
+The C<sigtrap> pragma initializes some default signal handlers that print
+a stack dump of your Perl program, then sends itself a SIGABRT. This
+provides a nice starting point if something horrible goes wrong.
+
+By default, handlers are installed for the ABRT, BUS, EMT, FPE, ILL, PIPE,
+QUIT, SEGV, SYS, TERM, and TRAP signals.
+
+See L<perlmod/Pragmatic Modules>.
+
+=cut
+
+require Carp;
+
+sub import {
+ my $pack = shift;
+ my @sigs = @_;
+ @sigs or @sigs = qw(QUIT ILL TRAP ABRT EMT FPE BUS SEGV SYS PIPE TERM);
+ foreach $sig (@sigs) {
+ $SIG{$sig} = 'sigtrap::trap';
+ }
+}
+
+sub trap {
+ package DB; # To get subroutine args.
+ $SIG{'ABRT'} = DEFAULT;
+ kill 'ABRT', $$ if $panic++;
+ syswrite(STDERR, 'Caught a SIG', 12);
+ syswrite(STDERR, $_[0], length($_[0]));
+ syswrite(STDERR, ' at ', 4);
+ ($pack,$file,$line) = caller;
+ syswrite(STDERR, $file, length($file));
+ syswrite(STDERR, ' line ', 6);
+ syswrite(STDERR, $line, length($line));
+ syswrite(STDERR, "\n", 1);
+
+ # Now go for broke.
+ for ($i = 1; ($p,$f,$l,$s,$h,$w,$e,$r) = caller($i); $i++) {
+ @a = ();
+ for $arg (@args) {
+ $_ = "$arg";
+ s/([\'\\])/\\$1/g;
+ s/([^\0]*)/'$1'/
+ unless /^(?: -?[\d.]+ | \*[\w:]* )$/x;
+ s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;
+ s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg;
+ push(@a, $_);
+ }
+ $w = $w ? '@ = ' : '$ = ';
+ $a = $h ? '(' . join(', ', @a) . ')' : '';
+ $e =~ s/\n\s*\;\s*\Z// if $e;
+ $e =~ s/[\\\']/\\$1/g if $e;
+ if ($r) {
+ $s = "require '$e'";
+ } elsif (defined $r) {
+ $s = "eval '$e'";
+ } elsif ($s eq '(eval)') {
+ $s = "eval {...}";
+ }
+ $f = "file `$f'" unless $f eq '-e';
+ $mess = "$w$s$a called from $f line $l\n";
+ syswrite(STDERR, $mess, length($mess));
+ }
+ kill 'ABRT', $$;
+}
+
+1;