mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 05:23:03 +01:00
Ability to show PSQL stack trace when exception occurs.
This commit is contained in:
parent
5265e42000
commit
d82cde309e
@ -60,6 +60,7 @@ using namespace Jrd;
|
||||
|
||||
|
||||
static void internal_error(ISC_STATUS, int);
|
||||
static void internal_post(ISC_STATUS status, va_list args);
|
||||
|
||||
|
||||
#if ( !defined( REQUESTER) && !defined( SUPERCLIENT))
|
||||
@ -392,7 +393,26 @@ bool ERR_post_warning(ISC_STATUS status, ...)
|
||||
|
||||
|
||||
#if ( !defined( REQUESTER) && !defined( SUPERCLIENT))
|
||||
void ERR_post_nothrow(ISC_STATUS status, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, status);
|
||||
|
||||
internal_post(status, args);
|
||||
};
|
||||
|
||||
void ERR_post(ISC_STATUS status, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, status);
|
||||
|
||||
internal_post(status, args);
|
||||
|
||||
DEBUG;
|
||||
ERR_punt();
|
||||
};
|
||||
|
||||
static void internal_post(ISC_STATUS status, va_list args)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -412,7 +432,7 @@ void ERR_post(ISC_STATUS status, ...)
|
||||
|
||||
/* stuff the status into temp buffer */
|
||||
MOVE_CLEAR(tmp_status, sizeof(tmp_status));
|
||||
STUFF_STATUS(tmp_status, status);
|
||||
STUFF_STATUS_function(tmp_status, status, args);
|
||||
|
||||
/* calculate length of the status */
|
||||
PARSE_STATUS(tmp_status, tmp_status_len, warning_indx);
|
||||
@ -425,8 +445,7 @@ void ERR_post(ISC_STATUS status, ...)
|
||||
/* this is a blank status vector just stuff the status */
|
||||
MOVE_FASTER(tmp_status, status_vector,
|
||||
sizeof(ISC_STATUS) * tmp_status_len);
|
||||
DEBUG;
|
||||
ERR_punt();
|
||||
return;
|
||||
}
|
||||
|
||||
PARSE_STATUS(status_vector, status_len, warning_indx);
|
||||
@ -448,8 +467,7 @@ void ERR_post(ISC_STATUS status, ...)
|
||||
sizeof(ISC_STATUS) * (tmp_status_len - 2)) == 0))
|
||||
{
|
||||
/* duplicate found */
|
||||
DEBUG;
|
||||
ERR_punt();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,8 +495,7 @@ void ERR_post(ISC_STATUS status, ...)
|
||||
sizeof(ISC_STATUS) * warning_count);
|
||||
}
|
||||
}
|
||||
DEBUG;
|
||||
ERR_punt();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -54,6 +54,7 @@ void ERR_duplicate_error(Jrd::idx_e, const Jrd::jrd_rel*, USHORT);
|
||||
void ERR_error(int);
|
||||
void ERR_error_msg(const TEXT*);
|
||||
void ERR_post(ISC_STATUS, ...);
|
||||
void ERR_post_nothrow(ISC_STATUS, ...);
|
||||
void ERR_punt(void);
|
||||
void ERR_warning(ISC_STATUS, ...);
|
||||
void ERR_log(int, int, const TEXT*);
|
||||
|
@ -172,6 +172,7 @@ static void trigger_failure(thread_db*, jrd_req*);
|
||||
static void validate(thread_db*, jrd_nod*);
|
||||
inline void PreModifyEraseTriggers(thread_db*, trig_vec**, SSHORT, record_param*,
|
||||
Record*, jrd_req::req_ta);
|
||||
static void stuff_stack_trace(const jrd_req* request);
|
||||
|
||||
#ifdef PC_ENGINE
|
||||
static jrd_nod* find(thread_db*, jrd_nod*);
|
||||
@ -204,6 +205,8 @@ const int ALL_TRIGS = 0;
|
||||
const int PRE_TRIG = 1;
|
||||
const int POST_TRIG = 2;
|
||||
|
||||
const int MAX_STACK_TRACE = 2048;
|
||||
|
||||
/* this constant defines how many records are locked
|
||||
before we check whether record locking has been
|
||||
turned off for a given relation; if we set the
|
||||
@ -1748,6 +1751,44 @@ static Lock* implicit_record_lock(jrd_tra* transaction, record_param* rpb)
|
||||
#endif
|
||||
|
||||
|
||||
static void stuff_stack_trace(const jrd_req* request)
|
||||
{
|
||||
Firebird::string sTrace;
|
||||
bool isEmpty = true;
|
||||
|
||||
for(const jrd_req* req = request; req; req = req->req_caller)
|
||||
{
|
||||
Firebird::string name;
|
||||
|
||||
if (req->req_trg_name) {
|
||||
name = "At trigger '";
|
||||
name += req->req_trg_name;
|
||||
}
|
||||
else if (req->req_procedure) {
|
||||
name = "At procedure '";
|
||||
name += req->req_procedure->prc_name;
|
||||
}
|
||||
|
||||
if (! name.isEmpty())
|
||||
{
|
||||
name.trim();
|
||||
|
||||
if(sTrace.length() + name.length() > MAX_STACK_TRACE)
|
||||
break;
|
||||
|
||||
if (isEmpty) {
|
||||
isEmpty = false;
|
||||
sTrace += name + "'";
|
||||
}
|
||||
else
|
||||
sTrace += "\n" + name + "'";
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEmpty)
|
||||
ERR_post_nothrow(isc_random, isc_arg_string, ERR_cstring(sTrace), 0);
|
||||
}
|
||||
|
||||
static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
|
||||
{
|
||||
/**************************************
|
||||
@ -1813,6 +1854,7 @@ static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
|
||||
|
||||
bool error_pending = false;
|
||||
bool catch_disabled = false;
|
||||
tdbb->tdbb_flags &= ~TDBB_stack_trace_done;
|
||||
|
||||
// Execute stuff until we drop
|
||||
|
||||
@ -2765,6 +2807,11 @@ static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
|
||||
error_pending = true;
|
||||
request->req_operation = jrd_req::req_unwind;
|
||||
request->req_label = 0;
|
||||
|
||||
if (! (tdbb->tdbb_flags & TDBB_stack_trace_done) ) {
|
||||
stuff_stack_trace(request);
|
||||
tdbb->tdbb_flags |= TDBB_stack_trace_done;
|
||||
}
|
||||
}
|
||||
} // while()
|
||||
|
||||
|
@ -933,6 +933,7 @@ const USHORT TDBB_no_cache_unwind = 2; /* Don't unwind page buffer cache */
|
||||
const USHORT TDBB_prc_being_dropped = 4; /* Dropping a procedure */
|
||||
const USHORT TDBB_set_backup_state = 8; /* Setting state for backup lock */
|
||||
const USHORT TDBB_backup_merge = 16; /* Merging changes from difference file */
|
||||
const USHORT TDBB_stack_trace_done = 32; /* PSQL stack trase is added into status-vector */
|
||||
|
||||
/* List of internal database handles */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user