2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD Access Method
|
2003-11-05 10:02:33 +01:00
|
|
|
* 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-29 03:59:57 +01:00
|
|
|
*
|
|
|
|
* 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
|
|
|
*/
|
|
|
|
|
2001-07-29 19:42:23 +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 "../jrd/common.h"
|
2003-11-11 13:19:20 +01:00
|
|
|
#include "gen/iberror.h"
|
2007-11-02 16:14:57 +01:00
|
|
|
#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/dbg_proto.h"
|
|
|
|
#include "../jrd/err_proto.h"
|
|
|
|
#include "../jrd/gds_proto.h"
|
2004-04-06 09:25:45 +02:00
|
|
|
#include "../common/config/config.h"
|
2004-10-09 05:58:45 +02:00
|
|
|
#include "../common/utils_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
using namespace Jrd;
|
2008-07-10 17:57:33 +02:00
|
|
|
using namespace Firebird;
|
2004-03-20 15:57:40 +01:00
|
|
|
|
2004-05-03 19:47:44 +02:00
|
|
|
//#define JRD_FAILURE_SPACE 2048
|
|
|
|
//#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);
|
2008-08-27 14:20:47 +02:00
|
|
|
static void internal_post(const ISC_STATUS* status_vector);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2004-09-24 02:11:32 +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.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-23 05:18:10 +02:00
|
|
|
Database* dbb = GET_DBB();
|
2001-05-23 15:26:42 +02:00
|
|
|
dbb->dbb_flags |= DBB_bugcheck;
|
|
|
|
|
|
|
|
CCH_shutdown_database(dbb);
|
|
|
|
|
2004-09-24 02:11:32 +02:00
|
|
|
internal_error(isc_bug_check, number, file, line);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-03 03:53:34 +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.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-23 05:18:10 +02:00
|
|
|
Database* dbb = GET_DBB();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
dbb->dbb_flags |= DBB_bugcheck;
|
|
|
|
DEBUG;
|
|
|
|
CCH_shutdown_database(dbb);
|
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_bug_check) << Arg::Str(msg));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-03 03:53:34 +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.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2003-11-11 13:19:20 +01:00
|
|
|
internal_error(isc_db_corrupt, number);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-25 11:08:14 +01:00
|
|
|
void ERR_duplicate_error(IDX_E code, const jrd_rel* relation, USHORT index_number, const TEXT* idx_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* E R R _ d u p l i c a t e _ e r r o r
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Duplicate error during index update.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-09-03 10:55:09 +02:00
|
|
|
MetaName index, constraint;
|
2009-01-25 11:08:14 +01:00
|
|
|
if (!idx_name)
|
|
|
|
MET_lookup_index(tdbb, index, relation->rel_name, index_number + 1);
|
|
|
|
else
|
|
|
|
index = idx_name;
|
2008-08-27 14:20:47 +02:00
|
|
|
|
|
|
|
bool haveConstraint = true;
|
|
|
|
if (index.hasData()) {
|
2005-05-12 20:28:04 +02:00
|
|
|
MET_lookup_cnstrt_for_index(tdbb, constraint, index);
|
2008-08-27 14:20:47 +02:00
|
|
|
if (constraint.isEmpty()) {
|
|
|
|
haveConstraint = false;
|
|
|
|
constraint = "***unknown***";
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else {
|
2008-08-27 14:20:47 +02:00
|
|
|
haveConstraint = false;
|
|
|
|
index = constraint = "***unknown***";
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2009-01-20 09:33:59 +01:00
|
|
|
switch (code)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
case idx_e_keytoobig:
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_imp_exc) <<
|
|
|
|
Arg::Gds(isc_keytoobig) << Arg::Str(index));
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case idx_e_conversion:
|
|
|
|
ERR_punt();
|
|
|
|
break;
|
|
|
|
|
2004-09-01 00:29:59 +02:00
|
|
|
case idx_e_foreign_target_doesnt_exist:
|
2008-12-05 02:20:14 +01:00
|
|
|
ERR_post(Arg::Gds(isc_foreign_key) << Arg::Str(constraint) <<
|
2008-08-27 14:20:47 +02:00
|
|
|
Arg::Str(relation->rel_name) <<
|
|
|
|
Arg::Gds(isc_foreign_key_target_doesnt_exist));
|
2004-09-01 00:29:59 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case idx_e_foreign_references_present:
|
2008-12-05 02:20:14 +01:00
|
|
|
ERR_post(Arg::Gds(isc_foreign_key) << Arg::Str(constraint) <<
|
2008-08-27 14:20:47 +02:00
|
|
|
Arg::Str(relation->rel_name) <<
|
|
|
|
Arg::Gds(isc_foreign_key_references_present));
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2008-08-27 14:20:47 +02:00
|
|
|
if (haveConstraint)
|
2008-08-30 05:14:08 +02:00
|
|
|
{
|
2008-12-05 02:20:14 +01:00
|
|
|
ERR_post(Arg::Gds(isc_unique_key_violation) << Arg::Str(constraint) <<
|
2008-08-27 14:20:47 +02:00
|
|
|
Arg::Str(relation->rel_name));
|
2008-08-30 05:14:08 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_no_dup) << Arg::Str(index));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-03 03:53:34 +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
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_random) << Arg::Str(errmsg));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-03 03:53:34 +02:00
|
|
|
void ERR_error_msg(const TEXT* msg)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* E R R _ e r r o r _ m s g
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Post a user-level error. This is a temporary mechanism
|
|
|
|
* that will eventually disappear.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
DEBUG;
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(isc_random) << Arg::Str(msg));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-03 03:53:34 +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];
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
DEBUG;
|
2004-10-09 05:58:45 +02:00
|
|
|
if (message) {
|
|
|
|
strncpy(errmsg, message, sizeof(errmsg));
|
|
|
|
errmsg[sizeof(errmsg) - 1] = 0;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2004-07-07 05:43:20 +02:00
|
|
|
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
|
|
|
|
2004-10-09 05:58:45 +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
|
|
|
|
2007-12-03 16:46:39 +01:00
|
|
|
gds__log("Database: %s\n\t%s", (tdbb && tdbb->getAttachment()) ?
|
2008-06-26 11:47:59 +02:00
|
|
|
tdbb->getAttachment()->att_filename.c_str() : "", errmsg);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-03 10:55:09 +02:00
|
|
|
bool 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);
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
int indx = 0, warning_indx = 0;
|
2008-08-30 05:14:08 +02:00
|
|
|
ISC_STATUS* status_vector = JRD_get_thread_data()->tdbb_status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-11 13:19:20 +01:00
|
|
|
if (status_vector[0] != isc_arg_gds ||
|
|
|
|
(status_vector[0] == isc_arg_gds && status_vector[1] == 0 &&
|
2008-12-20 09:12:19 +01:00
|
|
|
status_vector[2] != isc_arg_warning))
|
2004-07-07 05:43:20 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
/* this is a blank status vector */
|
2008-08-27 14:20:47 +02:00
|
|
|
fb_utils::init_status(status_vector);
|
2001-05-23 15:26:42 +02:00
|
|
|
indx = 2;
|
|
|
|
}
|
2008-12-05 02:20:14 +01:00
|
|
|
else
|
2008-08-27 14:20:47 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
/* find end of a status vector */
|
|
|
|
PARSE_STATUS(status_vector, indx, warning_indx);
|
|
|
|
if (indx)
|
|
|
|
--indx;
|
|
|
|
}
|
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
/* stuff the warning */
|
2008-12-05 02:20:14 +01:00
|
|
|
if (indx + v.length() + 1 < ISC_STATUS_LENGTH)
|
2008-08-27 14:20:47 +02:00
|
|
|
{
|
|
|
|
memcpy(&status_vector[indx], v.value(), sizeof(ISC_STATUS) * (v.length() + 1));
|
|
|
|
ERR_make_permanent(&status_vector[indx]);
|
2004-02-20 07:43:27 +01:00
|
|
|
return true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2008-01-16 09:54:50 +01:00
|
|
|
|
|
|
|
/* not enough free space */
|
|
|
|
return false;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
void ERR_post_nothrow(const Arg::StatusVector& v)
|
2004-08-10 15:40:10 +02:00
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* E R R _ p o s t _ n o t h r o w
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Create a status vector.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-08-06 17:26:55 +02:00
|
|
|
{
|
2008-09-05 13:46:26 +02:00
|
|
|
fb_assert(v.value()[0] == isc_arg_gds);
|
2008-08-27 14:20:47 +02:00
|
|
|
ISC_STATUS_ARRAY vector;
|
|
|
|
v.copyTo(vector);
|
|
|
|
ERR_make_permanent(vector);
|
|
|
|
internal_post(vector);
|
2004-08-21 11:29:46 +02:00
|
|
|
}
|
|
|
|
|
2004-08-06 17:26:55 +02:00
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
void ERR_make_permanent(ISC_STATUS* s)
|
2004-08-10 15:40:10 +02:00
|
|
|
/**************************************
|
|
|
|
*
|
2008-08-27 14:20:47 +02:00
|
|
|
* E R R _ m a k e _ p e r m a n e n t
|
2004-08-10 15:40:10 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2008-08-27 14:20:47 +02:00
|
|
|
* Make strings in vector permanent
|
2004-08-10 15:40:10 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2004-08-06 17:26:55 +02:00
|
|
|
{
|
2008-08-27 14:20:47 +02:00
|
|
|
Attachment* att = JRD_get_thread_data()->getAttachment();
|
|
|
|
if (att) {
|
2008-11-12 15:32:18 +01:00
|
|
|
MutexLockGuard(att->att_strings_mutex);
|
2008-09-03 10:55:09 +02:00
|
|
|
if (att->att_strings_buffer != ((StringsBuffer*)(~0)))
|
2008-08-27 14:20:47 +02:00
|
|
|
{
|
|
|
|
if (!att->att_strings_buffer)
|
|
|
|
{
|
2008-09-03 10:55:09 +02:00
|
|
|
att->att_strings_buffer = FB_NEW(*att->att_pool) CircularStringsBuffer<MAXPATHLEN * 4>;
|
2008-08-27 14:20:47 +02:00
|
|
|
}
|
|
|
|
att->att_strings_buffer->makePermanentVector(s, s);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2004-09-25 12:28:09 +02:00
|
|
|
|
2008-09-03 10:55:09 +02:00
|
|
|
StringsBuffer::makeEnginePermanentVector(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ERR_make_permanent(Arg::StatusVector& v)
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* E R R _ m a k e _ p e r m a n e n t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Make strings in vector permanent
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
{
|
|
|
|
ERR_make_permanent(const_cast<ISC_STATUS*>(v.value()));
|
2004-08-21 11:29:46 +02:00
|
|
|
}
|
|
|
|
|
2004-08-06 17:26:55 +02:00
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
void ERR_post(const Arg::StatusVector& v)
|
2008-07-10 17:57:33 +02:00
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* 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.
|
2008-07-10 17:57:33 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
{
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post_nothrow(v);
|
2008-07-10 17:57:33 +02:00
|
|
|
|
|
|
|
DEBUG;
|
|
|
|
ERR_punt();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
static void internal_post(const ISC_STATUS* tmp_status)
|
2008-07-10 17:57:33 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i n t e r n a l _ p o s t 2
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Append status vector with new values.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
/* calculate length of the status */
|
2006-05-04 04:57:26 +02:00
|
|
|
int tmp_status_len = 0, warning_indx = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
PARSE_STATUS(tmp_status, tmp_status_len, warning_indx);
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(warning_indx == 0);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
ISC_STATUS* status_vector = JRD_get_thread_data()->tdbb_status_vector;
|
2008-07-10 17:57:33 +02:00
|
|
|
|
2003-11-11 13:19:20 +01:00
|
|
|
if (status_vector[0] != isc_arg_gds ||
|
|
|
|
(status_vector[0] == isc_arg_gds && status_vector[1] == 0 &&
|
2008-12-20 09:12:19 +01:00
|
|
|
status_vector[2] != isc_arg_warning))
|
2004-07-07 05:43:20 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
/* this is a blank status vector just stuff the status */
|
2008-02-03 11:41:44 +01:00
|
|
|
memcpy(status_vector, tmp_status, sizeof(ISC_STATUS) * tmp_status_len);
|
2004-08-06 17:26:55 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2006-05-04 04:57:26 +02:00
|
|
|
int status_len = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
PARSE_STATUS(status_vector, status_len, warning_indx);
|
|
|
|
if (status_len)
|
|
|
|
--status_len;
|
|
|
|
|
2006-05-04 04:57:26 +02:00
|
|
|
/* check for duplicated error code */
|
|
|
|
int i;
|
2001-05-23 15:26:42 +02:00
|
|
|
for (i = 0; i < ISC_STATUS_LENGTH; i++) {
|
2003-11-11 13:19:20 +01:00
|
|
|
if (status_vector[i] == isc_arg_end && i == status_len)
|
2001-05-23 15:26:42 +02:00
|
|
|
break; /* end of argument list */
|
|
|
|
|
|
|
|
if (i && i == warning_indx)
|
|
|
|
break; /* vector has no more errors */
|
|
|
|
|
2008-12-20 09:12:19 +01:00
|
|
|
if (status_vector[i] == tmp_status[1] && i && status_vector[i - 1] != isc_arg_warning &&
|
2001-05-23 15:26:42 +02:00
|
|
|
i + tmp_status_len - 2 < ISC_STATUS_LENGTH &&
|
2008-12-20 09:12:19 +01:00
|
|
|
(memcmp(&status_vector[i], &tmp_status[1], sizeof(ISC_STATUS) * (tmp_status_len - 2)) == 0))
|
2004-07-07 05:43:20 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
/* duplicate found */
|
2004-08-06 17:26:55 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if the status_vector has only warnings then adjust err_status_len */
|
2006-05-04 04:57:26 +02:00
|
|
|
int err_status_len = i;
|
|
|
|
if (err_status_len == 2 && warning_indx)
|
2001-05-23 15:26:42 +02:00
|
|
|
err_status_len = 0;
|
|
|
|
|
2006-05-04 04:57:26 +02:00
|
|
|
ISC_STATUS_ARRAY warning_status;
|
|
|
|
int warning_count = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (warning_indx) {
|
|
|
|
/* copy current warning(s) to a temp buffer */
|
|
|
|
MOVE_CLEAR(warning_status, sizeof(warning_status));
|
2008-02-03 11:41:44 +01:00
|
|
|
memcpy(warning_status, &status_vector[warning_indx],
|
2003-04-10 08:49:16 +02:00
|
|
|
sizeof(ISC_STATUS) * (ISC_STATUS_LENGTH - warning_indx));
|
2001-05-23 15:26:42 +02:00
|
|
|
PARSE_STATUS(warning_status, warning_count, warning_indx);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add the status into a real buffer right in between last error
|
|
|
|
and first warning */
|
|
|
|
|
|
|
|
if ((i = err_status_len + tmp_status_len) < ISC_STATUS_LENGTH) {
|
2008-12-20 09:12:19 +01:00
|
|
|
memcpy(&status_vector[err_status_len], tmp_status, sizeof(ISC_STATUS) * tmp_status_len);
|
2001-05-23 15:26:42 +02:00
|
|
|
/* copy current warning(s) to the status_vector */
|
|
|
|
if (warning_count && i + warning_count - 1 < ISC_STATUS_LENGTH) {
|
2008-02-03 11:41:44 +01:00
|
|
|
memcpy(&status_vector[i - 1], warning_status, sizeof(ISC_STATUS) * warning_count);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
2004-08-06 17:26:55 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2007-12-03 16:46:39 +01:00
|
|
|
Database* dbb = tdbb->getDatabase();
|
2001-12-24 03:51:06 +01:00
|
|
|
|
|
|
|
if (dbb && (dbb->dbb_flags & DBB_bugcheck))
|
|
|
|
{
|
2007-12-03 16:46:39 +01:00
|
|
|
gds__log_status(tdbb->getAttachment()->att_filename.hasData() ?
|
2008-03-03 14:59:09 +01:00
|
|
|
tdbb->getAttachment()->att_filename.c_str() : NULL,
|
2003-10-29 11:53:47 +01:00
|
|
|
tdbb->tdbb_status_vector);
|
2004-04-10 02:25:22 +02:00
|
|
|
if (Config::getBugcheckAbort())
|
2007-11-02 16:14:57 +01:00
|
|
|
{
|
2004-04-10 02:25:22 +02:00
|
|
|
abort();
|
2007-11-02 16:14:57 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2008-09-03 10:55:09 +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.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-22 16:28:54 +02:00
|
|
|
thread_db* tdbb = JRD_get_thread_data();
|
2008-08-27 14:20:47 +02:00
|
|
|
ISC_STATUS* s = tdbb->tdbb_status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
v.copyTo(s);
|
|
|
|
ERR_make_permanent(s);
|
2001-05-23 15:26:42 +02:00
|
|
|
DEBUG;
|
2007-12-03 16:46:39 +01:00
|
|
|
tdbb->getRequest()->req_flags |= req_warning;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
void ERR_append_status(ISC_STATUS* 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
|
2008-08-27 14:20:47 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* 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);
|
|
|
|
ERR_make_permanent(status_vector);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ERR_build_status(ISC_STATUS* status_vector, const Arg::StatusVector& v)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
v.copyTo(status_vector);
|
|
|
|
ERR_make_permanent(status_vector);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-05 02:20:14 +01:00
|
|
|
static void internal_error(ISC_STATUS status, int number,
|
2004-09-24 02:11:32 +02:00
|
|
|
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
|
|
|
|
2004-10-09 05:58:45 +02:00
|
|
|
const size_t len = strlen(errmsg);
|
2008-12-05 02:20:14 +01:00
|
|
|
|
2004-09-24 02:11:32 +02:00
|
|
|
if (file) {
|
|
|
|
// Remove path information
|
2004-10-09 05:58:45 +02:00
|
|
|
const TEXT* ptr = (TEXT*)file + strlen(file);
|
2004-09-24 02:11:32 +02:00
|
|
|
for (; ptr > file; ptr--) {
|
|
|
|
if ((*ptr == '/') || (*ptr == '\\')) {
|
|
|
|
ptr++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-10-09 05:58:45 +02:00
|
|
|
fb_utils::snprintf(errmsg + len, sizeof(errmsg) - len,
|
|
|
|
" (%d), file: %s line: %d", number, ptr, line);
|
2004-09-24 02:11:32 +02:00
|
|
|
}
|
|
|
|
else {
|
2004-10-09 05:58:45 +02:00
|
|
|
fb_utils::snprintf(errmsg + len, sizeof(errmsg) - len, " (%d)", number);
|
2004-09-24 02:11:32 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-08-27 14:20:47 +02:00
|
|
|
ERR_post(Arg::Gds(status) << Arg::Str(errmsg));
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2004-03-07 08:58:55 +01:00
|
|
|
|