Пример #1
0
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;
    }
}
Пример #2
0
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);
    }