fis-gtm/sr_unix/err_init.c

125 lines
4.5 KiB
C

/****************************************************************
* *
* Copyright 2001, 2013 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include <sys/types.h>
#include <setjmp.h>
#include <errno.h>
#include "unistd.h"
#include "gtm_stdlib.h"
#include "gtm_stdio.h"
#include "invocation_mode.h"
#include "gtmimagename.h"
#include "error.h"
#include "send_msg.h"
#define COREDUMPFILTERFN "/proc/%i/coredump_filter"
#define FILTERPARMSIZE (8 + 1)
#define FILTERENABLEBITS 0x00000073 /* Represents bits 0, 1, 4, 5, 6 */
GBLREF enum gtmImageTypes image_type;
error_def(ERR_SYSCALL);
/* 1. Allocate a basic initial condition handler stack that can be expanded later if necessary.
* 2. On Linux, make sure bits 0,1, 4, 5, and 6 are set in /proc/PID/coredump_filter so dumps the sections that GT.M
* cores need to have in them.
*/
void err_init(void (*x)())
{
chnd = (condition_handler *)malloc((CONDSTK_INITIAL_INCR + CONDSTK_RESERVE) * SIZEOF(condition_handler));
chnd[0].ch_active = FALSE;
chnd[0].save_active_ch = NULL;
active_ch = ctxt = &chnd[0];
ctxt->ch = x;
chnd_end = &chnd[CONDSTK_INITIAL_INCR]; /* chnd_end is the end of the condition handler stack */
chnd_incr = CONDSTK_INITIAL_INCR * 2;
# ifdef __linux__
/* Read the coredump_filter value from /proc for this process, update the value if necessary so we have the proper
* flags set to get the info we (and gtmpcat) need to properly process a core file. Note any errors we encounter just
* send a message to the operator log and return as nothing here should prevent GT.M from running.
*
* Note "man 5 core" on x86-64 Linux (Ubuntu 12.04) notes that the /proc/PID/coredump_filter file is only provided when
* the Linux kernel is built with the CONFIG_ELF_CORE configuration option. This *seems* to control whether or not the
* kernel supports the ELF loader or not. To date, all Linux flavors GT.M supports use ELF so we regard this as largely
* mandatory though in the future it may happen that GT.M works yet runs with something other than ELF. In that case,
* we'd need to change the below to avoid the operator log messages every time GT.M initializes.
*/
{
int rc;
unsigned int filterbits;
char procfn[SIZEOF(COREDUMPFILTERFN) + MAX_DIGITS_IN_INT]; /* File name of file to update */
char filter[FILTERPARMSIZE], *filterend; /* Value read in & written out */
char *rcc;
FILE *filterstrm; /* filter stream file block */
/* Note use simple basic methods since this early in initialization not everything is necessarily setup to
* be able to properly use the *print*() wrapper functions.
*/
rc = snprintf(procfn, SIZEOF(procfn), COREDUMPFILTERFN, getpid());
if (0 > rc)
{
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("sprintf()"), CALLFROM, rc);
return;
}
filterstrm = fopen(procfn, "r");
if (NULL == filterstrm)
{
rc = errno;
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fopen()"), CALLFROM, rc);
return;
}
rcc = fgets(filter, SIZEOF(filter), filterstrm);
if (NULL == rcc)
{
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fgets()"), CALLFROM, rc);
return;
}
rc = fclose(filterstrm);
if (0 > rc)
{
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fclose()"), CALLFROM, rc);
return;
}
filterend = filter + SIZEOF(filter);
filterbits = (unsigned int)strtol(filter, &filterend, 16);
if (FILTERENABLEBITS != (filterbits & FILTERENABLEBITS))
{ /* At least one flag was missing - reset them */
filterbits = filterbits | FILTERENABLEBITS;
filterstrm = fopen(procfn, "w");
if (NULL == filterstrm)
{
rc = errno;
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fopen()"),
CALLFROM, rc);
return;
}
rc = fprintf(filterstrm, "0x%08x", filterbits);
if (0 > rc)
{
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fprintf"),
CALLFROM, rc);
return;
}
fclose(filterstrm);
if (0 > rc)
{
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fclose()"),
CALLFROM, rc);
return;
}
}
}
# endif
}