From 399cd14fb99d5f08569869cf650feb7eb230d4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 31 Dec 2014 16:56:09 +0100 Subject: [PATCH] Fixes #54 Sometimes TracePoint API events are generated for dead or aborting threads. Just ignore those events. --- ext/byebug/byebug.c | 4 ++++ ext/byebug/byebug.h | 1 + ext/byebug/threads.c | 28 ++++++++++++++++++---------- test/commands/eval_test.rb | 1 - 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/ext/byebug/byebug.c b/ext/byebug/byebug.c index c312fe31c..3befe5551 100644 --- a/ext/byebug/byebug.c +++ b/ext/byebug/byebug.c @@ -145,6 +145,10 @@ cleanup(debug_context_t * dc) rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(trace_point); \ debug_context_t *dc; \ VALUE context; \ + \ + if (!is_living_thread(rb_thread_current())) \ + return; \ + \ thread_context_lookup(rb_thread_current(), &context); \ Data_Get_Struct(context, debug_context_t, dc); \ \ diff --git a/ext/byebug/byebug.h b/ext/byebug/byebug.h index 1670f6f8c..538433180 100644 --- a/ext/byebug/byebug.h +++ b/ext/byebug/byebug.h @@ -66,6 +66,7 @@ extern VALUE create_threads_table(void); extern void check_threads_table(void); extern void thread_context_lookup(VALUE thread, VALUE *context); extern void halt_while_other_thread_is_active(debug_context_t *dc); +extern int is_living_thread(VALUE thread); /* global variables */ extern VALUE locker; diff --git a/ext/byebug/threads.c b/ext/byebug/threads.c index bb52b6c3b..d7e4fa33a 100644 --- a/ext/byebug/threads.c +++ b/ext/byebug/threads.c @@ -49,16 +49,6 @@ create_threads_table(void) return Data_Wrap_Struct(cThreadsTable, t_tbl_mark, t_tbl_free, t_tbl); } -/* - * The condition to be in the thread's table is to be either running or - * sleeping, namely, to be Thread#alive? - */ -static int -is_living_thread(VALUE thread) -{ - return rb_funcall(thread, rb_intern("alive?"), 0) == Qtrue; -} - /* * Checks a single entry in the threads table. * @@ -77,6 +67,24 @@ check_thread_i(st_data_t key, st_data_t value, st_data_t dummy) return ST_CONTINUE; } +/* + * Checks whether a thread is either in the running or sleeping state. + */ +int +is_living_thread(VALUE thread) +{ + VALUE status = rb_funcall(thread, rb_intern("status"), 0); + + if (status == Qfalse) + return 0; + + if (rb_str_cmp(status, rb_str_new2("run")) == 0 + || rb_str_cmp(status, rb_str_new2("sleep")) == 0) + return 1; + + return 0; +} + /* * Checks threads table for dead/finished threads. */ diff --git a/test/commands/eval_test.rb b/test/commands/eval_test.rb index 213b3e29d..01f3fd078 100644 --- a/test/commands/eval_test.rb +++ b/test/commands/eval_test.rb @@ -36,7 +36,6 @@ def program end def test_eval_properly_evaluates_an_expression_using_timeout - skip('for now') enter 'eval Timeout::timeout(60) { 1 }' debug_code(program) check_output_includes '1'