Skip to content

Commit

Permalink
[#59] Bug fixes and last minute changes
Browse files Browse the repository at this point in the history
1. Fix ydb_exit() to properly allow a call with process_exiting set so long as gtm_startup_active is also set.
2. Change all SKIP_BASE_FRAME invocations to SKIP_BASE_FRAMES and make the new macro be able to unwind past adjacent base frames of same or dissimilar types.
3. Visit all places where SFT_CI is used to make sure they are able to jump both TRIGGER and call-in base frames if that is appropriate (additional uses of SKIP_BASE_FRAMES was used in this effort).
4. Reverted gtm_filename_to_id() to what it was before (logic wise) undoing the attempt to return an error code.
5. Modified ydb_file_name_to_id() to no longer be a wrapper for gtm_filename_to_id() but now has simliar logic in that DOES return an error code.
6. The -1 return codes from ydb_thread_is_main() and ydb_file_is_identical() are changed to YDB_NOTOK which is an error code added to libyottadb.h (not a real error - just a value like YDB_LOCK_TIMEOUT).
7. Added invocation to create the YDB_FATAL_ERROR file when a fatal error is encountered in simpleAPI.
  • Loading branch information
estess authored and nars1 committed Mar 27, 2018
1 parent e26877a commit be9ecab
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 98 deletions.
15 changes: 4 additions & 11 deletions sr_port/alias_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2009, 2015 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* Copyright (c) 2017 YottaDB LLC. and/or its subsidiaries. *
* Copyright (c) 2017-2018 YottaDB LLC. and/or its subsidiaries.*
* All rights reserved. *
* *
* This source code contains the intellectual property *
Expand Down Expand Up @@ -296,16 +296,9 @@ void als_lsymtab_repair(hash_table_mname *table, ht_ent_mname *table_base_orig,
fp = fp->old_frame_pointer; /* Bump to prev frame and check if found a call-in base frame */
if (done)
break;
if ((NULL != fp) && (SFT_CI & fp->type))
{ /* Callins needs to be able to crawl past apparent end of stack to earlier stack segments.
* We should be in the base frame now. See if an earlier frame exists.
* Note we don't worry about trigger base frames here because triggers *always* have a
* different symbol table - previous symbol tables and stack levels are not affected.
*/
fp = *(stack_frame **)(fp + 1); /* Backups up to "prev pointer" created by base_frame() */
if ((NULL == fp) || (fp >= (stack_frame *)stackbase) || (fp < (stack_frame *)stacktop))
break; /* Pointer not within the stack -- must be earliest occurence */
}
SKIP_BASE_FRAMES(fp); /* Updates fp */
if ((NULL == fp) || (fp >= (stack_frame *)stackbase) || (fp < (stack_frame *)stacktop))
break; /* Pointer not within the stack -- must be earliest occurence */
} while(fp);
/* Next, check the mv_stents for the stackframes we processed. Certain mv_stents also have hash
* table references in them that need repair.
Expand Down
9 changes: 2 additions & 7 deletions sr_port/mprof_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2001-2017 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* Copyright (c) 2017 YottaDB LLC. and/or its subsidiaries. *
* Copyright (c) 2017-2018 YottaDB LLC. and/or its subsidiaries.*
* All rights reserved. *
* *
* This source code contains the intellectual property *
Expand Down Expand Up @@ -817,12 +817,7 @@ STATICFNDEF void get_entryref_information(boolean_t line, trace_entry *tmp_trc_t
line_reset = FALSE;
for (fp = frame_pointer; fp; fp = fp->old_frame_pointer)
{
if (fp->type & (GTMTRIG_ONLY(SFT_TRIGR) | SFT_CI))
{
assert(NULL == fp->old_frame_pointer);
/* Have a trigger or call-in baseframe, pick up stack continuation frame_pointer stored by base_frame() */
fp = *(stack_frame **)(fp + 1);
}
SKIP_BASE_FRAMES(fp); /* Updates fp */
assert(fp);
if (ADDR_IN_CODE(fp->mpc, fp->rvector))
{
Expand Down
15 changes: 10 additions & 5 deletions sr_port/op_clralsvars.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2009-2014 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* Copyright (c) 2017 YottaDB LLC. and/or its subsidiaries. *
* Copyright (c) 2017-2018 YottaDB LLC. and/or its subsidiaries.*
* All rights reserved. *
* *
* This source code contains the intellectual property *
Expand Down Expand Up @@ -107,14 +107,19 @@ void op_clralsvars(lv_val *rslt)
if (done)
break;
if (SFT_CI & fp->type)
{ /* Callins needs to be able to crawl past apparent end of stack (due to call-in base frame)
* to earlier stack segments. Base frames hide the stack continue address behind them so
{ /* For call-ins we need to be able to crawl past apparent end of stack (due to call-in base
* frame) to earlier stack segments. Base frames hide the stack continue address behind them so
* pick that up and see if it allows us to continue the unroll.
*
* Note no check for triggers here as their locals are isolated so hitting a trigger base
* frame stops this search back through the stack.
* frame stops this search back through the stack. Because of that, we do not use the
* SKIP_BASE_FRAMES() macro here.
*/
fp = *(stack_frame **)(fp + 1); /* Backups up to "prev pointer" created by base_frame() */
assert(NULL == fp->old_frame_pointer);
while ((NULL == fp->old_frame_pointer) && (SFT_CI & fp->type))
{
fp = *(stack_frame **)(fp + 1); /* Load "prev pointer" created by base_frame() */
}
if ((NULL == fp) || (fp >= (stack_frame *)stackbase) || (fp < (stack_frame *)stacktop))
break; /* Pointer not within the stack -- must be earliest occurence */
} else
Expand Down
12 changes: 1 addition & 11 deletions sr_port/op_zgoto.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2011-2017 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* Copyright (c) 2017 YottaDB LLC. and/or its subsidiaries. *
* Copyright (c) 2017-2018 YottaDB LLC. and/or its subsidiaries.*
* All rights reserved. *
* *
* This source code contains the intellectual property *
Expand All @@ -29,14 +29,10 @@
#include "gtmimagename.h"
#include "linktrc.h"
#include "gtm_unlink_all.h"
#ifdef GTM_TRIGGER
#include "gtm_trigger_trc.h"
#endif

GBLREF stack_frame *frame_pointer;
#ifdef GTM_TRIGGER
GBLREF boolean_t goframes_unwound_trigger;
#endif

LITREF gtmImageName gtmImageNames[];

Expand Down Expand Up @@ -120,15 +116,13 @@ void op_zgoto(mval *rtn_name, mval *lbl_name, int offset, int level)
lnrptr = op_labaddr(rtnhdr, &lblname, offset);
# endif
assert(NULL != lnrptr);
# ifdef GTM_TRIGGER
if (!IS_GTM_IMAGE && (1 >= level))
/* In MUPIP (or other utility that gets trigger support in the future), levels 0 and 1 refer to
* the pseudo baseframe and initial stack levels which are not rewritable (in the case where an
* entry ref was coded) and are not resume-able (if no entry ref were specified) so we cannot
* permit ZGOTOs to these levels in a utility.
*/
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_ZGOTOINVLVL, 3, GTMIMAGENAMETXT(image_type), level);
# endif
/* One last check if we are unlinking, make sure no call-in frames exist on our stack */
if (0 == level)
{
Expand All @@ -142,14 +136,12 @@ void op_zgoto(mval *rtn_name, mval *lbl_name, int offset, int level)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZGOCALLOUTIN);
if (NULL == fpprev)
{ /* Next frame is some sort of base frame */
# ifdef GTM_TRIGGER
if (fp->type & SFT_TRIGR)
{ /* Have a trigger baseframe, pick up stack continuation frame_pointer stored by
*base_frame() */
fpprev = *(stack_frame **)(fp + 1);
continue;
} else
# endif
break; /* Some other base frame that stops us */
}
}
Expand Down Expand Up @@ -194,13 +186,11 @@ void op_zgoto(mval *rtn_name, mval *lbl_name, int offset, int level)
NON_USHBIN_ONLY((* frame_func)(rtnhdr, (unsigned char *)LINKAGE_ADR(rtnhdr),
(unsigned char *)((int)rtnhdr + *(int *)((int)rtnhdr + *lnrptr))));
DBGEHND((stderr, "op_zgoto: Resuming at frame 0x"lvaddr" with type 0x%04lx\n", frame_pointer, frame_pointer->type));
# ifdef GTM_TRIGGER
if (goframes_unwound_trigger)
{ /* If goframes() called by golevel unwound a trigger base frame, we must use MUM_TSTART to unroll the
* C stack before invoking the return frame. Otherwise we can just return and avoid the overhead that
* MUM_TSTART incurs.
*/
MUM_TSTART;
}
# endif
}
24 changes: 19 additions & 5 deletions sr_port/stack_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ typedef struct stack_frame_struct /* contents of the GT.M MUMPS stack frame */
#define SIMPLEAPI_M_ENTRYREF "(SimpleAPI)" /* M entryref equivalent for simpleAPI. Filled in $zstatus */

#define ADJUST_FRAME_POINTER(fptr, shift) \
{ \
MBSTART { \
GBLREF stack_frame *error_frame; \
stack_frame *oldfp; \
\
Expand All @@ -138,13 +138,27 @@ typedef struct stack_frame_struct /* contents of the GT.M MUMPS stack frame */
assert(error_frame >= frame_pointer); \
error_frame = fptr; \
} \
}
} MBEND

/*
* Skip past trigger and/or call-in base frames
* Skip past trigger and/or call-in base frames - as many of them as appear adjacent (updates FP)
*/
#define SKIP_BASE_FRAME(FP) (((NULL != (FP)) && ((GTMTRIG_ONLY(SFT_TRIGR |) SFT_CI) & (FP)->type)) \
? *(stack_frame **)((FP) + 1) : (FP))
#define SKIP_BASE_FRAMES(FP) \
MBSTART { \
if (NULL != (FP)) \
{ \
while (NULL == (FP)->old_frame_pointer) \
{ /* We may need to jump over a base frame to get the rest of the M stack */ \
if ((SFT_TRIGR | SFT_CI) & (FP)->type) \
{ /* We have a trigger or call-in base frame, back up over it */ \
FP = *(stack_frame **)((FP) + 1); \
continue; \
} \
/* Either origin frame or mumps/updproc base frame */ \
break; \
} \
} \
} MBEND

void new_stack_frame(rhdtyp *rtn_base, unsigned char *context, unsigned char *transfer_addr);
void new_stack_frame_sp(rhdtyp *rtn_base, unsigned char *context, unsigned char *transfer_addr);
Expand Down
11 changes: 1 addition & 10 deletions sr_port/stp_gcol_src.h
Original file line number Diff line number Diff line change
Expand Up @@ -850,16 +850,7 @@ void stp_gcol(size_t space_asked) /* BYPASSOK */
* base frame described above, that also has a type of SFT_COUNT should stop rearward
* stack travel and break the loop.
*/
while (NULL == sf->old_frame_pointer)
{ /* We may need to jump over a base frame to get the rest of the M stack */
if ((GTMTRIG_ONLY(SFT_TRIGR |) SFT_CI) & sf->type)
{ /* We have a trigger or call-in base frame, back up over it */
sf = *(stack_frame **)(sf + 1);
continue;
}
/* Either origin frame or mumps/updproc base frame */
break;
}
SKIP_BASE_FRAMES(sf); /* Updates sf */
if (NULL == sf)
break;
assert(sf->temps_ptr);
Expand Down
8 changes: 4 additions & 4 deletions sr_port/zlput_rname.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2001-2015 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* Copyright (c) 2017 YottaDB LLC. and/or its subsidiaries. *
* Copyright (c) 2017-2018 YottaDB LLC. and/or its subsidiaries.*
* All rights reserved. *
* *
* This source code contains the intellectual property *
Expand Down Expand Up @@ -145,7 +145,7 @@ boolean_t on_stack(rhdtyp *rtnhdr, boolean_t *need_duplicate)
*need_duplicate = FALSE;
for (fp = frame_pointer; NULL != fp; fp = fp->old_frame_pointer)
{
fp = SKIP_BASE_FRAME(fp);
SKIP_BASE_FRAMES(fp); /* Updates fp */
if (MSTR_EQ(&fp->rvector->routine_name, &rtnhdr->routine_name))
{
if ((NULL != need_duplicate) && (CURRENT_RHEAD_ADR(fp->rvector) == rtnhdr))
Expand Down Expand Up @@ -240,7 +240,7 @@ STATICFNDEF boolean_t handle_active_old_versions(boolean_t *duplicated, rhdtyp *
old_rhead->active_rhead_adr = copy_rhead; /* Reserve previous version on active chain */
for (fp = frame_pointer; NULL != fp; fp = fp->old_frame_pointer)
{
fp = SKIP_BASE_FRAME(fp);
SKIP_BASE_FRAMES(fp); /* Updates fp */
DBGARLNK_ONLY(fprhd = CURRENT_RHEAD_ADR(fp->rvector));
if (CURRENT_RHEAD_ADR(fp->rvector) == old_rhead)
{
Expand Down Expand Up @@ -311,7 +311,7 @@ void zr_cleanup_recursive_rtn(rhdtyp *rtnhdr)
/* See if routine is still in use */
for (fp = frame_pointer; fp; fp = fp->old_frame_pointer)
{
fp = SKIP_BASE_FRAME(fp);
SKIP_BASE_FRAMES(fp); /* Update rp */
if (rtnhdr == fp->rvector)
break; /* Found reference - not done with it */
}
Expand Down
2 changes: 1 addition & 1 deletion sr_port/zshow_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void zshow_stack(zshow_out *output, boolean_t show_checksum)
zshow_output(output, &v);
v.len = 0;
}
fp = SKIP_BASE_FRAME(fp);
SKIP_BASE_FRAMES(fp); /* Updates fp */
if (NULL == fp->old_frame_pointer)
break; /* Endpoint.. */
if (!(fp->type & SFT_COUNT) || ((fp->type & SFT_ZINTR) && (fp->flags & SFF_INDCE)))
Expand Down
8 changes: 4 additions & 4 deletions sr_unix/gtm_trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -932,13 +932,13 @@ void gtm_trigger_cleanup(gv_trigger_t *trigdsc)
/* Verify trigger routine we want to remove is not currently active. If it is, we need to assert fail.
* Triggers are not like regular routines since they should only ever be referenced from the stack during a
* transaction. Likewise, we should only ever load the triggers as the first action in that transaction.
* Note, we can use SKIP_BASE_FRAME in the "for" statement here where we cannot in other places. In those
* other places, we want the checks done in SKIP_BASE_FRAME to be applicable to "fp" in the first iteration
* but here it is impossible for the first frame we look at to be either a trigger or call-in frame.
*/
# ifdef DEBUG
for (fp = frame_pointer; NULL != fp; fp = SKIP_BASE_FRAME(fp->old_frame_pointer))
for (fp = frame_pointer; NULL != fp; fp = fp->old_frame_pointer)
{
SKIP_BASE_FRAMES(fp);
assert(fp->rvector != rtnhdr);
}
# endif
/* Locate the routine in the routine table while all the pieces are available. Then remove from routine table
* after the routine is unlinked.
Expand Down
20 changes: 8 additions & 12 deletions sr_unix/gtm_unique_file_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,23 @@ ydb_status_t gtm_is_file_identical(ydb_fileid_ptr_t fileid1, ydb_fileid_ptr_t fi

/* Converts given filename to unique file id. Uses filename_to_id internally for getting the unique id. Note that,
* the allocation of the fileid structure is done here and the caller needs to worry only about free'ing the
* allocated pointer via gtm_xcfileid_free. */
* allocated pointer via gtm_xcfileid_free.
*
* Note, a reimplementation of this routine exists in ydb_file_name_to_id() so any changes here need to be
* reflected there.
*/
ydb_status_t gtm_filename_to_id(ydb_string_t *filename, ydb_fileid_ptr_t *fileid)
{
int actstatus;
boolean_t status;
gd_id_ptr_t tmp_fileid;

if (!filename)
return FALSE;
assert(fileid && !*fileid);
tmp_fileid = (gd_id_ptr_t)malloc(SIZEOF(gd_id));
actstatus = filename_to_id(tmp_fileid, filename->address);
status = (SS_NORMAL == actstatus);
if (status)
*fileid = (ydb_fileid_ptr_t)tmp_fileid;
else
{ /* There was an error */
free(tmp_fileid);
*fileid = NULL;
}
return status ? YDB_OK : actstatus;
status = (SS_NORMAL == filename_to_id(tmp_fileid, filename->address));
*fileid = (ydb_fileid_ptr_t)tmp_fileid;
return status;
}

/* Allocation of ydb_fileid_ptr_t happens in gtm_filename_to_id. During the close time, encryption library needs to free these
Expand Down
44 changes: 24 additions & 20 deletions sr_unix/gtmci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1244,28 +1244,32 @@ int ydb_exit()
return 0; /* GT.M environment not setup yet - quietly return */
ESTABLISH_RET(gtmci_ch, mumps_status);
assert(NULL != frame_pointer);
/* Do not allow ydb_exit() to be invoked from external calls (unless process_exiting) */
if (process_exiting || (!(SFT_CI & frame_pointer->type) || !(MUMPS_CALLIN & invocation_mode)
|| (1 < TREF(gtmci_nested_level))))
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVYDBEXIT);
/* Now get rid of the whole M stack - end of GT.M environment */
while (NULL != frame_pointer)
{
while ((NULL != frame_pointer) && !(frame_pointer->type & SFT_CI))
/* If process_exiting is set and the YottaDB environment is still active, shortcut some of the checks
* and cleanups we are making in this routine as they are not particularly useful. If the environment
* is not active though, that's still an error.
*/
if (!process_exiting && gtm_startup_active)
{ /* Do not allow ydb_exit() to be invoked from external calls (unless process_exiting) */
if (!(SFT_CI & frame_pointer->type) || !(MUMPS_CALLIN & invocation_mode) || (1 < TREF(gtmci_nested_level)))
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVYDBEXIT);
/* Now get rid of the whole M stack - end of GT.M environment */
while (NULL != frame_pointer)
{
# ifdef GTM_TRIGGER
if (SFT_TRIGR & frame_pointer->type)
gtm_trigger_fini(TRUE, FALSE);
else
# endif
op_unwind();
}
if (NULL != frame_pointer)
{ /* unwind the current invocation of call-in environment */
assert(frame_pointer->type & SFT_CI);
ci_ret_code_quit();
while ((NULL != frame_pointer) && !(frame_pointer->type & SFT_CI))
{
if (SFT_TRIGR & frame_pointer->type)
gtm_trigger_fini(TRUE, FALSE);
else
op_unwind();
}
if (NULL != frame_pointer)
{ /* unwind the current invocation of call-in environment */
assert(frame_pointer->type & SFT_CI);
ci_ret_code_quit();
}
}
}
} else if (!gtm_startup_active)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVYDBEXIT);
gtm_exit_handler(); /* rundown all open database resource */
/* If libyottadb was loaded via (or on account of) dlopen() and is later unloaded via dlclose()
* the exit handler on AIX and HPUX still tries to call the registered atexit() handler causing
Expand Down
Loading

0 comments on commit be9ecab

Please sign in to comment.