DCMD_DUMPER_NOTIFYEVENT

Register for dump notifications

Synopsis:

#include <sys/dcmd_dumper.h>

#define DCMD_DUMPER_NOTIFYEVENT   __DIOT(_DCMD_MISC, DUMPER_NOTIFYEVENT, struct sigevent)

Arguments to devctl():

Argument Value
filedes A file descriptor for the dumper that you obtained by opening /proc/dumper
dcmd DCMD_DUMPER_NOTIFYEVENT
dev_data_ptr A pointer to a struct sigevent
n_bytes sizeof(struct sigevent)
dev_info_ptr NULL

Description:

This command registers a program for dump notifications.

Input:

A struct sigevent that's filled in to indicate what type of notification you want.

Output:

None.

Example:

 
#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)
    {
        devctl(dumper_fd, DCMD_DUMPER_REMOVEALL, NULL, 0, NULL);

        /* This would have worked too, because we attached only one event:
        devctl(dumper_fd, DCMD_DUMPER_REMOVEEVENT, NULL, 0, NULL);
        */
        close(dumper_fd);
    }
    if (dp_coid >=0)
        ConnectDetach(dp_coid);
    if (dp_chid >=0)
        ChannelDestroy(dp_chid);
    exit(0);
} 

See also:

DCMD_DUMPER_REMOVEALL, DCMD_DUMPER_REMOVEEVENT

devctl() in the QNX Neutrino C Library Reference

dumper in the Utilities Reference