NAME
    Debug::SIGSEGVTrace - Extract A Backtrace on SegFault

SYNOPSIS
      use Debug::SIGSEGVTrace;
  
      use File::Spec::Functions;
      my $tmp_dir = File::Spec::Functions::tmpdir;
  
      my $trace = Debug::SIGSEGVTrace->new(
          dir            => "$tmp_dir",
          #verbose        => 1,
          #exec_path      => '/home/stas/perl/bin/perl',
          #core_path_base => catfile($tmp_dir, "mycore"),
          #command_path   => catfile($tmp_dir, "my-gdb-command"),
          #debugger       => "gdb",
      );
  
      # enable the sighandler
      $trace->ready();

      # or simply:
      Debug::SIGSEGVTrace->new(dir => "$tmp_dir")->ready;

DESCRIPTION
    This module attempts to automatically extract a backtrace when a
    segfault happens, rather then letting the core file be dumped. This has
    the following benefits:

    *   no need to setup the environment to allow core file dumped.
        Sometimes people just don't know how to set it up. Sometimes you
        aren't allowed to set it up (e.g., when the webserver environment is
        not under your control).

    *   if many Perl programs are run in a row and more than one program
        segfaults it's possible to collect all backtraces, rathen then
        aborting the run on the first segfault or staying with only the last
        core file, which will overwrite all the previous ones. For example
        consider a live webserver or a test suite which may segfault many
        times for different reasons.

    *   for huge core files, this approach saves disk space. And can be a
        saver when you don't have disk space left for various reasons
        (passed the quota?), but still have a few kilo-bytes left.

METHODS
  new()

      my $trace = Debug::SIGSEGVTrace->new(
          dir            => "$tmp_dir",
          verbose        => 1,
          exec_path      => '/home/stas/perl/bin/perl',
          core_path_base => catfile($tmp_dir, "mycore"),
          command_path   => catfile($tmp_dir, "my-gdb-command"),
          debugger       => "gdb",
      );

    Attributes:

    *dir*
        a writable by the process directory.

        This is a required attribute.

    *verbose*
        Whether to be silent (0) or verbose (1).

        This is an optional attribute. The default is 0.

        Currently it's always a non-verbose, with just a few traces printed
        out. Will work in the future.

    *exec_path*
        "gdb" needs to know the path to the executable in order to attach to
        the process (though gdb 5.2 and higher needs only pid to do that).
        This module is trying to automatically figure out the executable
        path, using several methods in the following order:

          $^X, /proc/self/exe, $Config{perlpath}

        If all these methods fail the module will die(), unless you
        explicitly set the *exec_path* attribute. Notice I named it
        *exec_path* because the executable doesn't have to be perl, when
        Perl is embedded, which is the case with mod_perl, which sets "$^X"
        to the path to the Apache httpd server.

    *core_path_base*
        The base path of the core file. e.g. if *core_path_base* is set to
        */tmp/mycore* and the pid of the process that has segfaulted is
        12345, the generated core is written to the file */tmp/mycore12345*.

        This is an optional attribute.

        By default *core_path_base* is a concatenation of the *dir*
        attribute and the string *core.*.

    *command_path*
        The path to the file with debugger commands. If this attribute is
        set the file should already include the commands. Notice that the
        commands should include 'quit' as the last command, so the debugger
        will quit.

        This is an optional attribute.

        By default *command_path* is a concatenation of the *dir* attribute
        and the string *gdb-command*, which is getting populated with the
        following commands:

          bt
          quit

    *debugger*
        Curently not used. In the future could be used to specify which
        debugger to use (when more than one debugger is supported). For the
        future compatibility "gdb" is going to be the default.

  ready()

      $trace->ready();

    This method sets the SIGSEGV sighandler. Only after this method is
    called the extract of the trace will be attempted on the event of
    SegFault.

    Notice that it sets the handler to be called only once. If another
    segfault happens during the processing of the handler, the SIGSEGV
    handler that was previously set will get invoked. If none was previously
    set the default SIGSEGV handler will attempt to dump the core file if
    the environment is configured to allow one (via shell's "limit" command
    and possibly other system-dependent manipulations).

  RELATED NOTES

    When you want to get a useful backtrace the debugger must be able to
    resolve symbols. Therefore the object in question must have its symbols
    preserved and not stripped. This is usually accomplished by compiling
    the C code with "-g". Since this code gets called from Perl, which in
    turn may be embedded into some other application (e.g., mod_perl enabled
    Apache), you probably want to have *libperl.so* and the application it's
    embedded to, to be compiled with the debug symbols non-stripped.

    For example to build a Perl package which includes XS/C objects, add:

      WriteMakefile(
          ...
          DEFINE            => '-g',
          ...
      );

    To build Perl in debug mode:

      ./Configure ... -Doptimize='-g' ...

    To build Apache 1.3 without stripping the symbols:

      ./configure ... --without-execstrip

    To build Apache 2.0 in the debug mode:

      ./configure ... --enable-maintainer-mode ...

BUGS
    *   When you run the handler you might get things like:

          /tmp/Debug-SIGSEGVTrace-0.01/24043: No such file or directory.

        This is a bug in older versions of gdb, simply ignore it.

    *   It probably won't compile on Win32. If you know how please submit
        patches.

EXPORT
    None.

TODO
    * the code is not thread-safe (so it's not running under mod_perl 2.0
    with worker mpm :(. The question is how to pass data to the SIGSEGV
    signal handler, without using static variables.

    * clean the backtrace from extra frames added by this module

    * how do we pass the test suite if we exit(2)? currently used fork() to
    workaround it, but it's not very portable.

    * how do we clean-up the autogenerated gdb-command file if we exit(2)?

    * support other debuggers than gdb. Need your input/patches.

    Currently this module works only on systems with gdb installed.

    I'm not sure how portable is my C code, but should probable work on any
    POSIX-complient system.

    If you know how to make the code more portable, or support other
    debuggers on other OSes please send patches.

ACKNOWLEDGEMENTS
    The idea has been borrowed from the GNOME's gnome-crash project, which
    is used to automatically extract a backtrace when reporting a bug.

    Parts of the C non-blocking-read implementation were borrowed from Matt
    Sergeant's PPerl project.

AUTHOR
    Stas Bekman <stas@stason.org>

SEE ALSO
    perl(3), "Debug::SIGSEGVFault(3)".

