blob: a2c66c9d5f14ac701ced2ba2a148a273dd3b2e6a [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
*****************************************************************************
*
* File: CmpEHCallBack.cpp
* Description: Compiler Call back functions for exception handling
*
*
* Created: 5/4/02
* Language: C++
*
*
*
*
*****************************************************************************
*/
#include "Platform.h"
#include <stdio.h>
#include <signal.h>
#include "CmpEHCallBack.h"
#include "CmpCommon.h"
#include "NAError.h"
#include "CmpStatement.h"
//-------------------------------------------------------------------------
// The following objects are used by Tandem Failure Data System (TFDS)
// to record state of process when software errors occur. First Failure Data
// Capture (FFDC) is carried out TFDS runtime library which is linked with
// the MX compiler. Currently this is switched on only for NSK.
//------------------------------------------------------------------------
//*******************************************************************
// Only for NSK: This routine gets a pointer to the user SQL query
//********************************************************************
//*******************************************************************
// For NSK only:This routine records stack trace at time of exception;
// An NSK event viewer can look at the stack trace.
// Control is returned to the compiler process by TFDS system.
// For NT only: this is a no-op.
//********************************************************************
void makeTFDSCall(const char *msg, const char *file, UInt32 line)
{
}
void CmpEHCallBack::doFFDC()
{
makeTFDSCall("",__FILE__,__LINE__);
}
void CmpEHCallBack::dumpDiags(){
// Do not clone this code; it's a bit kludgy.
// If needed, rewrite arkcmp.cpp main and StaticCompiler try..catch,
// *or* enhance diags ComCondition with a displayCount_ member
// which dumpDiags looks at and will only display the cond if not already
// done so (and then we'd replace this whole if{}else{} with a simple
// dumpDiags *without* a clear).
//
if (CmpCommon::context()->GetMode() == STMT_STATIC)
{
// StaticCompiler.cpp needs us to display these before
// its diags go out of scope in the longjmp stack unwind,
// because static comp lets arkcmp.cpp main do the catch
// (its caller, not itself).
if (CmpCommon::diags()->getNumber())
{
cerr << endl << "--- ERROR/EXCEPTION ..." << endl;
CmpCommon::dumpDiags(cerr, TRUE/*newline*/);
CmpCommon::diags()->clear();
}
}
else
{
// Dynamic compilation will catch this exception itself;
// it relies on the presence of *uncleared* diags conditions
// to tell if there was an error.
}
ARKCMP_EXCEPTION_EPILOGUE("EHException");
}
//*********************************************************************
//Trap Handler is invoked when conditions can't be explicitly checked
//The TFDS system invokes this routine when operating system throws
// an exception. An example would be when the process runs out of memory.
// Control is not returned to the compiler process.
//*********************************************************************
static Int32 sigTypes[] = {
SIGABRT,
SIGFPE,
SIGILL,
SIGINT,
SIGSEGV,
SIGTERM
};
static const char *sigNames[] = {
"SIGABRT",
"SIGFPE",
"SIGILL",
"SIGINT",
"SIGSEGV",
"SIGTERM"
};
void printSignalHandlers()
{
void (*oldHdlr)(Int32);
void (*newHdlr)(Int32);
for(Int32 i=0; i<sizeof(sigTypes)/sizeof(Int32); i++){
newHdlr = SIG_DFL;
oldHdlr = signal(sigTypes[i], newHdlr);
if(oldHdlr == SIG_ERR){
cerr << "signal() failed, cannot change " << sigNames[i]
<< " to the default handler" << endl;
exit(-1);
}
printf("%s %p\n", sigNames[i], oldHdlr);
newHdlr = signal(sigTypes[i], oldHdlr);
if(oldHdlr == SIG_ERR){
cerr << "signal() failed, cannot restore " << sigNames[i]
<< " to the original handler" << endl;
exit(-1);
}
}
}