fis-gtm/sr_port/gtm_c_stack_trace.h

137 lines
4.9 KiB
C

/****************************************************************
* *
* Copyright 2009, 2011 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. *
* *
****************************************************************/
#ifndef GTM_C_STACK_TRACE_H
#define GTM_C_STACK_TRACE_H
#include "gtm_stdio.h" /* For SPRINTF */
#define ONCE 1
#define TWICE 2
#ifdef VMS
#define GET_C_STACK_MULTIPLE_PIDS(MESSAGE, CNL_PID_ARRAY, MAX_PID_SLOTS, STUCK_CNT)
#define GET_C_STACK_FROM_SCRIPT(MESSAGE, WAITINGPID, BLOCKINGPID, COUNT)
#define GET_C_STACK_FOR_KIP(KIP_PIDS_ARR_PTR, TRYNUM, MAX_TRY, STUCK_CNT, MAX_PID_SLOTS)
#elif defined(UNIX)
#include <errno.h>
#include "send_msg.h"
#include "wbox_test_init.h"
#include "gt_timer.h"
#include "gtm_logicals.h"
#include "trans_log_name.h"
#ifndef GDSFHEAD_H_INCLUDED
#include "gdsroot.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#endif
error_def(ERR_STUCKACT);
error_def(ERR_SYSCALL);
error_def(ERR_TEXT);
#define GET_C_STACK_MULTIPLE_PIDS(MESSAGE, CNL_PID_ARRAY, MAX_PID_SLOTS, STUCK_CNT) \
{ \
uint4 index; \
uint4 pid; \
GBLREF uint4 process_id; \
\
for (index = 0; MAX_PID_SLOTS > index; index++) \
{ \
pid = CNL_PID_ARRAY[index]; \
if (0 != pid) \
GET_C_STACK_FROM_SCRIPT(MESSAGE, process_id, pid, STUCK_CNT); \
} \
}
#define GET_C_STACK_FROM_SCRIPT(MESSAGE, WAITINGPID, BLOCKINGPID, COUNT) \
{ \
int4 messagelen, arr_len; \
char *command; \
char *errptr, *currpos; \
int rs, save_errno; \
char *gtm_waitstuck_script; \
mstr envvar_logical, trans; \
char buf[MAX_TRANS_NAME_LEN]; \
int status; \
\
DCL_THREADGBL_ACCESS; \
\
SETUP_THREADGBL_ACCESS; \
if (!(TREF(gtm_waitstuck_script)).len) \
{ \
envvar_logical.addr = GTM_PROCSTUCKEXEC; \
envvar_logical.len = SIZEOF(GTM_PROCSTUCKEXEC)- 1; \
if (SS_NORMAL == (status = TRANS_LOG_NAME(&envvar_logical, &trans, buf, SIZEOF(buf), \
do_sendmsg_on_log2long))) \
{ \
assert(SIZEOF(buf) > trans.len); \
if (0 != trans.len) \
{ \
(TREF(gtm_waitstuck_script)).len = trans.len; \
(TREF(gtm_waitstuck_script)).addr = (char *)malloc(trans.len); \
memcpy((TREF(gtm_waitstuck_script)).addr, trans.addr, trans.len); \
} \
} \
} \
if (0 != (TREF(gtm_waitstuck_script)).len) \
{ \
messagelen = STRLEN(MESSAGE); \
arr_len = GTM_MAX_DIR_LEN + messagelen + 3 * SIZEOF(uint4) + 5; \
command = (char *)malloc (arr_len); \
memcpy(command, (TREF(gtm_waitstuck_script)).addr, (TREF(gtm_waitstuck_script)).len); \
currpos = (char *)command + (TREF(gtm_waitstuck_script)).len; \
*currpos++ = ' '; \
memcpy(currpos, MESSAGE, messagelen); \
currpos += messagelen; \
*currpos++ = ' '; \
SPRINTF(currpos, "%u %u %u", WAITINGPID, BLOCKINGPID, COUNT); \
assert (STRLEN(command) < arr_len); \
rs = SYSTEM((char *)command); \
if (0 != rs) \
{ \
save_errno = errno; \
send_msg(VARLSTCNT(6) ERR_STUCKACT, 4, LEN_AND_LIT("FAILURE"), LEN_AND_STR(command)); \
send_msg(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("system"), CALLFROM, save_errno); \
} else \
send_msg(VARLSTCNT(6) ERR_STUCKACT, 4, LEN_AND_LIT("SUCCESS"), LEN_AND_STR(command)); \
free((void *)command); \
} \
}
#define GET_C_STACK_FOR_KIP(KIP_PIDS_ARR_PTR, TRYNUM, MAX_TRY, STUCK_CNT, MAX_PID_SLOTS) \
{ \
boolean_t invoke_c_stack = FALSE; \
const char *kip_wait_string = NULL; \
\
DEBUG_ONLY( \
/* If we had waited for half the max time, get a C stack trace on the processes currently \
* doing the kill \
*/ \
if ((MAX_TRY / 2) == TRYNUM) \
{ \
invoke_c_stack = TRUE; \
kip_wait_string = "KILL_IN_PROG_HALFWAIT"; \
} \
) \
/* If we had waited for max time, get a C stack trace on the processes currently doing the kill \
* irrespective of whether it's pro or dbg \
*/ \
if (MAX_TRY <= TRYNUM) \
{ \
invoke_c_stack = TRUE; \
kip_wait_string = "KILL_IN_PROG_WAIT"; \
} \
if (invoke_c_stack) \
GET_C_STACK_MULTIPLE_PIDS(kip_wait_string, KIP_PIDS_ARR_PTR, MAX_PID_SLOTS, STUCK_CNT); \
}
#else
#error UNSUPPORTED PLATFORM
#endif
#endif