Skip to content

Commit

Permalink
fix segfault on exception breakpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
denofevil committed Jun 22, 2011
1 parent 71e26e3 commit 0597592
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 44 deletions.
58 changes: 14 additions & 44 deletions ext/ruby_debug/ruby_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <insns_info.inc>
#include "ruby_debug.h"

#define DEBUG_VERSION "0.11.28"
#define DEBUG_VERSION "0.11.29"

#define FRAME_N(n) (&debug_context->frames[debug_context->stack_size-(n)-1])
#define GET_FRAME (FRAME_N(check_frame_number(debug_context, frame)))
Expand Down Expand Up @@ -848,36 +848,6 @@ debug_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE kl
else
set_frame_source(event, debug_context, self, file, line, mid);

if (CTX_FL_TEST(debug_context, CTX_FL_CATCHING))
{
debug_frame_t *top_frame = get_top_frame(debug_context);

if (top_frame != NULL)
{
rb_control_frame_t *cfp = top_frame->info.runtime.cfp;
int hit_count;

/* restore the proper catch table */
cfp->iseq->catch_table_size = debug_context->catch_table.old_catch_table_size;
cfp->iseq->catch_table = debug_context->catch_table.old_catch_table;

/* send catchpoint notification */
hit_count = INT2FIX(FIX2INT(rb_hash_aref(rdebug_catchpoints,
debug_context->catch_table.mod_name)+1));
rb_hash_aset(rdebug_catchpoints, debug_context->catch_table.mod_name, hit_count);
debug_context->stop_reason = CTX_STOP_CATCHPOINT;
rb_funcall(context, idAtCatchpoint, 1, debug_context->catch_table.errinfo);
if(self && binding == Qnil)
binding = create_binding(self);
save_top_binding(debug_context, binding);
call_at_line(context, debug_context, rb_str_new2(file), INT2FIX(line));
}

/* now allow the next exception to be caught */
CTX_FL_UNSET(debug_context, CTX_FL_CATCHING);
break;
}

if(RTEST(tracing) || CTX_FL_TEST(debug_context, CTX_FL_TRACING))
rb_funcall(context, idAtTracing, 2, rb_str_new2(file), INT2FIX(line));

Expand Down Expand Up @@ -1046,17 +1016,17 @@ debug_event_hook(rb_event_flag_t event, VALUE data, VALUE self, ID mid, VALUE kl
debug_frame_t *top_frame = get_top_frame(debug_context);
rb_control_frame_t *cfp = top_frame->info.runtime.cfp;

/* save the current catch table */
CTX_FL_SET(debug_context, CTX_FL_CATCHING);
debug_context->catch_table.old_catch_table_size = cfp->iseq->catch_table_size;
debug_context->catch_table.old_catch_table = cfp->iseq->catch_table;
debug_context->catch_table.mod_name = mod_name;
debug_context->catch_table.errinfo = rb_errinfo();

/* create a new catch table to catch this exception, and put it in the current iseq */
cfp->iseq->catch_table_size = 1;
cfp->iseq->catch_table =
create_catch_table(debug_context, top_frame->info.runtime.last_pc - cfp->iseq->iseq_encoded - insn_len(BIN(trace)));
/* send catchpoint notification */
int c_hit_count = FIX2INT(rb_hash_aref(rdebug_catchpoints, mod_name)) + 1;
hit_count = INT2FIX(c_hit_count);
rb_hash_aset(rdebug_catchpoints, mod_name, hit_count);
debug_context->stop_reason = CTX_STOP_CATCHPOINT;
rb_funcall(context, idAtCatchpoint, 1, rb_errinfo());

if(self && binding == Qnil)
binding = create_binding(self);
save_top_binding(debug_context, binding);
call_at_line(context, debug_context, rb_str_new2(file), INT2FIX(line));
break;
}
}
Expand Down Expand Up @@ -1832,8 +1802,8 @@ context_frame_file(int argc, VALUE *argv, VALUE self)
frame = optional_frame_position(argc, argv);
Data_Get_Struct(self, debug_context_t, debug_context);

return rb_str_new_cstr(GET_FRAME->file);
//return(GET_FRAME->info.runtime.cfp->iseq->filename);
return rb_str_new_cstr(GET_FRAME->file);
//return(GET_FRAME->info.runtime.cfp->iseq->filename);
}

static int
Expand Down
25 changes: 25 additions & 0 deletions test/base/regression/catchpoint_segfault_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require_relative '../debug_test_base'

class CatchpointSegfaultTest < DebugTestBase
# test current_context
def test_catchpoints
Debugger.handler=FakeHandler.new
Debugger.start_
Debugger.add_catchpoint('ZeroDivisionError')
err
ensure
Debugger.stop
end

def err
begin
5/0
rescue
end
end
end

class FakeHandler
def method_missing(meth, *args, &block)
end
end

0 comments on commit 0597592

Please sign in to comment.