Signal Stacktrace

734
-1

Published on

Simple module to print a stacktrace given a signal.

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
734
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Signal Stacktrace

  1. 1. Signal::StackTrace When you're there and you know it. Steven Lembark <lembark@wrkhors.com>
  2. 2. Signals In General ● Signals are used on *NIX for asynchronous  communication. ● You send them when you want to, the recipiant gets  them [pretty much] right away. ● This gives a nice mechanism for notifying a process  that it needs to do something – say print a stack  trace.
  3. 3. Perly Signal Handling ● Pretty simple:  $SIG{ $signame } = sub { ... } ● You can turn them off just as easily: $SIG{ $signame } = 'IGNORE' or delete $SIG{ $signame } ● You can localize them like any other value: Local $SIG{ $signame } = sub { ... } ● In this case I used 'USR1' by default: $SIG{ USR1 } = sub { ... }
  4. 4. Finding Where You Are From ● The 'caller' function tells where the  currently  executing sub was called from. ● In an array context this includes the subroutine and  line number. ● Caller can look 'up' the stack by passing a value to  caller. ● Incrementing the value until there are no more  callers gives a stack trace.
  5. 5. Signal Handling With Caller ● Fortunately, signal handlers run in the context of the  current call: caller reports the stack for the currently  running subroutine. ● Stack tracing from a signal handler will tell where  the code was running when the signal hit.
  6. 6. Stack Trace Code my $stack_trace = sub { my %data = (); # walk up the stack until caller returns nada. for( my $i = 0 ; my @caller = caller $i ; ++$i ) { # using a hash slice names the values. @data{ @headerz } = @caller; $print_list->( "Caller level $i:", %data ); } $print_list->( "End of trace" ); return };
  7. 7. Installing the Signal Handler sub import { shift; # remainder of the stack are signal names, default to SIGUSR1. # %SIG is global, no need to worry about the caller's package. if( @_ ) { if( my @junk = grep { ! exists $known_sigz{ $_ } } @_ ) { croak "Unknown signals: unknown signals @junk"; } # all the signals are known, install them all # with the stack_trace handler. @SIG{ @_ } = ( $stack_trace ) x @_; } else { $SIG{ USR1 } = $stack_trace; } return }
  8. 8. Oddz & Endz ● Legit signal names are installed with perl: my %known_sigz = (); @known_sigz{ split ' ', $Config{ sig_name } } = (); ● Pretty printing a list: Dumper refs. my $print_list = sub { local $Data::Dumper::Purity = 0; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 1; local $Data::Dumper::Deparse = 1; local $Data::Dumper::Sortkeys = 1; local $Data::Dumper::Deepcopy = 0; local $Data::Dumper::Quotekeys = 0; print STDERR join "n", map { ref $_ ? Dumper $_ : $_ } @_ };
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×