From f11ab09a60ef384fd4de7d9cda43d7ea29faaf2e Mon Sep 17 00:00:00 2001 From: vsc Date: Wed, 2 Mar 2005 18:35:49 +0000 Subject: [PATCH] try to make initialisation process more robust try to make name more robust (in case Lookup new atom fails) git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1254 b08c6af1-5177-4d33-ba66-4b1c6b8b522a --- C/c_interface.c | 66 ++++++-- C/errors.c | 19 ++- C/exec.c | 5 +- C/save.c | 338 +++++++++++++++++++++++++++++------------ C/stdpreds.c | 15 +- console/yap.c | 16 +- docs/yap.tex | 26 +++- include/YapInterface.h | 8 +- include/yap_structs.h | 6 +- m4/Yap.h.m4 | 6 +- 10 files changed, 369 insertions(+), 136 deletions(-) diff --git a/C/c_interface.c b/C/c_interface.c index 38debffbd..b92d26b65 100644 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -10,8 +10,12 @@ * File: c_interface.c * * comments: c_interface primitives definition * * * -* Last rev: $Date: 2005-03-01 22:25:08 $,$Author: vsc $ * +* Last rev: $Date: 2005-03-02 18:35:44 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.61 2005/03/01 22:25:08 vsc +* fix pruning bug +* make DL_MALLOC less enthusiastic about walking through buckets. +* * Revision 1.60 2005/02/08 18:04:47 vsc * library_directory may not be deterministic (usually it isn't). * @@ -95,6 +99,9 @@ #include "Yap.h" #include "clause.h" #include "yapio.h" +#if HAVE_STDARG_H +#include +#endif #if _MSC_VER || defined(__MINGW32__) #include #endif @@ -165,7 +172,7 @@ X_API int STD_PROTO(YAP_StringToBuffer, (Term, char *, unsigned int)); X_API Term STD_PROTO(YAP_ReadBuffer, (char *,Term *)); X_API Term STD_PROTO(YAP_BufferToString, (char *)); X_API Term STD_PROTO(YAP_BufferToAtomList, (char *)); -X_API void STD_PROTO(YAP_Error,(char *)); +X_API void STD_PROTO(YAP_Error,(int, Term, char *, ...)); X_API Term STD_PROTO(YAP_RunGoal,(Term)); X_API int STD_PROTO(YAP_RestartGoal,(void)); X_API int STD_PROTO(YAP_GoalHasException,(Term *)); @@ -835,9 +842,28 @@ YAP_BufferToAtomList(char *s) X_API void -YAP_Error(char *buf) +YAP_Error(int myerrno, Term t, char *buf,...) { - Yap_Error(SYSTEM_ERROR,TermNil,buf); +#define YAP_BUF_SIZE 512 + va_list ap; + char tmpbuf[YAP_BUF_SIZE]; + + if (!myerrno) + myerrno = SYSTEM_ERROR; + if (t == 0L) + t = TermNil; + if (buf != NULL) { + va_start (ap, buf); +#if HAVE_VSNPRINTF + (void) vsnprintf(tmpbuf, YAP_BUF_SIZE, buf, ap); +#else + (void) vsprintf(tmpbuf, buf, ap); +#endif + va_end (ap); + } else { + tmpbuf[0] = '\0'; + } + Yap_Error(myerrno,t,tmpbuf); } static void myputc (int ch) @@ -1046,7 +1072,9 @@ YAP_Init(YAP_init_args *yap_init) if (yap_init->SavedState != NULL || yap_init->YapPrologBootFile == NULL) { if (Yap_SavedInfo (yap_init->SavedState, yap_init->YapLibDir, &Trail, &Stack, &Heap) != 1) { - return(YAP_BOOT_FROM_SAVED_ERROR); + yap_init->ErrorNo = Yap_Error_TYPE; + yap_init->ErrorCause = Yap_ErrorMessage; + return YAP_BOOT_FROM_SAVED_ERROR; } } if (yap_init->TrailSize == 0) { @@ -1095,6 +1123,11 @@ YAP_Init(YAP_init_args *yap_init) if (yap_init->SavedState != NULL || yap_init->YapPrologBootFile == NULL) { restore_result = Yap_Restore(yap_init->SavedState, yap_init->YapLibDir); + if (restore_result == FAIL_RESTORE) { + yap_init->ErrorNo = Yap_Error_TYPE; + yap_init->ErrorCause = Yap_ErrorMessage; + return YAP_BOOT_FROM_SAVED_ERROR; + } } else { restore_result = FAIL_RESTORE; } @@ -1134,21 +1167,25 @@ YAP_Init(YAP_init_args *yap_init) } if (yap_init->SavedState != NULL || yap_init->YapPrologBootFile == NULL) { - if (restore_result == FAIL_RESTORE) - return(YAP_BOOT_FROM_SAVED_ERROR); + if (restore_result == FAIL_RESTORE) { + yap_init->ErrorNo = Yap_Error_TYPE; + yap_init->ErrorCause = Yap_ErrorMessage; + return YAP_BOOT_FROM_SAVED_ERROR; + } if (restore_result == DO_ONLY_CODE) { - return(YAP_BOOT_FROM_SAVED_CODE); + return YAP_BOOT_FROM_SAVED_CODE; } else { - return(YAP_BOOT_FROM_SAVED_STACKS); + return YAP_BOOT_FROM_SAVED_STACKS; } } - return(YAP_BOOT_FROM_PROLOG); + return YAP_BOOT_FROM_PROLOG; } X_API Int YAP_FastInit(char saved_state[]) { YAP_init_args init_args; + Int out; init_args.SavedState = saved_state; init_args.HeapSize = 0; @@ -1166,8 +1203,13 @@ YAP_FastInit(char saved_state[]) init_args.PrologShouldHandleInterrupts = FALSE; init_args.Argc = 0; init_args.Argv = NULL; - - return(YAP_Init(&init_args)); + init_args.ErrorNo = 0; + init_args.ErrorCause = NULL; + out = YAP_Init(&init_args); + if (out == YAP_BOOT_FROM_SAVED_ERROR) { + Yap_Error(init_args.ErrorNo,TermNil,init_args.ErrorCause); + } + return out; } X_API void diff --git a/C/errors.c b/C/errors.c index 914d628b2..1a9e7d81b 100644 --- a/C/errors.c +++ b/C/errors.c @@ -372,7 +372,10 @@ Yap_Error(yap_error_number type, Term where, char *format,...) int psize = YAP_BUF_SIZE; #if DEBUG - /* fprintf(stderr,"***** Processing Error %d (%x,%x) %s***\n", type, ActiveSignals,Yap_PrologMode,format);*/ + if (Yap_heap_regs && !(Yap_PrologMode & BootMode)) + fprintf(stderr,"***** Processing Error %d (%x,%x) %s***\n", type, ActiveSignals,Yap_PrologMode,format); + else + fprintf(stderr,"***** Processing Error %d (%x) %s***\n", type,Yap_PrologMode,format); #endif if (type == INTERRUPT_ERROR) { fprintf(stderr,"%% YAP exiting: cannot handle signal %d\n", @@ -419,9 +422,9 @@ Yap_Error(yap_error_number type, Term where, char *format,...) tmpbuf[0] = '\0'; } if (Yap_PrologMode == UserCCallMode) { - fprintf(stderr,"%% OOOPS in USER C-CODE: %s.\n",tmpbuf); + fprintf(stderr,"%% YAP OOOPS in USER C-CODE: %s.\n",tmpbuf); } else { - fprintf(stderr,"%% OOOPS: %s.\n",tmpbuf); + fprintf(stderr,"%% YAP OOOPS: %s.\n",tmpbuf); } error_exit_yap (1); } @@ -461,7 +464,7 @@ Yap_Error(yap_error_number type, Term where, char *format,...) va_end (ap); if (Yap_PrologMode & BootMode) { /* crash in flames! */ - fprintf(stderr,"%% Fatal Error: %s exiting....\n",tmpbuf); + fprintf(stderr,"%% YAP Fatal Error: %s exiting....\n",tmpbuf); error_exit_yap (1); } #ifdef DEBUGX @@ -472,8 +475,12 @@ Yap_Error(yap_error_number type, Term where, char *format,...) { fprintf(stderr,"%% Internal YAP Error: %s exiting....\n",tmpbuf); serious = TRUE; - detect_bug_location(P, FIND_PRED_FROM_ANYWHERE, tmpbuf, YAP_BUF_SIZE); - fprintf(stderr,"%% Bug found while executing %s\n",tmpbuf); + if (Yap_PrologMode & BootMode) { + fprintf(stderr,"%% YAP crashed while booting %s\n",tmpbuf); + } else { + detect_bug_location(P, FIND_PRED_FROM_ANYWHERE, tmpbuf, YAP_BUF_SIZE); + fprintf(stderr,"%% Bug found while executing %s\n",tmpbuf); + } error_exit_yap (1); } case FATAL_ERROR: diff --git a/C/exec.c b/C/exec.c index 3ec986c22..c64885497 100644 --- a/C/exec.c +++ b/C/exec.c @@ -1450,11 +1450,14 @@ JumpToEnv(Term t) { #ifdef TABLING abolish_incomplete_subgoals(B); #endif /* TABLING */ - return(FALSE); + return FALSE; } Int Yap_JumpToEnv(Term t) { + if (Yap_PrologMode & BootMode) { + return FALSE; + } return JumpToEnv(t); } diff --git a/C/save.c b/C/save.c index 7c6554ea2..33c0665d2 100644 --- a/C/save.c +++ b/C/save.c @@ -81,7 +81,7 @@ static char end_msg[256] ="*** End of YAP saved state *****"; #endif -STATIC_PROTO(void myread, (int, char *, Int)); +STATIC_PROTO(int myread, (int, char *, Int)); STATIC_PROTO(void mywrite, (int, char *, Int)); STATIC_PROTO(int open_file, (char *, int)); STATIC_PROTO(void close_file, (void)); @@ -99,13 +99,13 @@ STATIC_PROTO(Int do_save, (int)); STATIC_PROTO(Int p_save, (void)); STATIC_PROTO(Int p_save_program, (void)); STATIC_PROTO(int check_header, (CELL *, CELL *, CELL *, CELL *)); -STATIC_PROTO(void get_heap_info, (void)); -STATIC_PROTO(void get_regs, (int)); -STATIC_PROTO(void get_insts, (OPCODE [])); -STATIC_PROTO(void get_hash, (void)); -STATIC_PROTO(void CopyCode, (void)); -STATIC_PROTO(void CopyStacks, (void)); -STATIC_PROTO(void get_coded, (int, OPCODE [])); +STATIC_PROTO(int get_heap_info, (void)); +STATIC_PROTO(int get_regs, (int)); +STATIC_PROTO(int get_insts, (OPCODE [])); +STATIC_PROTO(int get_hash, (void)); +STATIC_PROTO(int CopyCode, (void)); +STATIC_PROTO(int CopyStacks, (void)); +STATIC_PROTO(int get_coded, (int, OPCODE [])); STATIC_PROTO(void restore_codes, (void)); STATIC_PROTO(Term AdjustDBTerm, (Term, Term *)); STATIC_PROTO(void RestoreDB, (DBEntry *)); @@ -152,23 +152,45 @@ LightBug(s) #endif /* LIGHT */ +static int +do_system_error(yap_error_number etype, const char *msg) +{ +#if HAVE_SNPRINTF +#if HAVE_STRERROR + snprintf(Yap_ErrorSay,MAX_ERROR_MSG_SIZE,"%s (%s when reading %s)", msg, strerror(errno), Yap_FileNameBuf); +#else + snprintf(Yap_ErrorSay,MAX_ERROR_MSG_SIZE,"%s, (system error %d when reading %s)",msg,errno,Yap_FileNameBuf); +#endif +#else +#if HAVE_STRERROR + sprintf(Yap_ErrorSay,"%s, (%s when reading %s)",msg,strerror(errno),Yap_FileNameBuf); +#else + sprintf(Yap_ErrorSay,"%s, (system error %d when reading %s)",msg,errno,Yap_FileNameBuf); +#endif +#endif + Yap_ErrorMessage = Yap_ErrorSay; + Yap_Error_TYPE = etype; + return -1; +} + #if SHORT_INTS #ifdef M_WILLIAMS #include #endif -static void +static int myread(int fd, char *buff, Int len) { - while (len > 16000) { - int nchars = read(fd, buff, 16000); - if (nchars <= 0) - Yap_Error(FATAL_ERROR,TermNil,"bad saved state, system corrupted"); - len -= 16000; - buff += 16000; + while (len > 0) { + int nchars = read(fd, buff, len); + if (nchars < 0) { + return do_system_error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM, "bad read on saved state", ); + } + len -= nchars; + buff += nchars; } - read(fd, buff, (unsigned) len); + return len; } static void @@ -185,17 +207,18 @@ mywrite(int fd, char *buff, Int len) #else /* SHORT_INTS */ inline static -void myread(int fd, char *buffer, Int len) { +int myread(int fd, char *buffer, Int len) { int nread; while (len > 0) { nread = read(fd, buffer, (int)len); if (nread < 1) { - Yap_Error(FATAL_ERROR,TermNil,"bad saved state, system corrupted"); + return do_system_error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,"bad read on saved state"); } buffer += nread; len -= nread; } + return len; } inline static @@ -204,8 +227,9 @@ void mywrite(int fd, char *buff, Int len) { while (len > 0) { nwritten = (Int)write(fd, buff, (int)len); - if (nwritten == -1) { - Yap_Error(SYSTEM_ERROR,TermNil,"write error while saving"); + if (nwritten < 0) { + Yap_ErrorMessage = "bad write on saved state"; + Yap_Error(SYSTEM_ERROR,TermNil,Yap_ErrorMessage); } buff += nwritten; len -= nwritten; @@ -263,12 +287,12 @@ open_file(char *my_file, int flag) #endif /* M_WILLIAMS */ { splfild = 0; /* We do not have an open file */ - return(-1); + return -1; } #ifdef undf0 fprintf(errout, "Opened file %s\n", my_file); #endif - return(splfild); + return splfild; } static void @@ -311,12 +335,12 @@ get_header_cell(void) int count = 0, n; while (count < sizeof(CELL)) { if ((n = read(splfild, &l, sizeof(CELL)-count)) < 0) { - Yap_ErrorMessage = "corrupt saved state (too short)"; - return(0L); + do_system_error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,"failed to read saved state header"); + return 0L; } count += n; } - return(l); + return l; } /* gets a pointer to cell from a file */ @@ -524,7 +548,7 @@ do_save(int mode) { Term t1 = Deref(ARG1); if (!Yap_GetName(Yap_FileNameBuf, YAP_FILENAME_MAX, t1)) { Yap_Error(TYPE_ERROR_LIST,t1,"save/1"); - return(FALSE); + return FALSE; } Yap_CloseStreams(TRUE); if ((splfild = open_file(Yap_FileNameBuf, O_WRONLY | O_CREAT)) < 0) { @@ -576,7 +600,7 @@ static Int p_save_program(void) { which_save = 0; - return(do_save(DO_ONLY_CODE)); + return do_save(DO_ONLY_CODE); } /* Now, to restore the saved code */ @@ -593,8 +617,8 @@ check_header(CELL *info, CELL *ATrail, CELL *AStack, CELL *AHeap) /* skip the first line */ do { if (read(splfild, pp, 1) < 0) { - Yap_ErrorMessage = "corrupt saved state (failed to read first line)"; - return(FAIL_RESTORE); + do_system_error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,"failed to scan first line from saved state"); + return FAIL_RESTORE; } } while (pp[0] != 1); /* now check the version */ @@ -603,97 +627,126 @@ check_header(CELL *info, CELL *ATrail, CELL *AStack, CELL *AHeap) int count = 0, n, to_read = Unsigned(strlen(msg) + 1); while (count < to_read) { if ((n = read(splfild, pp, to_read-count)) < 0) { - Yap_ErrorMessage = "corrupt saved state (header too short)"; - return(FAIL_RESTORE); + do_system_error(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,"failed to scan version info from saved state"); + return FAIL_RESTORE; } count += n; } } if (pp[0] != 'Y' && pp[1] != 'A' && pp[0] != 'P') { - Yap_ErrorMessage = "corrupt saved state (should say YAP)"; - return(FAIL_RESTORE); + Yap_ErrorMessage = Yap_ErrorSay; + strncpy(Yap_ErrorMessage, "saved state ", MAX_ERROR_MSG_SIZE); + strncat(Yap_ErrorMessage, Yap_FileNameBuf, MAX_ERROR_MSG_SIZE); + strncat(Yap_ErrorMessage, " failed to match `YAP\'", MAX_ERROR_MSG_SIZE); + Yap_Error_TYPE = CONSISTENCY_ERROR; + return FAIL_RESTORE; } if (strcmp(pp, msg) != 0) { - Yap_ErrorMessage = "corrupt saved state (different version of YAP)"; - return(FAIL_RESTORE); + Yap_ErrorMessage = Yap_ErrorSay; + strncpy(Yap_ErrorMessage, "saved state ", MAX_ERROR_MSG_SIZE); + strncat(Yap_ErrorMessage, Yap_FileNameBuf, MAX_ERROR_MSG_SIZE); + strncat(Yap_ErrorMessage, " failed to match version ID", MAX_ERROR_MSG_SIZE); + Yap_Error_TYPE = CONSISTENCY_ERROR; + return FAIL_RESTORE; } /* check info on header */ /* ignore info on saved state */ *info = get_header_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; /* check the restore mode */ mode = get_header_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; if (mode != DO_EVERYTHING && mode != DO_ONLY_CODE) { - Yap_ErrorMessage = "corrupt saved state (bad type)"; - return(FAIL_RESTORE); + return FAIL_RESTORE; } /* ignore info on stacks size */ *AHeap = get_header_cell(); + if (Yap_ErrorMessage) { + return FAIL_RESTORE; + } *AStack = get_header_cell(); + if (Yap_ErrorMessage) { + return FAIL_RESTORE; + } *ATrail = get_header_cell(); - if (Yap_ErrorMessage) - return(FAIL_RESTORE); + if (Yap_ErrorMessage) { + return FAIL_RESTORE; + } /* now, check whether we got enough enough space to load the saved space */ hp_size = get_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; while (Yap_HeapBase != NULL && hp_size > Unsigned(HeapLim) - Unsigned(Yap_HeapBase)) { if(!Yap_growheap(FALSE, hp_size, NULL)) { - return(FAIL_RESTORE); + return FAIL_RESTORE; } } if (mode == DO_EVERYTHING) { lc_size = get_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; gb_size=get_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; if (Yap_HeapBase != NULL && lc_size+gb_size > Unsigned(Yap_LocalBase) - Unsigned(Yap_GlobalBase)) { - Yap_ErrorMessage = "not enough stack space for restore"; - return(FAIL_RESTORE); + if (Yap_ErrorMessage != NULL) + Yap_ErrorMessage = "could not allocate enough stack space"; + return FAIL_RESTORE; } if (Yap_HeapBase != NULL && (tr_size = get_cell()) > Unsigned(Yap_TrailTop) - Unsigned(Yap_TrailBase)) { - Yap_ErrorMessage = "not enough trail space for restore"; - return(FAIL_RESTORE); + if (Yap_ErrorMessage != NULL) + Yap_ErrorMessage = "could not allocate enough trail space"; + return FAIL_RESTORE; } } else { /* skip cell size */ get_header_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; get_header_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; get_header_cell(); if (Yap_ErrorMessage) - return(FAIL_RESTORE); + return FAIL_RESTORE; } return(mode); } /* Gets the state of the heap, and evaluates the related variables */ -static void +static int get_heap_info(void) { OldHeapBase = (ADDR) get_cellptr(); + if (Yap_ErrorMessage) + return -1; OldHeapTop = (ADDR) get_cellptr(); + if (Yap_ErrorMessage) + return -1; OldHeapUsed = (Int) get_cell(); + if (Yap_ErrorMessage) + return -1; FreeBlocks = (BlockHeader *) get_cellptr(); + if (Yap_ErrorMessage) + return -1; AuxSp = get_cellptr(); + if (Yap_ErrorMessage) + return -1; AuxTop = (ADDR)get_cellptr(); + if (Yap_ErrorMessage) + return -1; HDiff = Unsigned(Yap_HeapBase) - Unsigned(OldHeapBase); + return 1; } /* Gets the register array */ /* Saves the old bases for the work areas */ /* and evaluates the difference from the old areas to the new ones */ -static void +static int get_regs(int flag) { CELL *NewGlobalBase = (CELL *)Yap_GlobalBase; @@ -702,46 +755,95 @@ get_regs(int flag) /* Get regs */ compile_arrays = (int)get_cell(); + if (Yap_ErrorMessage) + return -1; if (flag == DO_EVERYTHING) { CP = (yamop *)get_cellptr(); + if (Yap_ErrorMessage) + return -1; ENV = get_cellptr(); + if (Yap_ErrorMessage) + return -1; ASP = get_cellptr(); + if (Yap_ErrorMessage) + return -1; /* N = get_cell(); */ H0 = get_cellptr(); + if (Yap_ErrorMessage) + return -1; LCL0 = get_cellptr(); + if (Yap_ErrorMessage) + return -1; H = get_cellptr(); + if (Yap_ErrorMessage) + return -1; HB = get_cellptr(); + if (Yap_ErrorMessage) + return -1; B = (choiceptr)get_cellptr(); + if (Yap_ErrorMessage) + return -1; TR = (tr_fr_ptr)get_cellptr(); + if (Yap_ErrorMessage) + return -1; YENV = get_cellptr(); + if (Yap_ErrorMessage) + return -1; S = get_cellptr(); + if (Yap_ErrorMessage) + return -1; P = (yamop *)get_cellptr(); + if (Yap_ErrorMessage) + return -1; CreepFlag = get_cell(); + if (Yap_ErrorMessage) + return -1; #ifdef COROUTINING DelayedVars = get_cell(); + if (Yap_ErrorMessage) + return -1; #endif } CurrentModule = get_cell(); + if (Yap_ErrorMessage) + return -1; if (flag == DO_EVERYTHING) { #ifdef COROUTINING WokenGoals = get_cell(); + if (Yap_ErrorMessage) + return -1; #endif #ifdef DEPTH_LIMIT DEPTH = get_cell(); + if (Yap_ErrorMessage) + return -1; #endif } /* Get the old bases */ OldXREGS = get_cellptr(); + if (Yap_ErrorMessage) + return -1; which_save = get_cell(); + if (Yap_ErrorMessage) + return -1; XDiff = (CELL)XREGS - (CELL)OldXREGS; - get_heap_info(); + if (Yap_ErrorMessage) + return -1; + if (get_heap_info() < 0) + return -1; if (flag == DO_EVERYTHING) { ARG1 = get_cell(); + if (Yap_ErrorMessage) + return -1; if (which_save == 2) { ARG2 = get_cell(); + if (Yap_ErrorMessage) + return -1; } /* get old trail base */ OldTrailBase = (ADDR)get_cellptr(); + if (Yap_ErrorMessage) + return -1; /* Save the old register where we can easily access them */ OldASP = ASP; OldLCL0 = LCL0; @@ -754,54 +856,71 @@ get_regs(int flag) Yap_GlobalBase = (ADDR)NewGlobalBase; LCL0 = NewLCL0; } + return 1; } /* Get the old opcodes and place them in a hash table */ -static void +static int get_insts(OPCODE old_ops[]) { - myread(splfild, (char *)old_ops, sizeof(OPCODE)*(_std_top+1)); + return myread(splfild, (char *)old_ops, sizeof(OPCODE)*(_std_top+1)); } /* Get the old atoms hash table */ -static void +static int get_hash(void) { - myread(splfild, Yap_chtype , NUMBER_OF_CHARS); + return myread(splfild, Yap_chtype , NUMBER_OF_CHARS); } /* Copy all of the old code to the new Heap */ -static void +static int CopyCode(void) { #if defined(YAPOR) || defined(TABLING) /* skip the local and global data structures */ CELL j = get_cell(); + if (Yap_ErrorMessage) + return -1; if (j != Unsigned(&GLOBAL) - Unsigned(Yap_HeapBase)) { - Yap_Error(FATAL_ERROR,TermNil,"bad saved state (code space size does not match)"); + Yap_ErrorMessage = "code space size does not match saved state"; + return -1; } - myread(splfild, (char *) Yap_HeapBase, j); + if (myread(splfild, (char *) Yap_HeapBase, j) < 0) + return -1; #ifdef USE_HEAP j = get_cell(); - myread(splfild, (char *) &HashChain, j); + if (Yap_ErrorMessage) + return -1; + if (myread(splfild, (char *) &HashChain, j) < 0) + return -1; #else j = get_cell(); + if (Yap_ErrorMessage) + return -1; if (j != Unsigned(BaseAllocArea) - Unsigned(&HashChain)) { - Yap_Error(FATAL_ERROR,TermNil,"bad saved state (Base to Hash does not match)"); + Yap_ErrorMessage = "Base to Hash does not match saved state"; + return -1; } - myread(splfild, (char *) &HashChain, j); + if (myread(splfild, (char *) &HashChain, j) < 0) + return -1; j = get_cell(); - myread(splfild, (char *) TopAllocBlockArea, j); + if (Yap_ErrorMessage) + return -1; + if (myread(splfild, (char *) TopAllocBlockArea, j) < 0) + return -1; #endif #else - myread(splfild, (char *) Yap_HeapBase, - (Unsigned(OldHeapTop) - Unsigned(OldHeapBase))); + if (myread(splfild, (char *) Yap_HeapBase, + (Unsigned(OldHeapTop) - Unsigned(OldHeapBase))) < 0) + return -1; #endif /* YAPOR || TABLING */ + return 1; } /* Copy the local and global stack and also the trail to their new home */ /* In REGS we still have nonadjusted values !! */ -static void +static int CopyStacks(void) { Int j; @@ -809,16 +928,20 @@ CopyStacks(void) j = Unsigned(OldLCL0) - Unsigned(ASP); NewASP = (char *) (Unsigned(ASP) + (Unsigned(LCL0) - Unsigned(OldLCL0))); - myread(splfild, (char *) NewASP, j); + if (myread(splfild, (char *) NewASP, j) < 0) + return -1; j = Unsigned(H) - Unsigned(OldGlobalBase); - myread(splfild, (char *) Yap_GlobalBase, j); + if (myread(splfild, (char *) Yap_GlobalBase, j) < 0) + return -1; j = Unsigned(TR) - Unsigned(OldTrailBase); - myread(splfild, Yap_TrailBase, j); + if (myread(splfild, Yap_TrailBase, j)) + return -1; + return 1; } /* Copy the local and global stack and also the trail to their new home */ /* In REGS we still have nonadjusted values !! */ -static void +static int CopyTrailEntries(void) { CELL entry, *Entries; @@ -826,31 +949,44 @@ CopyTrailEntries(void) Entries = (CELL *)Yap_TrailBase; do { *Entries++ = entry = get_cell(); + if (Yap_ErrorMessage) + return -1; } while ((CODEADDR)entry != NULL); + return 1; } /* get things which are saved in the file */ -static void +static int get_coded(int flag, OPCODE old_ops[]) { char my_end_msg[256]; - get_regs(flag); - get_insts(old_ops); - get_hash(); - CopyCode(); + if (get_regs(flag) < 0) + return -1; + if (get_insts(old_ops) < 0) + return -1; + if (get_hash() < 0) + return -1; + if (CopyCode() < 0) + return -1; switch (flag) { case DO_EVERYTHING: - CopyStacks(); + if (CopyStacks() < 0) + return -1; break; case DO_ONLY_CODE: - CopyTrailEntries(); + if (CopyTrailEntries() < 0) + return -1; break; } /* Check CRC */ - myread(splfild, my_end_msg, 256); - if (strcmp(end_msg,my_end_msg) != 0) - Yap_Error(FATAL_ERROR,TermNil,"corrupt saved state (bad trailing CRC)"); + if (myread(splfild, my_end_msg, 256) < 0) + return -1; + if (strcmp(end_msg,my_end_msg) != 0) { + Yap_ErrorMessage = "bad trailing CRC in saved state"; + return -1; + } + return 1; } /* restore some heap registers */ @@ -1278,10 +1414,22 @@ OpenRestore(char *inpf, char *YapLibDir, CELL *Astate, CELL *ATrail, CELL *AStac Yap_ErrorMessage = NULL; if (inpf == NULL) inpf = StartUpFile; +#if __simplescalar__ + /* does not implement getcwd */ + strncpy(Yap_FileNameBuf,yap_pwd,YAP_FILENAME_MAX); +#elif HAVE_GETCWD + if (getcwd (Yap_FileNameBuf, YAP_FILENAME_MAX) == NULL) + Yap_FileNameBuf[0] = '\0'; +#else + if (getwd (Yap_FileNameBuf) == NULL) + Yap_FileNameBuf[0] = '\0'; +#endif + strncat(Yap_FileNameBuf, "/", YAP_FILENAME_MAX); + strncat(Yap_FileNameBuf, inpf, YAP_FILENAME_MAX); if (inpf != NULL && (splfild = open_file(inpf, O_RDONLY)) > 0) { if ((mode = commit_to_saved_state(inpf,Astate,ATrail,AStack,AHeap)) != FAIL_RESTORE) { Yap_ErrorMessage = NULL; - return(mode); + return mode; } } if (!Yap_dir_separator(inpf[0]) && !Yap_volume_header(inpf)) { @@ -1294,7 +1442,7 @@ OpenRestore(char *inpf, char *YapLibDir, CELL *Astate, CELL *ATrail, CELL *AStac if ((splfild = open_file(Yap_FileNameBuf, O_RDONLY)) > 0) { if ((mode = commit_to_saved_state(Yap_FileNameBuf,Astate,ATrail,AStack,AHeap)) != FAIL_RESTORE) { Yap_ErrorMessage = NULL; - return(mode); + return mode; } } } @@ -1306,7 +1454,7 @@ OpenRestore(char *inpf, char *YapLibDir, CELL *Astate, CELL *ATrail, CELL *AStac if ((splfild = open_file(Yap_FileNameBuf, O_RDONLY)) > 0) { if ((mode = commit_to_saved_state(Yap_FileNameBuf,Astate,ATrail,AStack,AHeap)) != FAIL_RESTORE) { Yap_ErrorMessage = NULL; - return(mode); + return mode; } } } @@ -1324,12 +1472,10 @@ OpenRestore(char *inpf, char *YapLibDir, CELL *Astate, CELL *ATrail, CELL *AStac } /* could not open file */ if (Yap_ErrorMessage == NULL) { - Yap_Error(SYSTEM_ERROR,TermNil,"could not open %s,",inpf); - } else { - Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage); + strncpy(Yap_FileNameBuf, inpf, YAP_FILENAME_MAX); + do_system_error(PERMISSION_ERROR_OPEN_SOURCE_SINK,"could not open saved state"); } - Yap_ErrorMessage = NULL; - return(FAIL_RESTORE); + return FAIL_RESTORE; } static void @@ -1403,11 +1549,10 @@ Yap_SavedInfo(char *FileName, char *YapLibDir, CELL *ATrail, CELL *AStack, CELL int mode; mode = OpenRestore(FileName, YapLibDir, &MyState, &MyTrail, &MyStack, &MyHeap); - close_file(); if (mode == FAIL_RESTORE) { - Yap_ErrorMessage = NULL; - return(0); + return -1; } + close_file(); if (! *AHeap) *AHeap = MyHeap / 1024; if (mode != DO_ONLY_CODE && *AStack) @@ -1481,7 +1626,8 @@ Restore(char *s, char *lib_dir) return(FALSE); Yap_ShutdownLoadForeign(); in_limbo = TRUE; - get_coded(restore_mode, old_ops); + if (get_coded(restore_mode, old_ops) < 0) + return FAIL_RESTORE; restore_regs(restore_mode); in_limbo = FALSE; /*#endif*/ @@ -1518,7 +1664,7 @@ Restore(char *s, char *lib_dir) if (which_save == 2) { Yap_unify(ARG2, MkIntTerm(0)); } - return(restore_mode); + return restore_mode; } int diff --git a/C/stdpreds.c b/C/stdpreds.c index 37d56242f..70deaf5a6 100644 --- a/C/stdpreds.c +++ b/C/stdpreds.c @@ -11,8 +11,12 @@ * File: stdpreds.c * * comments: General-purpose C implemented system predicates * * * -* Last rev: $Date: 2005-03-01 22:25:09 $,$Author: vsc $ * +* Last rev: $Date: 2005-03-02 18:35:46 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.83 2005/03/01 22:25:09 vsc +* fix pruning bug +* make DL_MALLOC less enthusiastic about walking through buckets. +* * Revision 1.82 2005/02/21 16:50:04 vsc * amd64 fixes * library fixes @@ -1063,7 +1067,14 @@ p_name(void) } if (IsAtomTerm(t) && AtomOfTerm(t) == AtomNil) { if ((NewT = get_num(String)) == TermNil) { - NewT = MkAtomTerm(Yap_LookupAtom(String)); + Atom at; + while ((at = Yap_LookupAtom(String)) == NIL) { + if (!Yap_growheap(FALSE, 0, NULL)) { + Yap_Error(OUT_OF_HEAP_ERROR, TermNil, Yap_ErrorMessage); + return(FALSE); + } + } + NewT = MkAtomTerm(at); } return Yap_unify_constant(ARG1, NewT); } else { diff --git a/console/yap.c b/console/yap.c index f0ba6c647..604b514f9 100644 --- a/console/yap.c +++ b/console/yap.c @@ -287,14 +287,14 @@ parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap) host = *++argv; argc--; if (host == NULL || host[0] == '-') - YAP_Error("sockets must receive host to connect to"); + YAP_Error(0,0L,"sockets must receive host to connect to"); p1 = *++argv; argc--; if (p1 == NULL || p1[0] == '-') - YAP_Error("sockets must receive port to connect to"); + YAP_Error(0,0L,"sockets must receive port to connect to"); port = strtol(p1, &ptr, 10); if (ptr == NULL || ptr[0] != '\0') - YAP_Error("port argument to socket must be a number"); + YAP_Error(0,0L,"port argument to socket must be a number"); YAP_InitSocks(host,port); } break; @@ -446,6 +446,8 @@ init_standard_system(int argc, char *argv[], YAP_init_args *iap) iap->PrologShouldHandleInterrupts = TRUE; iap->Argc = argc; iap->Argv = argv; + iap->ErrorNo = 0; + iap->ErrorCause = NULL; BootMode = parse_yap_arguments(argc,argv,iap); @@ -466,10 +468,14 @@ init_standard_system(int argc, char *argv[], YAP_init_args *iap) /* init memory */ if (BootMode == YAP_BOOT_FROM_PROLOG || BootMode == YAP_FULL_BOOT_FROM_PROLOG) { - YAP_Init(iap); + BootMode = YAP_Init(iap); } else { BootMode = YAP_Init(iap); } + if (iap->ErrorNo) { + /* boot failed */ + YAP_Error(iap->ErrorNo,0L,iap->ErrorCause); + } return(BootMode); } @@ -552,7 +558,7 @@ main (int argc, char **argv) YAP_init_args init_args; BootMode = init_standard_system(argc, argv, &init_args); - if (BootMode == YAP_BOOT_FROM_SAVED_ERROR) { + if (BootMode == YAP_BOOT_ERROR) { fprintf(stderr,"[ FATAL ERROR: could not find saved state ]\n"); exit(1); } diff --git a/docs/yap.tex b/docs/yap.tex index b47e7a320..79aebcdb9 100644 --- a/docs/yap.tex +++ b/docs/yap.tex @@ -14029,7 +14029,7 @@ program contains two facts for the procedure @t{b}: int main(int argc, char *argv[]) @{ - if (YAP_FastInit("saved_state") == YAP_BOOT_FROM_SAVED_ERROR) + if (YAP_FastInit("saved_state") == YAP_BOOT_ERROR) exit(1); if (YAP_RunGoal(YAP_MkAtomTerm(YAP_LookupAtom("do")))) @{ printf("Success\n"); @@ -14091,14 +14091,19 @@ Initialize a copy of YAP from @var{SavedState}. The copy is monolithic and currently must be loaded at the same address where it was saved. @code{YAP_FastInit} is a simpler version of @code{YAP_Init}. -@item YAP_Init(@code{char *} @var{SavedState}, @code{int} -@var{HeapSize}, @code{int} @var{StackSize}, @code{int} -@var{TrailSize}, @code{int} @var{NumberofWorkers}, @code{int} +@item YAP_Init(@var{InitInfo}) +@findex YAP_Init/1 +Initialize YAP. The arguments are in a @code{C} +structure of type @code{YAP_init_args}. + +The fields of @var{InitInfo} are @code{char *} @var{SavedState}, +@code{int} @var{HeapSize}, @code{int} @var{StackSize}, @code{int} +@var{TrailSize}, @code{int} @var{NumberofWorkers}, @code{int} @var{SchedulerLoop}, @code{int} @var{DelayedReleaseLoad}, @code{int} -@var{argc}, @code{char **} @var{argv}) -@findex YAP_Init/9 -Initialize YAP. In the future the arguments as a single @code{C} -structure. +@var{argc}, @code{char **} @var{argv}, @code{int} @var{ErrorNo}, and +@code{char *} @var{ErrorCause}. The function returns an integer, which +indicates the current status. If the result is @code{YAP_BOOT_ERROR} +booting failed. If @var{SavedState} is not NULL, try to open and restore the file @var{SavedState}. Initially YAP will search in the current directory. If @@ -14120,6 +14125,11 @@ The argument count @var{argc} and string of arguments @var{argv} arguments are to be passed to user programs as the arguments used to call YAP. +If booting failed you may consult @code{ErrorNo} and @code{ErrorCause} +for the cause of the error, or call +@code{YAP_Error(ErrorNo,0L,ErrorCause)} to do default processing. + + @item @code{void} YAP_PutValue(@code{Atom} @var{at}, @code{Term} @var{value}) @findex YAP_PutValue/2 Associate the term @var{value} with the atom @var{at}. The term diff --git a/include/YapInterface.h b/include/YapInterface.h index c218d6410..edcf237c0 100644 --- a/include/YapInterface.h +++ b/include/YapInterface.h @@ -24,6 +24,10 @@ #include "yap_structs.h" +#if HAVE_STDARG_H +#include +#endif + #ifndef _yap_c_interface_h #define _yap_c_interface_h 1 @@ -220,8 +224,8 @@ extern X_API YAP_Bool PROTO(YAP_GoalHasException,(YAP_Term *)); /* int YAP_Reset(void) */ extern X_API void PROTO(YAP_Reset,(void)); -/* void YAP_Error(char *) */ -extern X_API void PROTO(YAP_Error,(char *)); +/* void YAP_Error(int, YAP_Term, char *,...) */ +extern X_API void PROTO(YAP_Error,(int, YAP_Term, char *, ...)); /* YAP_Term YAP_Read(int (*)(void)) */ extern X_API YAP_Term PROTO(YAP_Read,(int (*)(void))); diff --git a/include/yap_structs.h b/include/yap_structs.h index 2e1573406..9cc025e7f 100644 --- a/include/yap_structs.h +++ b/include/yap_structs.h @@ -53,7 +53,7 @@ typedef struct AtomEntry *YAP_Atom; #define YAP_BOOT_FROM_SAVED_CODE 1 #define YAP_BOOT_FROM_SAVED_STACKS 2 #define YAP_FULL_BOOT_FROM_PROLOG 4 -#define YAP_BOOT_FROM_SAVED_ERROR -1 +#define YAP_BOOT_ERROR -1 #define YAP_WRITE_QUOTED 0 #define YAP_WRITE_HANDLE_VARS 1 @@ -98,6 +98,10 @@ typedef struct { int Argc; /* array of arguments as seen by Prolog */ char **Argv; + /* errornumber */ + int ErrorNo; + /* errorstring */ + char *ErrorCause; } YAP_init_args; diff --git a/m4/Yap.h.m4 b/m4/Yap.h.m4 index a26f4e822..4a4dede0a 100644 --- a/m4/Yap.h.m4 +++ b/m4/Yap.h.m4 @@ -10,7 +10,7 @@ * File: Yap.h.m4 * * mods: * * comments: main header file for YAP * -* version: $Id: Yap.h.m4,v 1.79 2005-02-08 18:38:02 vsc Exp $ * +* version: $Id: Yap.h.m4,v 1.80 2005-03-02 18:35:49 vsc Exp $ * *************************************************************************/ #include "config.h" @@ -706,11 +706,11 @@ and RefOfTerm(t) : Term -> DBRef = ... extern ADDR Yap_HeapBase; -#define MAX_ERROR_MSG_SIZE 256 - /* This is ok for Linux, should be ok for everyone */ #define YAP_FILENAME_MAX 1024 +#define MAX_ERROR_MSG_SIZE YAP_FILENAME_MAX + #ifdef THREADS typedef struct thread_globs { ADDR local_base;