bool EXsys_report( register EX_ARGS *exargs, char *buffer ) { /* ** Number of message arguments; we add 2 because the PC and PSL are ** present in exarg_array (which is simply the exception signal vector) ** but aren't counted in exarg_count. */ i4 arg_count = exargs->exarg_count + 2; /* Report Hardware Exceptions ** ** This should report all hardware or system exceptions (including ** those that get mapped into internal Ingres exceptions. All available ** program information should be formatted and printed into the output ** buffer. ** ** We return FALSE for normal INGRES exceptions. These are exceptions ** where: ** 1. The exception number is in the correct range for INGRES ** exceptions. Unfortunately, this will also be true if someone ** signals an RMS failure. So in addition, we check that: ** 2. The signal array's PC is where lib$signal returns to EXsignal, ** meaning that EXsignal signaled this exception. */ /* ** if (CLERROR(exargs->exarg_num) && ** exargs->exarg_array[arg_count-2] == &EXsignal_PC) */ if (CLERROR(exargs->exarg_num)) { return FALSE; } else { char bufs[256]; $DESCRIPTOR(buf, bufs); unsigned short len; unsigned char info[4]; EXdump(EV_SIGVIO_DUMP); if ( !in_sysrep ) { in_sysrep = TRUE; if (Ex_print_stack) { Ex_print_stack(NULL, NULL, NULL, ex_print_error, TRUE); } in_sysrep = FALSE; } lib$sys_getmsg(&exargs->exarg_num, &len, &buf, 0, info); if (info[1] == 0 || arg_count < info[1]) { /* ** No args or insufficient args; don't try to format it. */ STlcopy(bufs, buffer, len); } else { $DESCRIPTOR(obuf, buffer); /* Format it. Use lib$sys_faol, so any number of args works */ obuf.dsc$w_length = buf.dsc$w_length; buf.dsc$w_length = len; lib$sys_faol(&buf, &len, &obuf, exargs->exarg_array); buffer[len] = '\0'; } return TRUE; } }
DB_STATUS uleFormatFcn( DB_ERROR *dberror, i4 err_code, CL_ERR_DESC *clerror, i4 flag, DB_SQLSTATE *sqlstate, char *msg_buffer, i4 msg_buf_length, i4 *msg_length, i4 *uleError, PTR uleFileName, i4 uleLineNumber, i4 num_parms, ... ) { #define NUM_ER_ARGS 12 struct { ULE_MHDR hdr; /* FIX ME should message size be ER_MAX_LEN - sizeof(ULE_MHDR) */ char message[ER_MAX_LEN]; } buffer; i4 i; i4 length = 0; i4 text_length; i4 status; CL_ERR_DESC sys_err; i4 language; SCF_SESSION sid; SCF_SCI info[10]; SCF_CB scf_cb; ER_ARGUMENT er_args[NUM_ER_ARGS]; char hex_chars[16] = {'0','1','2','3','4','5','6','7', '8','9','a','b','c','d','e','f'}; i4 error_code; i4 local_error_code; DB_ERROR localDBerror, *DBerror; PTR FileName; i4 LineNumber; char *qbuf = NULL; char *prev_qbuf = NULL; char *psqbuf = NULL; i4 qlen = 0; i4 prev_qlen = 0; i4 psqlen = 0; i4 trace_errno = 0; i4 trace_stack = 0; i4 prlen; char *prbuf; i2 hdr_size; i4 NumParms; va_list ap; LOCATION loc; char dev[LO_NM_LEN]; char fprefix[LO_NM_LEN]; char fsuffix[LO_NM_LEN]; char version[LO_NM_LEN]; char path[MAX_LOC + 1]; char filebuf[MAX_LOC + 1]; char LineNo[LO_NM_LEN]; char *MessageArea = (char*)&buffer.message; char SourceInfo[LO_NM_LEN]; i4 PrefixLen = sizeof(ULE_MHDR); if (Ule_started == 0) { MEfill(sizeof(ULE_MHDR), (u_char)' ', (PTR)&Ule_mhdr); Ule_started = -1; } /* ** If old form (no dberror) or overriding err_code, ** use caller's err_code, File, and Line information, ** otherwise use what's in "dberror". */ if ( !dberror || err_code ) { DBerror = &localDBerror; DBerror->err_file = uleFileName; DBerror->err_line = uleLineNumber; DBerror->err_code = err_code; DBerror->err_data = 0; /* Fill caller's dberror with that used */ if ( dberror ) *dberror = *DBerror; } else DBerror = dberror; error_code = local_error_code = DBerror->err_code; MessageArea = (char*)&buffer.message; info[0].sci_code = SCI_SID; info[0].sci_length = sizeof(sid); info[0].sci_aresult = (char *) &sid; info[0].sci_rlength = 0; info[1].sci_code = SCI_LANGUAGE; info[1].sci_length = sizeof(language); info[1].sci_aresult = (char *) &language; info[1].sci_rlength = 0; scf_cb.scf_length = sizeof(SCF_CB); scf_cb.scf_type = SCF_CB_TYPE; scf_cb.scf_ascii_id = SCF_ASCII_ID; scf_cb.scf_facility = DB_ULF_ID; scf_cb.scf_session = DB_NOSESSION; scf_cb.scf_len_union.scf_ilength = 2; scf_cb.scf_ptr_union.scf_sci = (SCI_LIST *) &info[0]; /* scf_error is not usually an input parameter */ if (flag == ULE_LOG || flag == ULE_MESSAGE) { info[2].sci_code = SCI_QBUF; info[2].sci_length = sizeof(qbuf); info[2].sci_aresult = (char *) &qbuf; info[2].sci_rlength = 0; info[3].sci_code = SCI_QLEN; info[3].sci_length = sizeof(qlen); info[3].sci_aresult = (char *) &qlen; info[3].sci_rlength = 0; info[4].sci_code = SCI_TRACE_ERRNO; info[4].sci_length = sizeof(trace_errno); info[4].sci_aresult = (char *) &trace_errno; info[4].sci_rlength = 0; info[5].sci_code = SCI_PREV_QBUF; info[5].sci_length = sizeof(prev_qbuf); info[5].sci_aresult = (char *) &prev_qbuf; info[5].sci_rlength = 0; info[6].sci_code = SCI_PREV_QLEN; info[6].sci_length = sizeof(prev_qlen); info[6].sci_aresult = (char *) &prev_qlen; info[6].sci_rlength = 0; info[7].sci_code = SCI_PSQ_QBUF; info[7].sci_length = sizeof(psqbuf); info[7].sci_aresult = (char *) &psqbuf; info[7].sci_rlength = 0; info[8].sci_code = SCI_PSQ_QLEN; info[8].sci_length = sizeof(psqlen); info[8].sci_aresult = (char *) &psqlen; info[8].sci_rlength = 0; info[9].sci_code = SCI_TRACE_STACK; info[9].sci_length = sizeof(trace_stack); info[9].sci_aresult = (char *) &trace_stack; info[9].sci_rlength = 0; scf_cb.scf_len_union.scf_ilength = 10; } status = scf_call(SCU_INFORMATION, &scf_cb); if (status) { language = 1; sid = 0; } if (!language) language = 1; /* package up the stack parameters into an ER_ARGUMENT array */ va_start( ap, num_parms ); for( NumParms = 0; NumParms < num_parms && NumParms < NUM_ER_ARGS; NumParms++ ) { er_args[NumParms].er_size = (i4) va_arg( ap, i4 ); er_args[NumParms].er_value = (PTR) va_arg( ap, PTR ); } va_end( ap ); *uleError = 0; if (flag == 0 || flag == ULE_LOG || flag == ULE_LOOKUP) { /* Get INGRES message text. */ status = ERslookup( local_error_code, CLERROR(local_error_code)? clerror : (CL_ERR_DESC*) NULL, ER_TIMESTAMP, (sqlstate) ? sqlstate->db_sqlstate : (char *) NULL, MessageArea, (i4) sizeof(buffer.message), (i4) language, &text_length, &sys_err, NumParms, er_args ); if (status != OK) { CL_ERR_DESC junk; STprintf(MessageArea, "ULE_FORMAT: "); length = STlength(MessageArea); /* ** If uleFormat caller is different than ** error source, identify caller. */ if ( flag == ULE_LOG && uleFileName && (uleFileName != DBerror->err_file || uleLineNumber != DBerror->err_line) ) { STcopy(uleFileName, filebuf); STprintf(LineNo, ":%d ", uleLineNumber); if ( LOfroms(PATH & FILENAME, filebuf, &loc) || LOdetail(&loc, dev, path, fprefix, fsuffix, version) ) { STpolycat(2, FileName, LineNo, &MessageArea[length]); } else { STpolycat(4, fprefix, ".", fsuffix, LineNo, &MessageArea[length]); } length = STlength(MessageArea); MessageArea[length++] = ' '; } STprintf(&MessageArea[length], "Couldn't look up message %x ", local_error_code); length = STlength(MessageArea); STprintf(&MessageArea[length], "(reason: ER error %x)\n",status); length = STlength(MessageArea); status = ERslookup( (i4) status, &sys_err, (i4) 0, (sqlstate) ? sqlstate->db_sqlstate : (char *) NULL, &MessageArea[length], (i4) (sizeof(buffer.message) - length), (i4) language, &text_length, &junk, 0, (ER_ARGUMENT *) NULL ); if (status != OK) { STprintf(&MessageArea[length], "... ERslookup failed twice: status = %x", status); length = STlength(MessageArea); } else { length += text_length; } *uleError = E_UL0002_BAD_ERROR_LOOKUP; } else { length = text_length; } /* Get system message text. */ if (clerror) { MessageArea[length++] = '\n'; /* ** Extract the distinct clerror source information, filename, ** extension, and line number from CL_ERR_DESC ** and prefix the message text with it. */ if ( !CLERROR(error_code) && (FileName = clerror->errfile) ) { STcopy(FileName, filebuf); STprintf(LineNo, ":%d ", clerror->errline); if ( LOfroms(PATH & FILENAME, filebuf, &loc) || LOdetail(&loc, dev, path, fprefix, fsuffix, version) ) { STpolycat(2, FileName, LineNo, &MessageArea[length]); } else { STpolycat(4, fprefix, ".", fsuffix, LineNo, &MessageArea[length]); } length += STlength(&MessageArea[length]); MessageArea[length++] = ' '; } status = ERslookup( (i4) 0, clerror, (i4) 0, (sqlstate) ? sqlstate->db_sqlstate : (char *) NULL, &MessageArea[length], (i4) (sizeof(buffer.message) - length), (i4) language, &text_length, &sys_err, 0, (ER_ARGUMENT *) NULL ); if (status != OK) { CL_ERR_DESC junk; STprintf(&MessageArea[length], "ULE_FORMAT: Couldn't look up system error "); length = STlength(MessageArea); STprintf(&MessageArea[length], "(reason: ER error %x)\n", status); length = STlength(MessageArea); status = ERslookup( (i4) status, &sys_err, (i4) 0, (sqlstate) ? sqlstate->db_sqlstate : (char *) NULL, &MessageArea[length], (i4) (sizeof(buffer.message) - length), (i4) language, &text_length, &junk, 0, (ER_ARGUMENT *) NULL ); if (status != OK) { STprintf(&MessageArea[length], "... ERslookup failed twice: status = %x", status); length = STlength(MessageArea); } else { length += text_length; } *uleError = E_UL0001_BAD_SYSTEM_LOOKUP; } else { length += text_length; } } /* Copy into callers buffer if requested. */ if (msg_buffer && msg_buf_length) { if (msg_buf_length < length) length = msg_buf_length; MEcopy((PTR)MessageArea, length, (PTR)msg_buffer); *msg_length = length; } } else if (flag == ULE_MESSAGE) { if (!msg_buffer || !msg_buf_length) { *uleError = E_UL0003_BADPARM; return (E_DB_ERROR); } MEcopy((PTR)msg_buffer, msg_buf_length, (PTR)MessageArea); length = msg_buf_length; } if (flag == ULE_LOG || flag == ULE_MESSAGE) { SCF_SESSION tmp_sid = sid; MEcopy((PTR)&Ule_mhdr, sizeof(ULE_MHDR), (PTR)&buffer.hdr); for (i = (sizeof(Ule_mhdr.ule_session)) ; --i >= 0; ) { buffer.hdr.ule_session[i] = hex_chars[(tmp_sid & 0xf)]; tmp_sid >>= 4; } /* ** Extract the error source information, filename, extension, ** and line number from CL_ERR_DESC or DB_ERROR ** and format it into the ULE_MHDR. */ if ( CLERROR(DBerror->err_code) && clerror && clerror->errfile ) { FileName = clerror->errfile; LineNumber = clerror->errline; } else { FileName = DBerror->err_file; LineNumber = DBerror->err_line; } if ( FileName ) { STprintf(LineNo, ":%d ", LineNumber); STcopy(FileName, filebuf); if ( LOfroms(PATH & FILENAME, filebuf, &loc) || LOdetail(&loc, dev, path, fprefix, fsuffix, version) ) { STpolycat(2, FileName, LineNo, SourceInfo); } else { STpolycat(4, fprefix, ".", fsuffix, LineNo, SourceInfo); } STmove(SourceInfo, ' ', SourceInfoLen, (PTR)&buffer.hdr.ule_source); } /* Echo the message to II_DBMS_LOG, if defined */ TRwrite(NULL, PrefixLen + length, (PTR)&buffer); status = ERsend(ER_ERROR_MSG, (PTR)&buffer, PrefixLen + length, &sys_err); }