Skip to content

Commit 85493d7

Browse files
viuginick1valich
authored andcommitted
monkeypatch load_iseq for debugger to work along with bootsnap (#61)
* monkey patch InstructionSequence#load_iseq to set tracing flags * workaround for ruby versions older than 2.5.0
1 parent 54f0d8f commit 85493d7

File tree

6 files changed

+82
-6
lines changed

6 files changed

+82
-6
lines changed

ext/attach/extconf.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@
2828
require "debase/ruby_core_source"
2929

3030
hdrs = proc {
31-
have_header("vm_core.h")
31+
have_header("vm_core.h") and
32+
have_header("iseq.h") and
33+
have_header("version.h") and
34+
have_header("vm_core.h") and
35+
have_header("vm_insnhelper.h") and
36+
have_header("vm_core.h") and
37+
have_header("method.h")
3238
}
3339

3440
# Allow use customization of compile options. For example, the

ext/debase_internals.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,36 @@ Debase_enable_file_filtering(VALUE self, VALUE value)
637637
return value;
638638
}
639639

640+
#if RUBY_API_VERSION_CODE >= 20500
641+
static const rb_iseq_t *
642+
my_iseqw_check(VALUE iseqw)
643+
{
644+
rb_iseq_t *iseq = DATA_PTR(iseqw);
645+
646+
if (!iseq->body) {
647+
ibf_load_iseq_complete(iseq);
648+
}
649+
650+
if (!iseq->body->location.label) {
651+
rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
652+
}
653+
return iseq;
654+
}
655+
656+
static void
657+
Debase_set_trace_flag_to_iseq(VALUE self, VALUE rb_iseq)
658+
{
659+
if (!SPECIAL_CONST_P(rb_iseq) && RBASIC_CLASS(rb_iseq) == rb_cISeq) {
660+
rb_iseq_t *iseq = my_iseqw_check(rb_iseq);
661+
rb_iseq_trace_set(iseq, RUBY_EVENT_TRACEPOINT_ALL);
662+
}
663+
}
664+
#else
665+
static void
666+
Debase_set_trace_flag_to_iseq(VALUE self, VALUE rb_iseq) {
667+
}
668+
#endif
669+
640670
static VALUE
641671
Debase_init_variables()
642672
{
@@ -680,6 +710,7 @@ Init_debase_internals()
680710
rb_define_module_function(mDebase, "enable_trace_points", Debase_enable_trace_points, 0);
681711
rb_define_module_function(mDebase, "prepare_context", Debase_prepare_context, 0);
682712
rb_define_module_function(mDebase, "init_variables", Debase_init_variables, 0);
713+
rb_define_module_function(mDebase, "set_trace_flag_to_iseq", Debase_set_trace_flag_to_iseq, 1);
683714

684715
idAlive = rb_intern("alive?");
685716
idAtLine = rb_intern("at_line");

ext/debase_internals.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#ifndef DEBASE_INTERNALS
22
#define DEBASE_INTERNALS
33

4-
#include <ruby.h>
4+
#include "ruby.h"
5+
#include "vm_core.h"
6+
#include "version.h"
7+
#include "iseq.h"
8+
#include "vm_insnhelper.h"
9+
#include "method.h"
510
#include <ruby/debug.h>
611

712
typedef struct rb_trace_arg_struct rb_trace_point_t;

ext/extconf.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@
2828
require "debase/ruby_core_source"
2929

3030
hdrs = proc {
31-
have_header("vm_core.h")
32-
have_header("version.h")
31+
have_header("vm_core.h") and
32+
have_header("iseq.h") and
33+
have_header("version.h") and
34+
have_header("vm_core.h") and
35+
have_header("vm_insnhelper.h") and
36+
have_header("vm_core.h") and
37+
have_header("method.h")
3338
}
3439

3540
# Allow use customization of compile options. For example, the

lib/debase.rb

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,21 @@ def start(options={}, &block)
2020
Debugger.const_set('ARGV', ARGV.clone) unless defined? Debugger::ARGV
2121
Debugger.const_set('PROG_SCRIPT', $0) unless defined? Debugger::PROG_SCRIPT
2222
Debugger.const_set('INITIAL_DIR', Dir.pwd) unless defined? Debugger::INITIAL_DIR
23-
return Debugger.started? ? block && block.call(self) : Debugger.start_(&block)
23+
24+
monkey_patch_prepend
25+
26+
Debugger.started? ? block && block.call(self) : Debugger.start_(&block)
27+
end
28+
29+
def monkey_patch_prepend
30+
class << RubyVM::InstructionSequence
31+
def self.prepend(mod, *smth)
32+
super
33+
if mod.to_s.include? 'Bootsnap'
34+
prepend InstructionSequenceMixin
35+
end
36+
end
37+
end
2438
end
2539

2640
# @param [String] file
@@ -81,6 +95,21 @@ def last_context
8195
def file_filter
8296
@file_filter ||= FileFilter.new
8397
end
98+
99+
module InstructionSequenceMixin
100+
def load_iseq(path)
101+
iseq = super(path)
102+
103+
do_set_flags(iseq)
104+
105+
iseq
106+
end
107+
108+
def do_set_flags(iseq)
109+
Debugger.set_trace_flag_to_iseq(iseq)
110+
iseq.each_child{|child_iseq| do_set_flags(child_iseq)}
111+
end
112+
end
84113
end
85114

86115
class FileFilter

lib/debase/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Debase
2-
VERSION = "0.2.3.beta1" unless defined? VERSION
2+
VERSION = "0.2.3.beta2" unless defined? VERSION
33
end

0 commit comments

Comments
 (0)