/* Removes the top of the handler stack */
void exception_pop_handler(void) {
  /* Are there any handlers? */
  exception_handler handler = exception_last_handler();
  if(handler) {
    /* If so, set the current handler to the previous one and free the old one */
    exception_set_handler(handler->previous);
  } else {
    /* Should never be here... */
    (*exception_panic)(EXCEPTION_UNRECHEABLE);
  };
};
Пример #2
0
DECLARE_TEST(exception, exception_thread) {
    thread_t thread;

    if (system_debugger_attached() || (system_platform() == PLATFORM_PNACL))
        return 0; //Don't do exception tests with debugger attached

    _exception_handler_called = false;
    exception_set_handler(test_local_exception_handler, STRING_CONST("thread_raise_abort"));

    log_enable_stdout(false);
    thread_initialize(&thread, thread_raise_abort, 0, STRING_CONST("raise_abort"), THREAD_PRIORITY_NORMAL, 0);
    thread_start(&thread);
    while (!thread_is_started(&thread))
        thread_sleep(100);
    thread_finalize(&thread);
    log_enable_stdout(true);

    EXPECT_TRUE(_exception_handler_called);

    return 0;
}
/* Creates a new handler, or gives the returned one */
exception_handler exception_add_handler(register exception_state status, register bool *flag, register const char *file, register int line, register const char *function) {
  /* Do we know the function that made the handler? */
  int function_size = function ? strlen(function) : 0;
  /* We make here a new handler */
  exception_handler handler = malloc(sizeof(struct exception_handler) + function_size + 1);
  if(handler) {
    handler->flag = flag;
    handler->start = exception_last_handler() ? exception_get_handler(EXCEPTION_LIVING)->start : flag;
    handler->status = status;
    handler->stack_size = (unsigned long)handler->start - (unsigned long)&function_size;
    handler->stack = malloc(handler->stack_size);
    handler->file = file;
    handler->line = line;
    if(function) {
      memcpy(handler->function, function, function_size);
    } else {
      *handler->function = (char)0;
    };
    if(handler->stack) {
      memcpy(handler->stack, &function_size, handler->stack_size);
      /* We push it to the stack */
      exception_set_handler(handler);
      /* And start it's execution... Warning: it is to here that it will return later on */
      exception_handler young = (exception_handler)setjmp(handler->nest);
      if(young) {
        /* If we've returned, let's restaure the old stack values */
        memcpy(young->start - young->stack_size, young->stack, young->stack_size);
        /* We return then the returned value, as if it was added now (which it "was") */
        return young;
      };
      /* We return the returned handler (may be at any position on the stack now) */
      return handler;
    };
  };
  /* Allocation have failed! */
  (*exception_panic)(EXCEPTION_UNALLOCATED);
  return NULL;
};