dumper

Dump the postmortem state of a program (QNX)

Syntax:

dumper [-bFfmnPStvw] [-D path] [-d path] [-N max_files]
       [-p pid] [-s size[G|M|K]]
       [-U user_name | uid[:gid[,sup_gid]*]]] &

Options:

-b
Attempt to slog a backtrace (libbacktrace.so.1 must be available).
-D path
The same as -d, but without querying authman.
-d path
The directory in which to place dumps, if authman doesn't supply an application sandbox path. The default is the home directory of user that started the process, or /tmp if none.
-F
Run at a fixed priority.
-f
Follow soft links for the creation of the dump files. The use of this option has security implications.
-m
Don't dump memory.
-N max_files
Save sequential dumps, to a maximum of the given number of files. Each dump is saved in a file whose name is in the form:

executable.num.core

where num starts at 1 and increases until the filename doesn't already exist.

-n
Save sequential dumps. Each dump is saved in a file whose name is in the form:

executable.num.core

where num starts at 1 and increases until the filename doesn't already exist.

-S
Disable the dumping of shared memory mappings.
-P
Dump the physical memory mappings.
-p pid
Save a dump file for this process immediately, and then exit dumper.
-s size[G|M|K]
Set the maximum core size, in bytes.
-t
Dump the stack of the errant thread only, instead of for all threads.
-U user_name
-U uid[:gid[,sup_gid]*]]
Once running, run as the specified user, so that the program doesn't need to run as root:
  • In the first form, the service sets itself to be the named user and uses that user's groups. This form depends on the /etc/passwd and /etc/group files.
  • In the second form, the service sets its user ID, and optionally its group ID and supplementary groups, to the values provided.
-v
Be verbose.
-w
Make core files world-readable.

Description:

The dumper utility runs in the background and provides a postmortem dump service for all processes. Whenever a program terminates abnormally, a dump of the current state of the program is written to disk. The dump filename is the same as the program name with a .core extension. For example, if the program name is experiment, the dump is written to experiment.core in your home directory.

  • Core dumps are placed in the logs directory in the application's sandbox.
  • Dump files can be large, so make sure the destination filesystem has lots of space.

The -p option lets you get a dump immediately for a particular process. If you specify -p, dumper doesn't run in the background, but exits right away.

You can use a debugger such as gdb to examine a dump file:

gdb program_binary program_core 

A program may terminate in one of two ways: it may exit cleanly under its own control, returning an exit status, or it may be forcibly terminated by the receipt of a signal that it isn't prepared to handle. In the latter case, dumper writes a dump file for the following set of signals:

Signal Description
SIGABRT Program-called abort function
SIGBUS Parity error
SIGEMT EMT instruction (emulation trap)

Note that SIGEMT and SIGDEADLK use the same signal number.

SIGFPE Floating-point error or division by zero
SIGILL Illegal instruction executed
SIGQUIT Quit
SIGSEGV Segmentation violation
SIGSYS Bad argument to a system call
SIGTRAP Trace trap (not reset when caught)
SIGXCPU Exceeded the CPU limit
SIGXFSZ Exceeded the file size limit

You can force the dump of a running program by setting one of the preceding signals, assuming that the program isn't masking or handling the signal itself.

To force a dump using the slay utility and the process name:

slay -s SIGABRT process_name

Examples:

Start dumper, with dump files to be written to the default directory:

dumper &

Start dumper, with dump files to be placed in the directory /home/dumps:

dumper -d /home/dumps &

Register for dump notifications:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dcmd_dumper.h>
#include <fcntl.h>
#include <unistd.h>
#include <devctl.h>
#include <sys/neutrino.h>

int
dumper_notify_attach(struct sigevent *devent)
{
    int dumper_fd;
    dumper_fd = open("/proc/dumper",O_RDONLY);
    if (dumper_fd >= 0) {
        devctl(dumper_fd, DCMD_DUMPER_NOTIFYEVENT, devent, sizeof(*devent), NULL);
        fcntl(dumper_fd, F_SETFD, FD_CLOEXEC);
    } else {
        dumper_fd = -1;
    }
    return dumper_fd;
}

#define DUMP_PULSE_CODE 0x50

int
main(int argc, const char *argv[], const char*envp[]){
    int dp_chid=-1;
    int dp_coid=-1;
    struct sigevent devent;
    struct _pulse gpulse;
    int dumper_fd=-1;
    int rcvid;
    pid_t pid;

    // create death pulses channel
    dp_chid = ChannelCreate(_NTO_CHF_FIXED_PRIORITY);
    if(dp_chid==-1){
        perror("ERROR: ChannelCreate");
        exit( -1 );
    }
    dp_coid = ConnectAttach(0, 0, dp_chid, _NTO_SIDE_CHANNEL, _NTO_COF_CLOEXEC);
    if(dp_coid==-1){
        perror("ERROR: ConnectAttach");
        exit( -1 );
    }
    SIGEV_PULSE_INIT(&devent, dp_coid, sched_get_priority_max(SCHED_RR), DUMP_PULSE_CODE, -1);
    dumper_fd=dumper_notify_attach(&devent);
    if(dumper_fd==-1){
        perror("ERROR: opening /proc/dumper");
        exit( -1 );
    }
    for (;;) {
        // Blocks waiting for a pulse
        rcvid = MsgReceivePulse(dp_chid, &gpulse, sizeof(gpulse),NULL);
        switch (gpulse.code) {
            case DUMP_PULSE_CODE: // something died
                pid = gpulse.value.sival_int;
                fprintf(stderr, "Received Death Pulse code %"PRId8"\n" , gpulse.code);
                fprintf(stderr, "Process Pid %d died abnormally\n" , pid);
                break;
            default:
                fprintf(stderr, "Unknown pulse code: %"PRId8"\n" , gpulse.code);
                break;
        }
    }
    if (dumper_fd >=0)
        close(dumper_fd);
    if (dp_coid >=0)
        ConnectDetach(dp_coid);
    if (dp_chid >=0)
        ChannelDestroy(dp_chid);
    exit(0);
} 

Files:

/proc/dumper
A special entry in the /proc filesystem (see procnto* ) that receives notification when a process terminates abnormally.

Exit status:

The dumper utility normally doesn't terminate. However, it may terminate if it encounters an error on startup (for instance, if it wasn't run by root) or if it receives a signal.

0
A signal was received and dumper shut down successfully.
1
An error was encountered on startup (not run by root or bad command-line options).

Last modified: 2013-12-21

comments powered by Disqus