Beispiel #1
0
int
outOfStack(void *stack, stack_overflow_action how)
{ GET_LD
  Stack s = stack;
  const char *msg = "unhandled stack overflow";

  if ( LD->outofstack )
  { Sdprintf("[Thread %d]: failed to recover from %s-overflow\n",
	     PL_thread_self(), s->name);
    print_backtrace_named(msg);
    save_backtrace("crash");
    print_backtrace_named("crash");
    fatalError("Sorry, cannot continue");

    return FALSE;				/* NOTREACHED */
  }

  save_backtrace(msg);

  LD->trim_stack_requested = TRUE;
  LD->exception.processing = TRUE;
  LD->outofstack = stack;

  switch(how)
  { case STACK_OVERFLOW_THROW:
    case STACK_OVERFLOW_RAISE:
    { fid_t fid;

      blockGC(0 PASS_LD);

      if ( (fid=PL_open_foreign_frame()) )
      { PL_clearsig(SIG_GC);
	s->gced_size = 0;			/* after handling, all is new */
	if ( !PL_unify_term(LD->exception.tmp,
			    PL_FUNCTOR, FUNCTOR_error2,
			      PL_FUNCTOR, FUNCTOR_resource_error1,
			        PL_ATOM, ATOM_stack,
			      PL_CHARS, s->name) )
	  fatalError("Out of stack inside out-of-stack handler");

	if ( how == STACK_OVERFLOW_THROW )
	{ PL_close_foreign_frame(fid);
	  unblockGC(0 PASS_LD);
	  PL_throw(LD->exception.tmp);
	  warning("Out of %s stack while not in Prolog!?", s->name);
	  assert(0);
	} else
	{ PL_raise_exception(LD->exception.tmp);
	}

	PL_close_foreign_frame(fid);
      }

      unblockGC(0 PASS_LD);
      fail;
    }
  }
  assert(0);
  fail;
}
Beispiel #2
0
int
outOfStack(void *stack, stack_overflow_action how)
{ GET_LD
  Stack s = stack;
  const char *msg = "out-of-stack";

  if ( LD->outofstack )
  { Sdprintf("[Thread %d]: failed to recover from %s-overflow\n",
	     PL_thread_self(), s->name);
    print_backtrace_named(msg);
    save_backtrace("crash");
    print_backtrace_named("crash");
    fatalError("Sorry, cannot continue");

    return FALSE;				/* NOTREACHED */
  }

  save_backtrace(msg);

  if ( s->spare != s->def_spare )
  { Sdprintf("[Thread %d]: %s-overflow: spare=%ld\n"
	     "Last resource exception:\n",
	     PL_thread_self(), s->name, (long)s->spare);
    print_backtrace_named("exception");
  }

  LD->trim_stack_requested = TRUE;
  LD->exception.processing = TRUE;
  LD->outofstack = stack;

  switch(how)
  { case STACK_OVERFLOW_THROW:
    case STACK_OVERFLOW_RAISE:
    { if ( gTop+5 < gMax )
      { Word p = gTop;

	p[0] = FUNCTOR_error2;			/* see (*) above */
	p[1] = consPtr(&p[3], TAG_COMPOUND|STG_GLOBAL);
	p[2] = PL_new_atom(s->name);
	p[3] = FUNCTOR_resource_error1;
	p[4] = ATOM_stack;
	gTop += 5;
	PL_unregister_atom(p[2]);

	*valTermRef(LD->exception.bin) = consPtr(p, TAG_COMPOUND|STG_GLOBAL);
	freezeGlobal(PASS_LD1);
      } else
      { Sdprintf("Out of %s-stack.  No room for exception term.  Aborting.\n", s->name);
	*valTermRef(LD->exception.bin) = ATOM_aborted;
      }
      exception_term = exception_bin;

      if ( how == STACK_OVERFLOW_THROW &&
	   LD->exception.throw_environment )
      {						/* see PL_throw() */
	longjmp(LD->exception.throw_environment->exception_jmp_env, 1);
      }

      return FALSE;
    }
    default:
      assert(0);
      fail;
  }
}