Ejemplo n.º 1
0
static void
print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg)
{
    const char *einfo = "";
    long elen = 0;
    VALUE mesg;

    if (emesg != Qundef) {
	if (NIL_P(errat) || RARRAY_LEN(errat) == 0 ||
	    NIL_P(mesg = RARRAY_AREF(errat, 0))) {
	    error_pos();
	}
	else {
	    warn_print_str(mesg);
	    warn_print(": ");
	}

	if (!NIL_P(emesg)) {
	    einfo = RSTRING_PTR(emesg);
	    elen = RSTRING_LEN(emesg);
	}
    }

    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print("unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print_str(epath);
	    warn_print("\n");
	}
	else {
	    const char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print_str(tail ? rb_str_subseq(emesg, 0, len) : emesg);
	    if (epath) {
		warn_print(" (");
		warn_print_str(epath);
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print_str(rb_str_subseq(emesg, tail - einfo, elen - len - 1));
	    }
	    if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1);
	}
    }
}
Ejemplo n.º 2
0
void
rb_threadptr_error_print(rb_thread_t *th, VALUE errinfo)
{
    volatile VALUE errat = Qundef;
    int raised_flag = th->raised_flag;
    volatile VALUE eclass = Qundef, e = Qundef;
    const char *volatile einfo;
    volatile long elen;
    VALUE mesg;

    if (NIL_P(errinfo))
	return;
    rb_thread_raised_clear(th);

    TH_PUSH_TAG(th);
    if (TH_EXEC_TAG() == 0) {
	errat = rb_get_backtrace(errinfo);
    }
    else if (errat == Qundef) {
	errat = Qnil;
    }
    else if (eclass == Qundef || e != Qundef) {
	goto error;
    }
    else {
	goto no_message;
    }
    if (NIL_P(errat) || RARRAY_LEN(errat) == 0 ||
	NIL_P(mesg = RARRAY_AREF(errat, 0))) {
	error_pos();
    }
    else {
	warn_print_str(mesg);
	warn_print(": ");
    }

    eclass = CLASS_OF(errinfo);
    if (eclass != Qundef &&
	(e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0)) != Qundef &&
	(RB_TYPE_P(e, T_STRING) || !NIL_P(e = rb_check_string_type(e)))) {
	einfo = RSTRING_PTR(e);
	elen = RSTRING_LEN(e);
    }
    else {
      no_message:
	einfo = "";
	elen = 0;
    }
    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print("unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print_str(epath);
	    warn_print("\n");
	}
	else {
	    const char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print_str(tail ? rb_str_subseq(e, 0, len) : e);
	    if (epath) {
		warn_print(" (");
		warn_print_str(epath);
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print_str(rb_str_subseq(e, tail - einfo, elen - len - 1));
	    }
	    if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1);
	}
    }

    if (!NIL_P(errat)) {
	long i;
	long len = RARRAY_LEN(errat);
        int skip = eclass == rb_eSysStackError;

#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
#define TRACE_HEAD 8
#define TRACE_TAIL 5

	for (i = 1; i < len; i++) {
	    VALUE line = RARRAY_AREF(errat, i);
	    if (RB_TYPE_P(line, T_STRING)) {
		warn_print_str(rb_sprintf("\tfrom %"PRIsVALUE"\n", line));
	    }
	    if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
		warn_print_str(rb_sprintf("\t ... %ld levels...\n",
					  len - TRACE_HEAD - TRACE_TAIL));
		i = len - TRACE_TAIL;
	    }
	}
    }
  error:
    TH_POP_TAG();
    th->errinfo = errinfo;
    rb_thread_raised_set(th, raised_flag);
}
Ejemplo n.º 3
0
static int
error_handle(int ex)
{
    int status = EXIT_FAILURE;
    rb_thread_t *th = GET_THREAD();

    if (rb_threadptr_set_raised(th))
	return EXIT_FAILURE;
    switch (ex & TAG_MASK) {
      case 0:
	status = EXIT_SUCCESS;
	break;

      case TAG_RETURN:
	error_pos();
	warn_print("unexpected return\n");
	break;
      case TAG_NEXT:
	error_pos();
	warn_print("unexpected next\n");
	break;
      case TAG_BREAK:
	error_pos();
	warn_print("unexpected break\n");
	break;
      case TAG_REDO:
	error_pos();
	warn_print("unexpected redo\n");
	break;
      case TAG_RETRY:
	error_pos();
	warn_print("retry outside of rescue clause\n");
	break;
      case TAG_THROW:
	/* TODO: fix me */
	error_pos();
	warn_print("unexpected throw\n");
	break;
      case TAG_RAISE: {
	VALUE errinfo = th->errinfo;
	if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
	    status = sysexit_status(errinfo);
	}
	else if (rb_obj_is_instance_of(errinfo, rb_eSignal) &&
		 rb_ivar_get(errinfo, id_signo) != INT2FIX(SIGSEGV)) {
	    /* no message when exiting by signal */
	}
	else {
	    error_print(th);
	}
	break;
      }
      case TAG_FATAL:
	error_print(th);
	break;
      default:
	unknown_longjmp_status(ex);
	break;
    }
    rb_threadptr_reset_raised(th);
    return status;
}
Ejemplo n.º 4
0
static void error_print(FILE *out, int state, int cgi, int mode, VALUE code)
{
    char buff[BUFSIZ];

#if RUBY_VERSION_CODE < 180
    rb_defout = rb_stdout;
#endif
    if (cgi) {
	char *imgdir;
	if ((imgdir = getenv("SCRIPT_NAME")) == NULL)
	    imgdir = "UNKNOWN_IMG_DIR";
        if (mode == MODE_NPHCGI)
            print_http_headers();
        fprintf(out, "Content-Type: text/html\r\n");
        fprintf(out, "Content-Style-Type: text/css\r\n");
        fprintf(out, "\r\n");
	fprintf(out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n");
	fprintf(out, "<html>\n");
	fprintf(out, "<head>\n");
	fprintf(out, "<title>eRuby</title>\n");
	fprintf(out, "<style type=\"text/css\">\n");
	fprintf(out, "<!--\n");
	fprintf(out, "body { background-color: #ffffff }\n");
	fprintf(out, "table { width: 100%%; padding: 5pt; border-style: none }\n");
	fprintf(out, "th { color: #6666ff; background-color: #b0d0d0; text-align: left }\n");
	fprintf(out, "td { color: #336666; background-color: #d0ffff }\n");
	fprintf(out, "strong { color: #ff0000; font-weight: bold }\n");
	fprintf(out, "div.backtrace { text-indent: 15%% }\n");
	fprintf(out, "#version { color: #ff9900 }\n");
	fprintf(out, "-->\n");
	fprintf(out, "</style>\n");
	fprintf(out, "</head>\n");
	fprintf(out, "<body>\n");
        fprintf(out, "<table summary=\"eRuby error information\">\n");
        fprintf(out, "<caption>\n");
	fprintf(out, "<img src=\"%s/logo.png\" alt=\"eRuby\">\n", imgdir);
        fprintf(out, "<span id=version>version: %s</span>\n", ERUBY_VERSION);
        fprintf(out, "</caption>\n");
        fprintf(out, "<tr><th id=\"error\">\n");
        fprintf(out, "ERROR\n");
        fprintf(out, "</th></tr>\n");
        fprintf(out, "<tr><td headers=\"error\">\n");
    }

    switch (state) {
    case TAG_RETURN:
	error_pos(out, cgi);
	fprintf(out, ": unexpected return\n");
	break;
    case TAG_NEXT:
	error_pos(out, cgi);
	fprintf(out, ": unexpected next\n");
	break;
    case TAG_BREAK:
	error_pos(out, cgi);
	fprintf(out, ": unexpected break\n");
	break;
    case TAG_REDO:
	error_pos(out, cgi);
	fprintf(out, ": unexpected redo\n");
	break;
    case TAG_RETRY:
	error_pos(out, cgi);
	fprintf(out, ": retry outside of rescue clause\n");
	break;
    case TAG_RAISE:
    case TAG_FATAL:
	exception_print(out, cgi);
	break;
    default:
	error_pos(out, cgi);
	snprintf(buff, BUFSIZ, ": unknown longjmp status %d", state);
	fputs(buff, out);
	break;
    }
    if (cgi) {
        fprintf(out, "</td></tr>\n");
    }

    if (!NIL_P(code))
	print_generated_code(out, code, cgi);

    if (cgi) {
        fprintf(out, "</table>\n");
	fprintf(out, "</body>\n");
	fprintf(out, "</html>\n");
    }
}
Ejemplo n.º 5
0
static void exception_print(FILE *out, int cgi)
{
    VALUE errat;
    VALUE eclass;
    VALUE einfo;

    if (NIL_P(ruby_errinfo)) return;

    errat = rb_funcall(ruby_errinfo, rb_intern("backtrace"), 0);
    if (!NIL_P(errat)) {
	VALUE mesg = RARRAY_PTR(errat)[0];

	if (NIL_P(mesg)) {
	    error_pos(out, cgi);
	}
	else {
	    if (cgi)
		write_escaping_html(out, RSTRING_PTR(mesg), RSTRING_LEN(mesg));
	    else
		fwrite(RSTRING_PTR(mesg), 1, RSTRING_LEN(mesg), out);
	}
    }

    eclass = CLASS_OF(ruby_errinfo);
    einfo = rb_obj_as_string(ruby_errinfo);
    if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) {
	fprintf(out, ": unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_path(eclass);
	if (RSTRING_LEN(einfo) == 0) {
	    fprintf(out, ": ");
	    if (cgi)
		write_escaping_html(out, RSTRING_PTR(epath), RSTRING_LEN(epath));
	    else
		fwrite(RSTRING_PTR(epath), 1, RSTRING_LEN(epath), out);
	    if (cgi)
		fprintf(out, "<br>\n");
	    else
		fprintf(out, "\n");
	}
	else {
	    char *tail  = 0;
	    int len = RSTRING_LEN(einfo);

	    if (RSTRING_PTR(epath)[0] == '#') epath = 0;
	    if ((tail = strchr(RSTRING_PTR(einfo), '\n')) != NULL) {
		len = tail - RSTRING_PTR(einfo);
		tail++;		/* skip newline */
	    }
	    fprintf(out, ": ");
	    if (cgi)
		write_escaping_html(out, RSTRING_PTR(einfo), len);
	    else
		fwrite(RSTRING_PTR(einfo), 1, len, out);
	    if (epath) {
		fprintf(out, " (");
		if (cgi)
		    write_escaping_html(out, RSTRING_PTR(epath), RSTRING_LEN(epath));
		else
		    fwrite(RSTRING_PTR(epath), 1, RSTRING_LEN(epath), out);
		if (cgi)
		    fprintf(out, ")<br>\n");
		else
		    fprintf(out, ")\n");
	    }
	    if (tail) {
		if (cgi)
		    write_escaping_html(out, tail, RSTRING_LEN(einfo) - len - 1);
		else
		    fwrite(tail, 1, RSTRING_LEN(einfo) - len - 1, out);
		if (cgi)
		    fprintf(out, "<br>\n");
		else
		    fprintf(out, "\n");
	    }
	}
    }

    if (!NIL_P(errat)) {
	int i;
	struct RArray *ep = RARRAY(errat);

#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
#define TRACE_HEAD 8
#define TRACE_TAIL 5

	rb_ary_pop(errat);
	ep = RARRAY(errat);
	for (i=1; i<RARRAY_LEN(ep); i++) {
	    if (TYPE(RARRAY_PTR(ep)[i]) == T_STRING) {
		if (cgi) {
		    fprintf(out, "<div class=\"backtrace\">from ");
		    write_escaping_html(out,
					RSTRING_PTR(RARRAY_PTR(ep)[i]),
					RSTRING_LEN(RARRAY_PTR(ep)[i]));
		}
		else {
		    fprintf(out, "        from ");
		    fwrite(RSTRING_PTR(RARRAY_PTR(ep)[i]), 1,
			   RSTRING_LEN(RARRAY_PTR(ep)[i]), out);
		}
		if (cgi)
		    fprintf(out, "<br></div>\n");
		else
		    fprintf(out, "\n");
	    }
	    if (i == TRACE_HEAD && RARRAY_LEN(ep) > TRACE_MAX) {
		char buff[BUFSIZ];
		if (cgi)
		    snprintf(buff, BUFSIZ,
			     "<div class=\"backtrace\">... %ld levels...\n",
			     RARRAY_LEN(ep) - TRACE_HEAD - TRACE_TAIL);
		else
		    snprintf(buff, BUFSIZ, "         ... %ld levels...<br></div>\n",
			     RARRAY_LEN(ep) - TRACE_HEAD - TRACE_TAIL);
		if (cgi)
		    write_escaping_html(out, buff, strlen(buff));
		else
		    fputs(buff, out);
		i = RARRAY_LEN(ep) - TRACE_TAIL;
	    }
	}
    }
}
Ejemplo n.º 6
0
static void
error_print(void)
{
    volatile VALUE errat = Qnil;		/* OK */
    VALUE errinfo = GET_THREAD()->errinfo;
    volatile VALUE eclass, e;
    const char *volatile einfo;
    volatile long elen;

    if (NIL_P(errinfo))
	return;

    PUSH_TAG();
    if (EXEC_TAG() == 0) {
	errat = get_backtrace(errinfo);
    }
    else {
	errat = Qnil;
    }
    if (EXEC_TAG())
	goto error;
    if (NIL_P(errat)) {
	const char *file = rb_sourcefile();
	int line = rb_sourceline();
	if (!file)
	    warn_printf("%d", line);
	else if (!line)
	    warn_printf("%s", file);
	else
	    warn_printf("%s:%d", file, line);
    }
    else if (RARRAY_LEN(errat) == 0) {
	error_pos();
    }
    else {
	VALUE mesg = RARRAY_PTR(errat)[0];

	if (NIL_P(mesg))
	    error_pos();
	else {
	    warn_print2(RSTRING_PTR(mesg), RSTRING_LEN(mesg));
	}
    }

    eclass = CLASS_OF(errinfo);
    if (EXEC_TAG() == 0) {
	e = rb_funcall(errinfo, rb_intern("message"), 0, 0);
	StringValue(e);
	einfo = RSTRING_PTR(e);
	elen = RSTRING_LEN(e);
    }
    else {
	einfo = "";
	elen = 0;
    }
    if (EXEC_TAG())
	goto error;
    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print(": unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print(": ");
	    warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
	    warn_print("\n");
	}
	else {
	    char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print(": ");
	    warn_print2(einfo, len);
	    if (epath) {
		warn_print(" (");
		warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print2(tail, elen - len - 1);
		if (einfo[elen-1] != '\n') warn_print2("\n", 1);
	    }
	}
    }

    if (!NIL_P(errat)) {
	long i;
	long len = RARRAY_LEN(errat);
	VALUE *ptr = RARRAY_PTR(errat);
        int skip = eclass == rb_eSysStackError;

#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
#define TRACE_HEAD 8
#define TRACE_TAIL 5

	for (i = 1; i < len; i++) {
	    if (TYPE(ptr[i]) == T_STRING) {
		warn_printf("\tfrom %s\n", RSTRING_PTR(ptr[i]));
	    }
	    if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
		warn_printf("\t ... %ld levels...\n",
			    len - TRACE_HEAD - TRACE_TAIL);
		i = len - TRACE_TAIL;
	    }
	}
    }
  error:
    POP_TAG();
}