8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 08:43:04 +01:00
firebird-mirror/src/jrd/err.cpp

396 lines
9.3 KiB
C++
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Access Method
* MODULE: err.cpp
2001-05-23 15:26:42 +02:00
* DESCRIPTION: Bug check routine
*
* The contents of this file are subject to the Interbase Public
* License Version 1.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.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "MPEXL" port
*
2002-10-30 07:40:58 +01:00
* 2002.10.29 Sean Leyne - Removed obsolete "Netware" port
*
2001-05-23 15:26:42 +02:00
*/
#include "firebird.h"
2004-04-29 00:36:29 +02:00
#include <stdio.h>
2001-05-23 15:26:42 +02:00
#include <string.h>
#include "gen/iberror.h"
#include <errno.h>
2001-05-23 15:26:42 +02:00
#include "../jrd/jrd.h"
2003-07-14 12:35:49 +02:00
#include "../jrd/os/pio.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/val.h"
#include "../jrd/ods.h"
#include "../jrd/btr.h"
#include "../jrd/req.h"
2003-10-20 12:53:52 +02:00
#include "../jrd/rse.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/tra.h"
#include "../jrd/cch_proto.h"
#include "../jrd/met_proto.h"
#include "../jrd/err_proto.h"
2010-10-12 10:02:57 +02:00
#include "../yvalve/gds_proto.h"
#include "../common/isc_proto.h"
#include "../common/config/config.h"
#include "../common/utils_proto.h"
2001-05-23 15:26:42 +02:00
using namespace Jrd;
using namespace Firebird;
2004-05-03 19:47:44 +02:00
//#define JRD_FAILURE_SPACE 2048
2009-11-22 04:56:20 +01:00
//#define JRD_FAILURE_UNKNOWN "<UNKNOWN>" // Used when buffer fails
2001-05-23 15:26:42 +02:00
2008-12-20 09:12:19 +01:00
static void internal_error(ISC_STATUS status, int number, const TEXT* file = NULL, int line = 0);
2001-05-23 15:26:42 +02:00
void ERR_bugcheck(int number, const TEXT* file, int line)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ b u g c h e c k
*
**************************************
*
* Functional description
* Things seem to be going poorly today.
*
**************************************/
thread_db* const tdbb = JRD_get_thread_data();
Database* const dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
dbb->dbb_flags |= DBB_bugcheck;
CCH_shutdown(tdbb);
2001-05-23 15:26:42 +02:00
internal_error(isc_bug_check, number, file, line);
2001-05-23 15:26:42 +02:00
}
void ERR_bugcheck_msg(const TEXT* msg)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ b u g c h e c k _ m s g
*
**************************************
*
* Functional description
* Things seem to be going poorly today.
*
**************************************/
thread_db* const tdbb = JRD_get_thread_data();
Database* const dbb = tdbb->getDatabase();
2001-05-23 15:26:42 +02:00
dbb->dbb_flags |= DBB_bugcheck;
DEBUG;
CCH_shutdown(tdbb);
2001-05-23 15:26:42 +02:00
ERR_post(Arg::Gds(isc_bug_check) << Arg::Str(msg));
2001-05-23 15:26:42 +02:00
}
void ERR_corrupt(int number)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ c o r r u p t
*
**************************************
*
* Functional description
* Things seem to be going poorly today.
*
**************************************/
internal_error(isc_db_corrupt, number);
2001-05-23 15:26:42 +02:00
}
void ERR_error(int number)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ e r r o r
*
**************************************
*
* Functional description
* Post a user-level error. This is a temporary mechanism
* that will eventually disappear.
*
**************************************/
TEXT errmsg[MAX_ERRMSG_LEN + 1];
DEBUG;
2004-07-07 05:43:20 +02:00
if (gds__msg_lookup(0, JRD_BUGCHK, number, sizeof(errmsg), errmsg, NULL) < 1)
sprintf(errmsg, "error code %d", number);
2001-05-23 15:26:42 +02:00
ERR_post(Arg::Gds(isc_random) << Arg::Str(errmsg));
2001-05-23 15:26:42 +02:00
}
void ERR_log(int facility, int number, const TEXT* message)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ l o g
*
**************************************
*
* Functional description
2008-12-05 02:20:14 +01:00
* Log a message to the firebird.log
2001-05-23 15:26:42 +02:00
*
**************************************/
TEXT errmsg[MAX_ERRMSG_LEN + 1];
thread_db* tdbb = JRD_get_thread_data();
2001-05-23 15:26:42 +02:00
DEBUG;
2009-08-10 00:21:31 +02:00
if (message)
2009-08-07 12:39:56 +02:00
{
strncpy(errmsg, message, sizeof(errmsg));
errmsg[sizeof(errmsg) - 1] = 0;
}
2009-08-07 12:39:56 +02:00
else if (gds__msg_lookup(0, facility, number, sizeof(errmsg), errmsg, NULL) < 1)
strcpy(errmsg, "Internal error code");
2001-05-23 15:26:42 +02:00
const size_t len = strlen(errmsg);
fb_utils::snprintf(errmsg + len, sizeof(errmsg) - len, " (%d)", number);
2001-05-23 15:26:42 +02:00
gds__log("Database: %s\n\t%s", (tdbb && tdbb->getAttachment()) ?
tdbb->getAttachment()->att_filename.c_str() : "", errmsg);
2001-05-23 15:26:42 +02:00
}
void ERR_post_warning(const Arg::StatusVector& v)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ p o s t _ w a r n i n g
*
**************************************
*
* Functional description
* Post a warning to the current status vector.
*
**************************************/
2008-09-05 13:46:26 +02:00
fb_assert(v.value()[0] == isc_arg_warning);
FbStatusVector* const status_vector = JRD_get_thread_data()->tdbb_status_vector;
Arg::StatusVector warnings(status_vector->getWarnings());
warnings << v;
status_vector->setWarnings(warnings.value());
2001-05-23 15:26:42 +02:00
}
void ERR_post_nothrow(const Arg::StatusVector& v, FbStatusVector* statusVector)
2004-08-10 15:40:10 +02:00
/**************************************
*
* E R R _ p o s t _ n o t h r o w
*
**************************************
*
* Functional description
* Populate a status vector.
2004-08-10 15:40:10 +02:00
*
**************************************/
{
// calculate length of the status
unsigned lenToAdd = v.length();
if (lenToAdd == 0) // nothing to do
return;
const ISC_STATUS* toAdd = v.value();
fb_assert(toAdd[0] == isc_arg_gds);
2004-08-21 11:29:46 +02:00
// Use default from tdbb when no vector specified
if (!statusVector)
statusVector = JRD_get_thread_data()->tdbb_status_vector;
if (!(statusVector->getState() & FbStatusVector::STATE_ERRORS))
{
// this is a blank status vector just stuff the status
statusVector->setErrors2(lenToAdd, toAdd);
return;
}
2008-09-03 10:55:09 +02:00
const ISC_STATUS* oldVector = statusVector->getErrors();
unsigned lenOld = fb_utils::statusLength(oldVector);
2008-09-03 10:55:09 +02:00
// check for duplicated error code
if (fb_utils::subStatus(oldVector, lenOld, toAdd, lenToAdd) != ~0u)
return;
// copy memory from/to
StaticStatusVector tmp;
tmp.assign(oldVector, lenOld);
tmp.append(toAdd, lenToAdd);
statusVector->setErrors2(tmp.getCount(), tmp.begin());
2004-08-21 11:29:46 +02:00
}
void ERR_post(const Arg::StatusVector& v)
/**************************************
*
* E R R _ p o s t
*
**************************************
*
* Functional description
2008-07-11 04:37:23 +02:00
* Create a status vector and return to the user.
*
**************************************/
{
ERR_post_nothrow(v);
DEBUG;
ERR_punt();
}
2009-01-14 12:10:48 +01:00
void ERR_punt()
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ p u n t
*
**************************************
*
* Functional description
* Error stuff has been copied to status vector. Now punt.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
Database* dbb = tdbb->getDatabase();
2001-12-24 03:51:06 +01:00
if (dbb && (dbb->dbb_flags & DBB_bugcheck))
{
iscDbLogStatus(dbb->dbb_filename.nullStr(), tdbb->tdbb_status_vector);
2004-04-10 02:25:22 +02:00
if (Config::getBugcheckAbort())
{
2004-04-10 02:25:22 +02:00
abort();
}
2001-05-23 15:26:42 +02:00
}
status_exception::raise(tdbb->tdbb_status_vector);
2001-05-23 15:26:42 +02:00
}
2008-09-03 10:55:09 +02:00
void ERR_warning(const Arg::StatusVector& v)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* E R R _ w a r n i n g
*
**************************************
*
* Functional description
* Write an error out to the status vector but
2001-12-29 12:41:29 +01:00
* don't throw an exception. This allows
2001-05-23 15:26:42 +02:00
* sending a warning message back to the user
* without stopping execution of a request. Note
* that subsequent errors can supersede this one.
*
**************************************/
thread_db* tdbb = JRD_get_thread_data();
FbStatusVector* s = tdbb->tdbb_status_vector;
2001-05-23 15:26:42 +02:00
v.copyTo(s);
2001-05-23 15:26:42 +02:00
DEBUG;
tdbb->getRequest()->req_flags |= req_warning;
2001-05-23 15:26:42 +02:00
}
void ERR_append_status(FbStatusVector* status_vector, const Arg::StatusVector& v)
{
/**************************************
*
2008-08-30 05:14:08 +02:00
* E R R _ a p p e n d _ s t a t u s
*
**************************************
*
* Functional description
* Append the given status vector with the passed arguments.
*
**************************************/
// First build a status vector with the passed one
Arg::StatusVector passed(status_vector);
// Now append the newly vector to the passed one
passed.append(v);
// Return the result
passed.copyTo(status_vector);
}
void ERR_build_status(FbStatusVector* status_vector, const Arg::StatusVector& v)
{
/**************************************
*
* E R R _ a p p e n d _ s t a t u s
*
**************************************
*
* Functional description
* Set the given status vector to the passed arguments.
*
**************************************/
v.copyTo(status_vector);
}
2009-08-07 12:39:56 +02:00
static void internal_error(ISC_STATUS status, int number, const TEXT* file, int line)
2001-05-23 15:26:42 +02:00
{
/**************************************
*
* i n t e r n a l _ e r r o r
*
**************************************
*
* Functional description
* Things seem to be going poorly today.
*
**************************************/
TEXT errmsg[MAX_ERRMSG_LEN + 1];
DEBUG;
2004-07-07 05:43:20 +02:00
if (gds__msg_lookup(0, JRD_BUGCHK, number, sizeof(errmsg), errmsg, NULL) < 1)
strcpy(errmsg, "Internal error code");
2001-05-23 15:26:42 +02:00
const size_t len = strlen(errmsg);
2008-12-05 02:20:14 +01:00
2009-08-10 00:21:31 +02:00
if (file)
2009-08-07 12:39:56 +02:00
{
// Remove path information
2009-08-07 14:14:25 +02:00
const TEXT* ptr = file + strlen(file);
2009-08-10 00:21:31 +02:00
for (; ptr > file; ptr--)
2009-08-07 12:39:56 +02:00
{
2009-08-10 00:21:31 +02:00
if ((*ptr == '/') || (*ptr == '\\'))
2009-08-07 12:39:56 +02:00
{
ptr++;
break;
}
}
fb_utils::snprintf(errmsg + len, sizeof(errmsg) - len,
" (%d), file: %s line: %d", number, ptr, line);
}
else {
fb_utils::snprintf(errmsg + len, sizeof(errmsg) - len, " (%d)", number);
}
2001-05-23 15:26:42 +02:00
ERR_post(Arg::Gds(status) << Arg::Str(errmsg));
2001-05-23 15:26:42 +02:00
}