Skip to content

Commit

Permalink
[#205] Fix assert to handle case where a SimpleThreadAPI process is e…
Browse files Browse the repository at this point in the history
…xiting and exit handler is being invoked in a thread other than the MAIN worker thread

We got a test failure in the simplethreadapi/tp subtest where a SimpleThreadAPI process was exiting
and as part of the exit handler, we ended up checking for deferred timers and that failed the following
assert in timer_handler().

	assert(gtm_is_main_thread() || gtm_jvm_process);

In this case, we were exiting as the below C-stack shows.

(gdb) where
 #0  __pthread_kill (threadid=<optimized out>, signo=3) at ../sysdeps/unix/sysv/linux/pthread_kill.c:62
 #1  gtm_dump_core () at sr_unix/gtm_dump_core.c:72
 #2  gtm_fork_n_core () at sr_unix/gtm_fork_n_core.c:148
 #3  ch_cond_core () at sr_unix/ch_cond_core.c:64
 #4  rts_error_va (csa=0x0, argcnt=7, var=0x7ffe7c683120) at sr_unix/rts_error.c:194
 #5  rts_error_csa (csa=0x0, argcnt=7) at sr_unix/rts_error.c:101
 #6  timer_handler (why=0) at sr_unix/gt_timers.c:724
 #7  check_for_deferred_timers () at sr_unix/gt_timers.c:1178
 #8  deferred_signal_handler () at sr_port/deferred_signal_handler.c:49
 #9  gtm_exit_handler () at sr_unix/gtm_exit_handler.c:191
 #10 __run_exit_handlers (status=0, listp=0x7fb6d8d2f5f8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
 #11 __GI_exit (status=<optimized out>) at exit.c:104
 #12 __libc_start_main (main=0x400f76 <main>, argc=1, argv=0x7ffe7c683648, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffe7c683638) at ../csu/libc-start.c:325
 #13 _start ()

So the assert is enhanced to reflect this.
  • Loading branch information
nars1 committed Dec 19, 2018
1 parent a2a5c46 commit 1db06c5
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion sr_unix/gt_timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ GBLREF boolean_t posix_timer_created;
#ifdef DEBUG
GBLREF boolean_t in_nondeferrable_signal_handler;
GBLREF boolean_t gtm_jvm_process;
GBLREF boolean_t exit_handler_active;
#endif

error_def(ERR_SETITIMERFAILED);
Expand Down Expand Up @@ -721,7 +722,7 @@ STATICFNDEF void timer_handler(int why)
/* else: why == DUMMY_SIG_NUM we know that "timer_handler" was called directly, so no need
* to check if the signal needs to be forwarded to appropriate thread.
*/
assert(gtm_is_main_thread() || gtm_jvm_process);
assert(gtm_is_main_thread() || gtm_jvm_process || exit_handler_active && (DUMMY_SIG_NUM == why));
DUMP_TIMER_INFO("At the start of timer_handler()");
# ifdef DEBUG
/* Note that it is possible "in_nondeferrable_signal_handler" is non-zero if we first went into generic_signal_handler
Expand Down

0 comments on commit 1db06c5

Please sign in to comment.