mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 06:43:03 +01:00
Backported fix for CORE-3612: gfix-related services may loose error value in status vector in isc_service_start()
This commit is contained in:
parent
b42ce8e27b
commit
2689670200
@ -84,7 +84,7 @@ void ALICE_exit(int code, AliceGlobals* tdgbl)
|
|||||||
Firebird::LongJump::raise();
|
Firebird::LongJump::raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alice_output(const SCHAR*, ...) ATTRIBUTE_FORMAT(1,2);
|
static void alice_output(bool error, const SCHAR*, ...) ATTRIBUTE_FORMAT(2,3);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -105,8 +105,8 @@ THREAD_ENTRY_DECLARE ALICE_main(THREAD_ENTRY_PARAM arg)
|
|||||||
{
|
{
|
||||||
ISC_STATUS_ARRAY status;
|
ISC_STATUS_ARRAY status;
|
||||||
e.stuff_exception(status);
|
e.stuff_exception(status);
|
||||||
uSvc->initStatus();
|
|
||||||
uSvc->setServiceStatus(status);
|
uSvc->setServiceStatus(status);
|
||||||
|
uSvc->started();
|
||||||
exit_code = FB_FAILURE;
|
exit_code = FB_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,7 +494,6 @@ int alice(Firebird::UtilSvc* uSvc)
|
|||||||
if (uSvc->isService())
|
if (uSvc->isService())
|
||||||
{
|
{
|
||||||
uSvc->setServiceStatus(ALICE_MSG_FAC, 20, MsgFormat::SafeArg());
|
uSvc->setServiceStatus(ALICE_MSG_FAC, 20, MsgFormat::SafeArg());
|
||||||
uSvc->started();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -559,7 +558,7 @@ int alice(Firebird::UtilSvc* uSvc)
|
|||||||
|
|
||||||
if (ret == FINI_ERROR)
|
if (ret == FINI_ERROR)
|
||||||
{
|
{
|
||||||
ALICE_print_status(tdgbl->status);
|
ALICE_print_status(true, tdgbl->status);
|
||||||
ALICE_exit(FINI_ERROR, tdgbl);
|
ALICE_exit(FINI_ERROR, tdgbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,12 +576,10 @@ int alice(Firebird::UtilSvc* uSvc)
|
|||||||
{
|
{
|
||||||
// Non-alice exception was caught
|
// Non-alice exception was caught
|
||||||
e.stuff_exception(tdgbl->status_vector);
|
e.stuff_exception(tdgbl->status_vector);
|
||||||
ALICE_print_status(tdgbl->status_vector);
|
ALICE_print_status(true, tdgbl->status_vector);
|
||||||
exit_code = FINI_ERROR;
|
exit_code = FINI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
tdgbl->uSvc->started();
|
|
||||||
|
|
||||||
AliceGlobals::restoreSpecific();
|
AliceGlobals::restoreSpecific();
|
||||||
|
|
||||||
#if defined(DEBUG_GDS_ALLOC)
|
#if defined(DEBUG_GDS_ALLOC)
|
||||||
@ -597,6 +594,7 @@ int alice(Firebird::UtilSvc* uSvc)
|
|||||||
uSvc->initStatus();
|
uSvc->initStatus();
|
||||||
uSvc->setServiceStatus(tdgbl->status);
|
uSvc->setServiceStatus(tdgbl->status);
|
||||||
}
|
}
|
||||||
|
tdgbl->uSvc->started();
|
||||||
|
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
@ -627,7 +625,7 @@ void ALICE_print(USHORT number, const SafeArg& arg)
|
|||||||
TEXT buffer[256];
|
TEXT buffer[256];
|
||||||
|
|
||||||
fb_msg_format(0, ALICE_MSG_FAC, number, sizeof(buffer), buffer, arg);
|
fb_msg_format(0, ALICE_MSG_FAC, number, sizeof(buffer), buffer, arg);
|
||||||
alice_output("%s\n", buffer);
|
alice_output(false, "%s\n", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -637,7 +635,7 @@ void ALICE_print(USHORT number, const SafeArg& arg)
|
|||||||
// to allow redirecting output.
|
// to allow redirecting output.
|
||||||
//
|
//
|
||||||
|
|
||||||
void ALICE_print_status(const ISC_STATUS* status_vector)
|
void ALICE_print_status(bool error, const ISC_STATUS* status_vector)
|
||||||
{
|
{
|
||||||
if (status_vector && status_vector[1])
|
if (status_vector && status_vector[1])
|
||||||
{
|
{
|
||||||
@ -645,15 +643,20 @@ void ALICE_print_status(const ISC_STATUS* status_vector)
|
|||||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||||
tdgbl->uSvc->setServiceStatus(status_vector);
|
tdgbl->uSvc->setServiceStatus(status_vector);
|
||||||
|
|
||||||
|
if (error && tdgbl->uSvc->isService())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SCHAR s[1024];
|
SCHAR s[1024];
|
||||||
if (fb_interpret(s, sizeof(s), &vector))
|
if (fb_interpret(s, sizeof(s), &vector))
|
||||||
{
|
{
|
||||||
alice_output("%s\n", s);
|
alice_output(error, "%s\n", s);
|
||||||
|
|
||||||
// Continuation of error
|
// Continuation of error
|
||||||
s[0] = '-';
|
s[0] = '-';
|
||||||
while (fb_interpret(s + 1, sizeof(s) - 1, &vector)) {
|
while (fb_interpret(s + 1, sizeof(s) - 1, &vector)) {
|
||||||
alice_output("%s\n", s);
|
alice_output(error, "%s\n", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -671,9 +674,12 @@ void ALICE_error(USHORT number, const SafeArg& arg)
|
|||||||
TEXT buffer[256];
|
TEXT buffer[256];
|
||||||
|
|
||||||
tdgbl->uSvc->setServiceStatus(ALICE_MSG_FAC, number, arg);
|
tdgbl->uSvc->setServiceStatus(ALICE_MSG_FAC, number, arg);
|
||||||
|
if (!tdgbl->uSvc->isService())
|
||||||
|
{
|
||||||
|
fb_msg_format(0, ALICE_MSG_FAC, number, sizeof(buffer), buffer, arg);
|
||||||
|
alice_output(true, "%s\n", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
fb_msg_format(0, ALICE_MSG_FAC, number, sizeof(buffer), buffer, arg);
|
|
||||||
alice_output("%s\n", buffer);
|
|
||||||
ALICE_exit(FINI_ERROR, tdgbl);
|
ALICE_exit(FINI_ERROR, tdgbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,7 +689,7 @@ void ALICE_error(USHORT number, const SafeArg& arg)
|
|||||||
// Platform independent output routine.
|
// Platform independent output routine.
|
||||||
//
|
//
|
||||||
|
|
||||||
static void alice_output(const SCHAR* format, ...)
|
static void alice_output(bool error, const SCHAR* format, ...)
|
||||||
{
|
{
|
||||||
|
|
||||||
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
AliceGlobals* tdgbl = AliceGlobals::getSpecific();
|
||||||
@ -694,6 +700,9 @@ static void alice_output(const SCHAR* format, ...)
|
|||||||
buf.vprintf(format, arglist);
|
buf.vprintf(format, arglist);
|
||||||
va_end(arglist);
|
va_end(arglist);
|
||||||
|
|
||||||
tdgbl->uSvc->outputError(buf.c_str());
|
if (error)
|
||||||
|
tdgbl->uSvc->outputError(buf.c_str());
|
||||||
|
else
|
||||||
|
tdgbl->uSvc->outputVerbose(buf.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ static const rfr_tab_t rfr_table[] =
|
|||||||
|
|
||||||
static inline void return_error(const ISC_STATUS* /*user_status*/)
|
static inline void return_error(const ISC_STATUS* /*user_status*/)
|
||||||
{
|
{
|
||||||
ALICE_print_status(gds_status);
|
ALICE_print_status(true, gds_status);
|
||||||
Firebird::LongJump::raise();
|
Firebird::LongJump::raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ static tdr* get_description(ISC_QUAD* blob_id)
|
|||||||
tdgbl->status[1] = isc_virmemexh;
|
tdgbl->status[1] = isc_virmemexh;
|
||||||
tdgbl->status[2] = isc_arg_end;
|
tdgbl->status[2] = isc_arg_end;
|
||||||
|
|
||||||
ALICE_print_status(tdgbl->status);
|
ALICE_print_status(true, tdgbl->status);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
snarf_blob(blob_id, length, bigger_buffer);
|
snarf_blob(blob_id, length, bigger_buffer);
|
||||||
@ -479,7 +479,7 @@ static USHORT snarf_blob(ISC_QUAD* blob_id, USHORT buffer_length, TEXT* buffer)
|
|||||||
FB_API_HANDLE blob = 0;
|
FB_API_HANDLE blob = 0;
|
||||||
if (isc_open_blob(gds_status, &DB, &gds_trans, &blob, blob_id))
|
if (isc_open_blob(gds_status, &DB, &gds_trans, &blob, blob_id))
|
||||||
{
|
{
|
||||||
ALICE_print_status(gds_status);
|
ALICE_print_status(true, gds_status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class AliceGlobals;
|
|||||||
void ALICE_down_case(const TEXT*, TEXT*, const size_t);
|
void ALICE_down_case(const TEXT*, TEXT*, const size_t);
|
||||||
void ALICE_print(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
void ALICE_print(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||||
void ALICE_error(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
void ALICE_error(USHORT, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());
|
||||||
void ALICE_print_status(const ISC_STATUS*);
|
void ALICE_print_status(bool error, const ISC_STATUS*);
|
||||||
void ALICE_exit(int, AliceGlobals*);
|
void ALICE_exit(int, AliceGlobals*);
|
||||||
|
|
||||||
#endif // ALICE_ALICE_PROTO_H
|
#endif // ALICE_ALICE_PROTO_H
|
||||||
|
@ -87,8 +87,6 @@ int EXE_action(const TEXT* database, const SINT64 switches)
|
|||||||
dpb.getBufferLength(),
|
dpb.getBufferLength(),
|
||||||
reinterpret_cast<const SCHAR*>(dpb.getBuffer()));
|
reinterpret_cast<const SCHAR*>(dpb.getBuffer()));
|
||||||
|
|
||||||
tdgbl->uSvc->started();
|
|
||||||
|
|
||||||
if (tdgbl->status[1] &&
|
if (tdgbl->status[1] &&
|
||||||
// Ignore isc_shutdown error produced when we switch to full shutdown mode. It is expected.
|
// Ignore isc_shutdown error produced when we switch to full shutdown mode. It is expected.
|
||||||
(tdgbl->status[1] != isc_shutdown || !(switches & sw_shut) ||
|
(tdgbl->status[1] != isc_shutdown || !(switches & sw_shut) ||
|
||||||
@ -100,7 +98,7 @@ int EXE_action(const TEXT* database, const SINT64 switches)
|
|||||||
if (tdgbl->status[2] == isc_arg_warning)
|
if (tdgbl->status[2] == isc_arg_warning)
|
||||||
{
|
{
|
||||||
Firebird::makePermanentVector(tdgbl->status);
|
Firebird::makePermanentVector(tdgbl->status);
|
||||||
ALICE_print_status(tdgbl->status);
|
ALICE_print_status(false, tdgbl->status);
|
||||||
}
|
}
|
||||||
else if (error)
|
else if (error)
|
||||||
{
|
{
|
||||||
@ -126,6 +124,11 @@ int EXE_action(const TEXT* database, const SINT64 switches)
|
|||||||
|
|
||||||
isc_detach_database(tdgbl->status, &handle);
|
isc_detach_database(tdgbl->status, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
tdgbl->uSvc->setServiceStatus(tdgbl->status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return error ? FINI_ERROR : FINI_OK;
|
return error ? FINI_ERROR : FINI_OK;
|
||||||
@ -173,15 +176,15 @@ int EXE_two_phase(const TEXT* database, const SINT64 switches)
|
|||||||
error = TDR_reconnect_multiple(handle, tdgbl->ALICE_data.ua_transaction, database, switches);
|
error = TDR_reconnect_multiple(handle, tdgbl->ALICE_data.ua_transaction, database, switches);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
Firebird::makePermanentVector(tdgbl->status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
isc_detach_database(tdgbl->status, &handle);
|
isc_detach_database(tdgbl->status, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
tdgbl->uSvc->setServiceStatus(tdgbl->status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (error ? FINI_ERROR : FINI_OK);
|
return (error ? FINI_ERROR : FINI_OK);
|
||||||
|
@ -227,7 +227,7 @@ bool TDR_attach_database(ISC_STATUS* status_vector, tdr* trans, const TEXT* path
|
|||||||
if (tdgbl->ALICE_data.ua_debug)
|
if (tdgbl->ALICE_data.ua_debug)
|
||||||
{
|
{
|
||||||
ALICE_print(69); // msg 69: failed
|
ALICE_print(69); // msg 69: failed
|
||||||
ALICE_print_status(status_vector);
|
ALICE_print_status(false, status_vector);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ void TDR_list_limbo(FB_API_HANDLE handle, const TEXT* name, const SINT64 switche
|
|||||||
sizeof(buffer),
|
sizeof(buffer),
|
||||||
reinterpret_cast<char*>(buffer)))
|
reinterpret_cast<char*>(buffer)))
|
||||||
{
|
{
|
||||||
ALICE_print_status(status_vector);
|
ALICE_print_status(true, status_vector);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,7 +832,7 @@ static bool reconnect(FB_API_HANDLE handle, SLONG number, const TEXT* name, SINT
|
|||||||
{
|
{
|
||||||
ALICE_print(90, SafeArg() << name);
|
ALICE_print(90, SafeArg() << name);
|
||||||
// msg 90: failed to reconnect to a transaction in database %s
|
// msg 90: failed to reconnect to a transaction in database %s
|
||||||
ALICE_print_status(status_vector);
|
ALICE_print_status(false, status_vector);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,7 +858,7 @@ static bool reconnect(FB_API_HANDLE handle, SLONG number, const TEXT* name, SINT
|
|||||||
|
|
||||||
if (status_vector[1])
|
if (status_vector[1])
|
||||||
{
|
{
|
||||||
ALICE_print_status(status_vector);
|
ALICE_print_status(false, status_vector);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +85,12 @@ void StatusVector::ImplStatusVector::clear() throw()
|
|||||||
m_status_vector[0] = isc_arg_end;
|
m_status_vector[0] = isc_arg_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StatusVector::ImplStatusVector::compare(const StatusVector& v) const throw()
|
||||||
|
{
|
||||||
|
return m_length == v.length() &&
|
||||||
|
memcmp(m_status_vector, v.value(), m_length * sizeof(ISC_STATUS)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void StatusVector::ImplStatusVector::append(const StatusVector& v) throw()
|
void StatusVector::ImplStatusVector::append(const StatusVector& v) throw()
|
||||||
{
|
{
|
||||||
ImplStatusVector newVector(getKind(), getCode());
|
ImplStatusVector newVector(getKind(), getCode());
|
||||||
|
@ -71,6 +71,8 @@ protected:
|
|||||||
virtual void shiftLeft(const AbstractString&) throw() { }
|
virtual void shiftLeft(const AbstractString&) throw() { }
|
||||||
virtual void shiftLeft(const MetaName&) throw() { }
|
virtual void shiftLeft(const MetaName&) throw() { }
|
||||||
|
|
||||||
|
virtual bool compare(const StatusVector& v) const throw() { return false; }
|
||||||
|
|
||||||
ImplBase(ISC_STATUS k, ISC_STATUS c) throw() : kind(k), code(c) { }
|
ImplBase(ISC_STATUS k, ISC_STATUS c) throw() : kind(k), code(c) { }
|
||||||
virtual ~ImplBase() { }
|
virtual ~ImplBase() { }
|
||||||
};
|
};
|
||||||
@ -113,6 +115,8 @@ protected:
|
|||||||
virtual void shiftLeft(const AbstractString& text) throw();
|
virtual void shiftLeft(const AbstractString& text) throw();
|
||||||
virtual void shiftLeft(const MetaName& text) throw();
|
virtual void shiftLeft(const MetaName& text) throw();
|
||||||
|
|
||||||
|
virtual bool compare(const StatusVector& v) const throw();
|
||||||
|
|
||||||
ImplStatusVector(ISC_STATUS k, ISC_STATUS c) throw() : ImplBase(k, c)
|
ImplStatusVector(ISC_STATUS k, ISC_STATUS c) throw() : ImplBase(k, c)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
@ -170,6 +174,16 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const StatusVector& arg) const throw()
|
||||||
|
{
|
||||||
|
return implementation->compare(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const StatusVector& arg) const throw()
|
||||||
|
{
|
||||||
|
return !(*this == arg);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -514,9 +514,12 @@ void Service::setServiceStatus(const ISC_STATUS* status_vector)
|
|||||||
{
|
{
|
||||||
Arg::StatusVector svc(svc_status);
|
Arg::StatusVector svc(svc_status);
|
||||||
Arg::StatusVector passed(status_vector);
|
Arg::StatusVector passed(status_vector);
|
||||||
svc.append(passed);
|
if (svc != passed)
|
||||||
svc.copyTo(svc_status);
|
{
|
||||||
makePermanentStatusVector();
|
svc.append(passed);
|
||||||
|
svc.copyTo(svc_status);
|
||||||
|
makePermanentStatusVector();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user