ruby-changes:20226
From: ko1 <ko1@a...>
Date: Wed, 29 Jun 2011 06:17:42 +0900 (JST)
Subject: [ruby-changes:20226] ko1:r32274 (trunk): * error.c (rb_async_bug_errno): async-safe bug report function.
ko1 2011-06-29 06:17:29 +0900 (Wed, 29 Jun 2011) New Revision: 32274 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32274 Log: * error.c (rb_async_bug_errno): async-safe bug report function. In timer thread, signal handler shoul use it. The patch is contributed by Eric Wong <normalperson@y...>. Refs: [ruby-core:37644] and [ruby-core:37647] * thread_pthread.c: use rb_async_bug_errno(). And replace all fprintf() to write(). * internal.h (rb_async_bug_errno): add decl. of above func. Modified files: trunk/ChangeLog trunk/error.c trunk/internal.h trunk/thread_pthread.c Index: ChangeLog =================================================================== --- ChangeLog (revision 32273) +++ ChangeLog (revision 32274) @@ -1,3 +1,15 @@ +Wed Jun 29 06:09:54 2011 Koichi Sasada <ko1@a...> + + * error.c (rb_async_bug_errno): async-safe bug report function. + In timer thread, signal handler shoul use it. + The patch is contributed by Eric Wong <normalperson@y...>. + Refs: [ruby-core:37644] and [ruby-core:37647] + + * thread_pthread.c: use rb_async_bug_errno(). + And replace all fprintf() to write(). + + * internal.h (rb_async_bug_errno): add decl. of above func. + Tue Jun 28 23:46:08 2011 Keiju Ishitsuka <keiju@i...> * lib/tracer.rb: count only non-internal libraries in stack trace, Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 32273) +++ thread_pthread.c (revision 32274) @@ -990,6 +990,9 @@ #define TT_DEBUG 0 +#define WRITE_CONST(fd, str) write((fd),(str),sizeof(str)-1); + +/* only use signal-safe system calls here */ void rb_thread_wakeup_timer_thread(void) { @@ -1008,16 +1011,17 @@ #endif break; default: - rb_bug_errno("rb_thread_wakeup_timer_thread - write", errno); + rb_async_bug_errno("rb_thread_wakeup_timer_thread - write", errno); } } - if (TT_DEBUG) fprintf(stderr, "rb_thread_wakeup_timer_thread: write\n"); + if (TT_DEBUG) WRITE_CONST(2, "rb_thread_wakeup_timer_thread: write\n"); } else { /* ignore wakeup */ } } +/* VM-dependent API is not available for this function */ static void consume_communication_pipe(void) { @@ -1032,7 +1036,7 @@ switch (errno) { case EINTR: goto retry; default: - rb_bug_errno("consume_communication_pipe: read", errno); + rb_async_bug_errno("consume_communication_pipe: read\n", errno); } } } @@ -1061,7 +1065,7 @@ int result; struct timeval timeout; - if (TT_DEBUG) fprintf(stderr, "start timer thread\n"); + if (TT_DEBUG) WRITE_CONST(2, "start timer thread\n"); while (system_working > 0) { fd_set rfds; @@ -1069,7 +1073,7 @@ /* timer function */ ping_signal_thread_list(); timer_thread_function(0); - if (TT_DEBUG) fprintf(stderr, "tick\n"); + if (TT_DEBUG) WRITE_CONST(2, "tick\n"); /* wait */ FD_ZERO(&rfds); @@ -1098,12 +1102,12 @@ /* interrupted. ignore */ } else { - rb_bug_errno("thread_timer: select", errno); + rb_async_bug_errno("thread_timer: select", errno); } } } - if (TT_DEBUG) fprintf(stderr, "finish timer thread\n"); + if (TT_DEBUG) WRITE_CONST(2, "finish timer thread\n"); return NULL; } Index: error.c =================================================================== --- error.c (revision 32273) +++ error.c (revision 32274) @@ -21,6 +21,9 @@ #include <stdlib.h> #endif #include <errno.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 @@ -36,6 +39,13 @@ extern const char ruby_description[]; +#define REPORTBUG_MSG \ + "[NOTE]\n" \ + "You may have encountered a bug in the Ruby interpreter" \ + " or extension libraries.\n" \ + "Bug reports are welcome.\n" \ + "For details: http://www.ruby-lang.org/bugreport.html\n\n" \ + static const char * rb_strerrno(int err) { @@ -247,12 +257,7 @@ rb_vm_bugreport(); - fprintf(out, - "[NOTE]\n" - "You may have encountered a bug in the Ruby interpreter" - " or extension libraries.\n" - "Bug reports are welcome.\n" - "For details: http://www.ruby-lang.org/bugreport.html\n\n"); + fprintf(out, REPORTBUG_MSG); } } @@ -286,6 +291,35 @@ } } +/* + * this is safe to call inside signal handler and timer thread + * (which isn't a Ruby Thread object) + */ +#define WRITE_CONST(fd,str) write((fd),(str),sizeof(str) - 1) + +void rb_async_bug_errno(const char *mesg, int errno_arg) +{ + WRITE_CONST(2, "[ASYNC BUG] "); + write(2, mesg, strlen(mesg)); + WRITE_CONST(2, "\n"); + + if (errno_arg == 0) { + WRITE_CONST(2, "errno == 0 (NOERROR)\n"); + } + else { + const char *errno_str = rb_strerrno(errno_arg); + + if (!errno_str) + errno_str = "undefined errno"; + write(2, errno_str, strlen(errno_str)); + } + WRITE_CONST(2, "\n\n"); + write(2, ruby_description, strlen(ruby_description)); + WRITE_CONST(2, "\n\n"); + WRITE_CONST(2, REPORTBUG_MSG); + abort(); +} + void rb_compile_bug(const char *file, int line, const char *fmt, ...) { Index: internal.h =================================================================== --- internal.h (revision 32273) +++ internal.h (revision 32274) @@ -76,6 +76,7 @@ /* error.c */ NORETURN(PRINTF_ARGS(void rb_compile_bug(const char*, int, const char*, ...), 3, 4)); VALUE rb_check_backtrace(VALUE); +NORETURN(void rb_async_bug_errno(const char *,int)); /* eval_error.c */ void ruby_error_print(void); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/