9 rb_thread_t
*th
= GET_THREAD();
10 rb_control_frame_t
*cfp
= vm_get_ruby_level_cfp(th
, th
->cfp
);
13 return RSTRING_PTR(cfp
->iseq
->filename
);
23 rb_thread_t
*th
= GET_THREAD();
24 rb_control_frame_t
*cfp
= vm_get_ruby_level_cfp(th
, th
->cfp
);
27 return vm_get_sourceline(cfp
);
35 warn_printf(const char *fmt
, ...)
40 va_init_list(args
, fmt
);
41 vsnprintf(buf
, BUFSIZ
, fmt
, args
);
46 #define warn_print(x) rb_write_error(x)
47 #define warn_print2(x,l) rb_write_error2(x,l)
52 const char *sourcefile
= rb_sourcefile();
53 int sourceline
= rb_sourceline();
56 if (sourceline
== 0) {
57 warn_printf("%s", sourcefile
);
59 else if (rb_frame_callee()) {
60 warn_printf("%s:%d:in `%s'", sourcefile
, sourceline
,
61 rb_id2name(rb_frame_callee()));
64 warn_printf("%s:%d", sourcefile
, sourceline
);
69 VALUE
rb_check_backtrace(VALUE
);
72 get_backtrace(VALUE info
)
76 info
= rb_funcall(info
, rb_intern("backtrace"), 0);
79 return rb_check_backtrace(info
);
83 set_backtrace(VALUE info
, VALUE bt
)
85 rb_funcall(info
, rb_intern("set_backtrace"), 1, bt
);
91 VALUE errat
= Qnil
; /* OK */
92 VALUE errinfo
= GET_THREAD()->errinfo
;
93 volatile VALUE eclass
, e
;
101 if (EXEC_TAG() == 0) {
102 errat
= get_backtrace(errinfo
);
110 const char *file
= rb_sourcefile();
111 int line
= rb_sourceline();
113 warn_printf("%s:%d", file
, line
);
115 warn_printf("%d", line
);
117 else if (RARRAY_LEN(errat
) == 0) {
121 VALUE mesg
= RARRAY_PTR(errat
)[0];
126 warn_print2(RSTRING_PTR(mesg
), RSTRING_LEN(mesg
));
130 eclass
= CLASS_OF(errinfo
);
131 if (EXEC_TAG() == 0) {
132 e
= rb_funcall(errinfo
, rb_intern("message"), 0, 0);
134 einfo
= RSTRING_PTR(e
);
135 elen
= RSTRING_LEN(e
);
143 if (eclass
== rb_eRuntimeError
&& elen
== 0) {
144 warn_print(": unhandled exception\n");
149 epath
= rb_class_name(eclass
);
152 warn_print2(RSTRING_PTR(epath
), RSTRING_LEN(epath
));
159 if (RSTRING_PTR(epath
)[0] == '#')
161 if ((tail
= memchr(einfo
, '\n', elen
)) != 0) {
163 tail
++; /* skip newline */
166 warn_print2(einfo
, len
);
169 warn_print2(RSTRING_PTR(epath
), RSTRING_LEN(epath
));
173 warn_print2(tail
, elen
- len
- 1);
174 if (einfo
[elen
-1] != '\n') warn_print2("\n", 1);
181 long len
= RARRAY_LEN(errat
);
182 VALUE
*ptr
= RARRAY_PTR(errat
);
183 int skip
= eclass
== rb_eSysStackError
;
185 #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
189 for (i
= 1; i
< len
; i
++) {
190 if (TYPE(ptr
[i
]) == T_STRING
) {
191 warn_printf("\tfrom %s\n", RSTRING_PTR(ptr
[i
]));
193 if (skip
&& i
== TRACE_HEAD
&& len
> TRACE_MAX
) {
194 warn_printf("\t ... %ld levels...\n",
195 len
- TRACE_HEAD
- TRACE_TAIL
);
196 i
= len
- TRACE_TAIL
;
205 ruby_error_print(void)
211 rb_print_undef(VALUE klass
, ID id
, int scope
)
217 case NOEX_PUBLIC
: v
= ""; break;
218 case NOEX_PRIVATE
: v
= " private"; break;
219 case NOEX_PROTECTED
: v
= " protected"; break;
221 rb_name_error(id
, "undefined%s method `%s' for %s `%s'", v
,
223 (TYPE(klass
) == T_MODULE
) ? "module" : "class",
224 rb_class2name(klass
));
228 sysexit_status(VALUE err
)
230 VALUE st
= rb_iv_get(err
, "status");
237 int status
= EXIT_FAILURE
;
238 rb_thread_t
*th
= GET_THREAD();
240 if (rb_thread_set_raised(th
))
242 switch (ex
& TAG_MASK
) {
244 status
= EXIT_SUCCESS
;
249 warn_print(": unexpected return\n");
253 warn_print(": unexpected next\n");
257 warn_print(": unexpected break\n");
261 warn_print(": unexpected redo\n");
265 warn_print(": retry outside of rescue clause\n");
270 warn_printf(": unexpected throw\n");
274 VALUE errinfo
= GET_THREAD()->errinfo
;
275 if (rb_obj_is_kind_of(errinfo
, rb_eSystemExit
)) {
276 status
= sysexit_status(errinfo
);
278 else if (rb_obj_is_instance_of(errinfo
, rb_eSignal
)) {
279 /* no message when exiting by signal */
287 rb_bug("Unknown longjmp status %d", ex
);
290 rb_thread_reset_raised(th
);