ruby-debug-ide22 0.7.4 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +75 -75
- data/ChangeLog.archive +1073 -1073
- data/ChangeLog.md +594 -594
- data/Gemfile +38 -38
- data/MIT-LICENSE +24 -24
- data/Rakefile +92 -92
- data/bin/gdb_wrapper +96 -96
- data/bin/rdebug-ide +200 -200
- data/ext/mkrf_conf.rb +44 -44
- data/lib/ruby-debug-ide/attach/debugger_loader.rb +20 -20
- data/lib/ruby-debug-ide/attach/gdb.rb +73 -73
- data/lib/ruby-debug-ide/attach/lldb.rb +71 -71
- data/lib/ruby-debug-ide/attach/native_debugger.rb +133 -133
- data/lib/ruby-debug-ide/attach/process_thread.rb +54 -54
- data/lib/ruby-debug-ide/attach/util.rb +114 -114
- data/lib/ruby-debug-ide/command.rb +187 -187
- data/lib/ruby-debug-ide/commands/breakpoints.rb +128 -128
- data/lib/ruby-debug-ide/commands/catchpoint.rb +64 -64
- data/lib/ruby-debug-ide/commands/condition.rb +51 -51
- data/lib/ruby-debug-ide/commands/control.rb +164 -158
- data/lib/ruby-debug-ide/commands/enable.rb +203 -203
- data/lib/ruby-debug-ide/commands/eval.rb +64 -64
- data/lib/ruby-debug-ide/commands/expression_info.rb +71 -71
- data/lib/ruby-debug-ide/commands/file_filtering.rb +106 -106
- data/lib/ruby-debug-ide/commands/frame.rb +155 -155
- data/lib/ruby-debug-ide/commands/inspect.rb +25 -25
- data/lib/ruby-debug-ide/commands/load.rb +17 -17
- data/lib/ruby-debug-ide/commands/stepping.rb +108 -108
- data/lib/ruby-debug-ide/commands/threads.rb +178 -178
- data/lib/ruby-debug-ide/commands/variables.rb +154 -154
- data/lib/ruby-debug-ide/event_processor.rb +71 -71
- data/lib/ruby-debug-ide/greeter.rb +42 -42
- data/lib/ruby-debug-ide/helper.rb +33 -33
- data/lib/ruby-debug-ide/ide_processor.rb +155 -155
- data/lib/ruby-debug-ide/interface.rb +47 -45
- data/lib/ruby-debug-ide/multiprocess/monkey.rb +46 -46
- data/lib/ruby-debug-ide/multiprocess/pre_child.rb +58 -58
- data/lib/ruby-debug-ide/multiprocess/starter.rb +10 -10
- data/lib/ruby-debug-ide/multiprocess/unmonkey.rb +30 -30
- data/lib/ruby-debug-ide/multiprocess.rb +22 -22
- data/lib/ruby-debug-ide/thread_alias.rb +26 -26
- data/lib/ruby-debug-ide/version.rb +3 -3
- data/lib/ruby-debug-ide/xml_printer.rb +570 -570
- data/lib/ruby-debug-ide.rb +230 -228
- data/ruby-debug-ide.gemspec +47 -47
- metadata +4 -4
@@ -1,73 +1,73 @@
|
|
1
|
-
require 'ruby-debug-ide/attach/native_debugger'
|
2
|
-
|
3
|
-
class GDB < NativeDebugger
|
4
|
-
|
5
|
-
def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
6
|
-
super(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
7
|
-
end
|
8
|
-
|
9
|
-
def set_flags
|
10
|
-
execute 'set scheduler-locking off' # we will deadlock with it
|
11
|
-
execute 'set unwindonsignal on' # in case of some signal we will exit gdb
|
12
|
-
end
|
13
|
-
|
14
|
-
def update_threads
|
15
|
-
@process_threads = []
|
16
|
-
info_threads = (execute 'info threads').split("\n")
|
17
|
-
info_threads.each do |thread_info|
|
18
|
-
next unless thread_info =~ /[\s*]*\d+\s+Thread.*/
|
19
|
-
$stdout.puts "thread_info: #{thread_info}"
|
20
|
-
is_main = thread_info[0] == '*'
|
21
|
-
thread_num = thread_info.sub(/[\s*]*/, '').sub(/\s.*$/, '').to_i
|
22
|
-
thread = ProcessThread.new(thread_num, is_main, thread_info, self)
|
23
|
-
if thread.is_main
|
24
|
-
@main_thread = thread
|
25
|
-
end
|
26
|
-
@process_threads << thread
|
27
|
-
end
|
28
|
-
@process_threads
|
29
|
-
end
|
30
|
-
|
31
|
-
def check_already_under_debug
|
32
|
-
threads = execute 'info threads'
|
33
|
-
threads =~ /ruby-debug-ide/
|
34
|
-
end
|
35
|
-
|
36
|
-
def switch_to_thread(thread_num)
|
37
|
-
execute "thread #{thread_num}"
|
38
|
-
end
|
39
|
-
|
40
|
-
def set_break(str)
|
41
|
-
execute "tbreak #{str}"
|
42
|
-
end
|
43
|
-
|
44
|
-
def call_start_attach
|
45
|
-
super()
|
46
|
-
execute "call dlopen(\"#{@path_to_attach}\", 2)"
|
47
|
-
execute 'call debase_start_attach()'
|
48
|
-
set_break(@tbreak)
|
49
|
-
end
|
50
|
-
|
51
|
-
def print_delimiter
|
52
|
-
@pipe.puts "print \"#{@delimiter}\""
|
53
|
-
end
|
54
|
-
|
55
|
-
def check_delimiter(line)
|
56
|
-
line =~ /\$\d+\s=\s"#{@delimiter}"/
|
57
|
-
end
|
58
|
-
|
59
|
-
def load_debugger
|
60
|
-
execute "call #{@eval_string}"
|
61
|
-
end
|
62
|
-
|
63
|
-
def to_s
|
64
|
-
GDB.to_s
|
65
|
-
end
|
66
|
-
|
67
|
-
class << self
|
68
|
-
def to_s
|
69
|
-
'gdb'
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
1
|
+
require 'ruby-debug-ide/attach/native_debugger'
|
2
|
+
|
3
|
+
class GDB < NativeDebugger
|
4
|
+
|
5
|
+
def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
6
|
+
super(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_flags
|
10
|
+
execute 'set scheduler-locking off' # we will deadlock with it
|
11
|
+
execute 'set unwindonsignal on' # in case of some signal we will exit gdb
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_threads
|
15
|
+
@process_threads = []
|
16
|
+
info_threads = (execute 'info threads').split("\n")
|
17
|
+
info_threads.each do |thread_info|
|
18
|
+
next unless thread_info =~ /[\s*]*\d+\s+Thread.*/
|
19
|
+
$stdout.puts "thread_info: #{thread_info}"
|
20
|
+
is_main = thread_info[0] == '*'
|
21
|
+
thread_num = thread_info.sub(/[\s*]*/, '').sub(/\s.*$/, '').to_i
|
22
|
+
thread = ProcessThread.new(thread_num, is_main, thread_info, self)
|
23
|
+
if thread.is_main
|
24
|
+
@main_thread = thread
|
25
|
+
end
|
26
|
+
@process_threads << thread
|
27
|
+
end
|
28
|
+
@process_threads
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_already_under_debug
|
32
|
+
threads = execute 'info threads'
|
33
|
+
threads =~ /ruby-debug-ide/
|
34
|
+
end
|
35
|
+
|
36
|
+
def switch_to_thread(thread_num)
|
37
|
+
execute "thread #{thread_num}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_break(str)
|
41
|
+
execute "tbreak #{str}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def call_start_attach
|
45
|
+
super()
|
46
|
+
execute "call dlopen(\"#{@path_to_attach}\", 2)"
|
47
|
+
execute 'call debase_start_attach()'
|
48
|
+
set_break(@tbreak)
|
49
|
+
end
|
50
|
+
|
51
|
+
def print_delimiter
|
52
|
+
@pipe.puts "print \"#{@delimiter}\""
|
53
|
+
end
|
54
|
+
|
55
|
+
def check_delimiter(line)
|
56
|
+
line =~ /\$\d+\s=\s"#{@delimiter}"/
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_debugger
|
60
|
+
execute "call #{@eval_string}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
GDB.to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
class << self
|
68
|
+
def to_s
|
69
|
+
'gdb'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -1,71 +1,71 @@
|
|
1
|
-
require 'ruby-debug-ide/attach/native_debugger'
|
2
|
-
|
3
|
-
class LLDB < NativeDebugger
|
4
|
-
|
5
|
-
def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
6
|
-
super(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
7
|
-
end
|
8
|
-
|
9
|
-
def set_flags
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def update_threads
|
14
|
-
@process_threads = []
|
15
|
-
info_threads = (execute 'thread list').split("\n")
|
16
|
-
info_threads.each do |thread_info|
|
17
|
-
next unless thread_info =~ /[\s*]*thread\s#\d+.*/
|
18
|
-
is_main = thread_info[0] == '*'
|
19
|
-
thread_num = thread_info.sub(/[\s*]*thread\s#/, '').sub(/:\s.*$/, '').to_i
|
20
|
-
thread = ProcessThread.new(thread_num, is_main, thread_info, self)
|
21
|
-
if thread.is_main
|
22
|
-
@main_thread = thread
|
23
|
-
end
|
24
|
-
@process_threads << thread
|
25
|
-
end
|
26
|
-
@process_threads
|
27
|
-
end
|
28
|
-
|
29
|
-
def check_already_under_debug
|
30
|
-
threads = execute 'thread list'
|
31
|
-
threads =~ /ruby-debug-ide/
|
32
|
-
end
|
33
|
-
|
34
|
-
def switch_to_thread(thread_num)
|
35
|
-
execute "thread select #{thread_num}"
|
36
|
-
end
|
37
|
-
|
38
|
-
def set_break(str)
|
39
|
-
execute "breakpoint set --shlib #{@path_to_attach} --name #{str}"
|
40
|
-
end
|
41
|
-
|
42
|
-
def call_start_attach
|
43
|
-
super()
|
44
|
-
execute "expr (void *) dlopen(\"#{@path_to_attach}\", 2)"
|
45
|
-
execute 'expr (int) debase_start_attach()'
|
46
|
-
set_break(@tbreak)
|
47
|
-
end
|
48
|
-
|
49
|
-
def print_delimiter
|
50
|
-
@pipe.puts "script print \"#{@delimiter}\""
|
51
|
-
end
|
52
|
-
|
53
|
-
def check_delimiter(line)
|
54
|
-
line =~ /#{@delimiter}$/
|
55
|
-
end
|
56
|
-
|
57
|
-
def load_debugger
|
58
|
-
execute "expr (void) #{@eval_string}"
|
59
|
-
end
|
60
|
-
|
61
|
-
def to_s
|
62
|
-
LLDB.to_s
|
63
|
-
end
|
64
|
-
|
65
|
-
class << self
|
66
|
-
def to_s
|
67
|
-
'lldb'
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
1
|
+
require 'ruby-debug-ide/attach/native_debugger'
|
2
|
+
|
3
|
+
class LLDB < NativeDebugger
|
4
|
+
|
5
|
+
def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
6
|
+
super(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_flags
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def update_threads
|
14
|
+
@process_threads = []
|
15
|
+
info_threads = (execute 'thread list').split("\n")
|
16
|
+
info_threads.each do |thread_info|
|
17
|
+
next unless thread_info =~ /[\s*]*thread\s#\d+.*/
|
18
|
+
is_main = thread_info[0] == '*'
|
19
|
+
thread_num = thread_info.sub(/[\s*]*thread\s#/, '').sub(/:\s.*$/, '').to_i
|
20
|
+
thread = ProcessThread.new(thread_num, is_main, thread_info, self)
|
21
|
+
if thread.is_main
|
22
|
+
@main_thread = thread
|
23
|
+
end
|
24
|
+
@process_threads << thread
|
25
|
+
end
|
26
|
+
@process_threads
|
27
|
+
end
|
28
|
+
|
29
|
+
def check_already_under_debug
|
30
|
+
threads = execute 'thread list'
|
31
|
+
threads =~ /ruby-debug-ide/
|
32
|
+
end
|
33
|
+
|
34
|
+
def switch_to_thread(thread_num)
|
35
|
+
execute "thread select #{thread_num}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_break(str)
|
39
|
+
execute "breakpoint set --shlib #{@path_to_attach} --name #{str}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def call_start_attach
|
43
|
+
super()
|
44
|
+
execute "expr (void *) dlopen(\"#{@path_to_attach}\", 2)"
|
45
|
+
execute 'expr (int) debase_start_attach()'
|
46
|
+
set_break(@tbreak)
|
47
|
+
end
|
48
|
+
|
49
|
+
def print_delimiter
|
50
|
+
@pipe.puts "script print \"#{@delimiter}\""
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_delimiter(line)
|
54
|
+
line =~ /#{@delimiter}$/
|
55
|
+
end
|
56
|
+
|
57
|
+
def load_debugger
|
58
|
+
execute "expr (void) #{@eval_string}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
LLDB.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
def to_s
|
67
|
+
'lldb'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -1,133 +1,133 @@
|
|
1
|
-
class NativeDebugger
|
2
|
-
|
3
|
-
attr_reader :pid, :main_thread, :process_threads, :pipe
|
4
|
-
|
5
|
-
# @param executable -- path to ruby interpreter
|
6
|
-
# @param pid -- pid of process you want to debug
|
7
|
-
# @param flags -- flags you want to specify to your debugger as a string (e.g. "-nx -nh" for gdb to disable .gdbinit)
|
8
|
-
def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
9
|
-
@pid = pid
|
10
|
-
@delimiter = '__OUTPUT_FINISHED__' # for getting response
|
11
|
-
@tbreak = '__func_to_set_breakpoint_at'
|
12
|
-
@main_thread = nil
|
13
|
-
@process_threads = nil
|
14
|
-
debase_path = gems_to_include.select {|gem_path| gem_path =~ /debase/}
|
15
|
-
if debase_path.size == 0
|
16
|
-
raise 'No debase gem found.'
|
17
|
-
end
|
18
|
-
@path_to_attach = find_attach_lib(debase_path[0])
|
19
|
-
|
20
|
-
@gems_to_include = '["' + gems_to_include * '", "' + '"]'
|
21
|
-
@debugger_loader_path = debugger_loader_path
|
22
|
-
@argv = argv
|
23
|
-
|
24
|
-
@eval_string = "debase_rb_eval(\"require '#{@debugger_loader_path}'; load_debugger(#{@gems_to_include.gsub("\"", "'")}, #{@argv.gsub("\"", "'")})\")"
|
25
|
-
|
26
|
-
launch_string = "#{self} #{executable} #{flags}"
|
27
|
-
@pipe = IO.popen(launch_string, 'r+')
|
28
|
-
$stdout.puts "executed '#{launch_string}'"
|
29
|
-
end
|
30
|
-
|
31
|
-
def find_attach_lib(debase_path)
|
32
|
-
attach_lib = debase_path + '/attach'
|
33
|
-
known_extensions = %w(.so .bundle .dll .dylib)
|
34
|
-
known_extensions.each do |ext|
|
35
|
-
if File.file?(attach_lib + ext)
|
36
|
-
return attach_lib + ext
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
raise 'Could not find attach library'
|
41
|
-
end
|
42
|
-
|
43
|
-
def attach_to_process
|
44
|
-
execute "attach #{@pid}"
|
45
|
-
end
|
46
|
-
|
47
|
-
def execute(command)
|
48
|
-
@pipe.puts command
|
49
|
-
$stdout.puts "executed `#{command}` command inside #{self}."
|
50
|
-
if command == 'q'
|
51
|
-
return ''
|
52
|
-
end
|
53
|
-
get_response
|
54
|
-
end
|
55
|
-
|
56
|
-
def get_response
|
57
|
-
# we need this hack to understand that debugger gave us all output from last executed command
|
58
|
-
print_delimiter
|
59
|
-
|
60
|
-
content = ''
|
61
|
-
loop do
|
62
|
-
line = @pipe.readline
|
63
|
-
DebugPrinter.print_debug('respond line: ' + line)
|
64
|
-
break if check_delimiter(line)
|
65
|
-
next if line =~ /\(lldb\)/ # lldb repeats your input to its output
|
66
|
-
content += line
|
67
|
-
end
|
68
|
-
|
69
|
-
content
|
70
|
-
end
|
71
|
-
|
72
|
-
def update_threads
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
def check_already_under_debug
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
def print_delimiter
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
def check_delimiter(line)
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
def switch_to_thread
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
def set_break(str)
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
def continue
|
97
|
-
$stdout.puts 'continuing'
|
98
|
-
@pipe.puts 'c'
|
99
|
-
loop do
|
100
|
-
line = @pipe.readline
|
101
|
-
DebugPrinter.print_debug('respond line: ' + line)
|
102
|
-
break if line =~ /#{Regexp.escape(@tbreak)}/
|
103
|
-
end
|
104
|
-
get_response
|
105
|
-
end
|
106
|
-
|
107
|
-
def call_start_attach
|
108
|
-
raise 'No main thread found. Did you forget to call `update_threads`?' if @main_thread == nil
|
109
|
-
@main_thread.switch
|
110
|
-
end
|
111
|
-
|
112
|
-
def wait_line_event
|
113
|
-
call_start_attach
|
114
|
-
continue
|
115
|
-
end
|
116
|
-
|
117
|
-
def load_debugger
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
def exited?
|
122
|
-
@pipe.closed?
|
123
|
-
end
|
124
|
-
|
125
|
-
def exit
|
126
|
-
@pipe.close
|
127
|
-
end
|
128
|
-
|
129
|
-
def to_s
|
130
|
-
'native_debugger'
|
131
|
-
end
|
132
|
-
|
133
|
-
end
|
1
|
+
class NativeDebugger
|
2
|
+
|
3
|
+
attr_reader :pid, :main_thread, :process_threads, :pipe
|
4
|
+
|
5
|
+
# @param executable -- path to ruby interpreter
|
6
|
+
# @param pid -- pid of process you want to debug
|
7
|
+
# @param flags -- flags you want to specify to your debugger as a string (e.g. "-nx -nh" for gdb to disable .gdbinit)
|
8
|
+
def initialize(executable, pid, flags, gems_to_include, debugger_loader_path, argv)
|
9
|
+
@pid = pid
|
10
|
+
@delimiter = '__OUTPUT_FINISHED__' # for getting response
|
11
|
+
@tbreak = '__func_to_set_breakpoint_at'
|
12
|
+
@main_thread = nil
|
13
|
+
@process_threads = nil
|
14
|
+
debase_path = gems_to_include.select {|gem_path| gem_path =~ /debase/}
|
15
|
+
if debase_path.size == 0
|
16
|
+
raise 'No debase gem found.'
|
17
|
+
end
|
18
|
+
@path_to_attach = find_attach_lib(debase_path[0])
|
19
|
+
|
20
|
+
@gems_to_include = '["' + gems_to_include * '", "' + '"]'
|
21
|
+
@debugger_loader_path = debugger_loader_path
|
22
|
+
@argv = argv
|
23
|
+
|
24
|
+
@eval_string = "debase_rb_eval(\"require '#{@debugger_loader_path}'; load_debugger(#{@gems_to_include.gsub("\"", "'")}, #{@argv.gsub("\"", "'")})\")"
|
25
|
+
|
26
|
+
launch_string = "#{self} #{executable} #{flags}"
|
27
|
+
@pipe = IO.popen(launch_string, 'r+')
|
28
|
+
$stdout.puts "executed '#{launch_string}'"
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_attach_lib(debase_path)
|
32
|
+
attach_lib = debase_path + '/attach'
|
33
|
+
known_extensions = %w(.so .bundle .dll .dylib)
|
34
|
+
known_extensions.each do |ext|
|
35
|
+
if File.file?(attach_lib + ext)
|
36
|
+
return attach_lib + ext
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
raise 'Could not find attach library'
|
41
|
+
end
|
42
|
+
|
43
|
+
def attach_to_process
|
44
|
+
execute "attach #{@pid}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def execute(command)
|
48
|
+
@pipe.puts command
|
49
|
+
$stdout.puts "executed `#{command}` command inside #{self}."
|
50
|
+
if command == 'q'
|
51
|
+
return ''
|
52
|
+
end
|
53
|
+
get_response
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_response
|
57
|
+
# we need this hack to understand that debugger gave us all output from last executed command
|
58
|
+
print_delimiter
|
59
|
+
|
60
|
+
content = ''
|
61
|
+
loop do
|
62
|
+
line = @pipe.readline
|
63
|
+
DebugPrinter.print_debug('respond line: ' + line)
|
64
|
+
break if check_delimiter(line)
|
65
|
+
next if line =~ /\(lldb\)/ # lldb repeats your input to its output
|
66
|
+
content += line
|
67
|
+
end
|
68
|
+
|
69
|
+
content
|
70
|
+
end
|
71
|
+
|
72
|
+
def update_threads
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
def check_already_under_debug
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def print_delimiter
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_delimiter(line)
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def switch_to_thread
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_break(str)
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
def continue
|
97
|
+
$stdout.puts 'continuing'
|
98
|
+
@pipe.puts 'c'
|
99
|
+
loop do
|
100
|
+
line = @pipe.readline
|
101
|
+
DebugPrinter.print_debug('respond line: ' + line)
|
102
|
+
break if line =~ /#{Regexp.escape(@tbreak)}/
|
103
|
+
end
|
104
|
+
get_response
|
105
|
+
end
|
106
|
+
|
107
|
+
def call_start_attach
|
108
|
+
raise 'No main thread found. Did you forget to call `update_threads`?' if @main_thread == nil
|
109
|
+
@main_thread.switch
|
110
|
+
end
|
111
|
+
|
112
|
+
def wait_line_event
|
113
|
+
call_start_attach
|
114
|
+
continue
|
115
|
+
end
|
116
|
+
|
117
|
+
def load_debugger
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
def exited?
|
122
|
+
@pipe.closed?
|
123
|
+
end
|
124
|
+
|
125
|
+
def exit
|
126
|
+
@pipe.close
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_s
|
130
|
+
'native_debugger'
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
@@ -1,54 +1,54 @@
|
|
1
|
-
require 'ruby-debug-ide/attach/native_debugger'
|
2
|
-
|
3
|
-
class ProcessThread
|
4
|
-
|
5
|
-
attr_reader :thread_num, :is_main, :thread_info, :last_bt
|
6
|
-
|
7
|
-
def initialize(thread_num, is_main, thread_info, native_debugger)
|
8
|
-
@thread_num = thread_num
|
9
|
-
@is_main = is_main
|
10
|
-
@native_debugger = native_debugger
|
11
|
-
@thread_info = thread_info
|
12
|
-
@last_bt = nil
|
13
|
-
end
|
14
|
-
|
15
|
-
def switch
|
16
|
-
@native_debugger.switch_to_thread(thread_num)
|
17
|
-
end
|
18
|
-
|
19
|
-
def finish
|
20
|
-
@native_debugger.execute 'finish'
|
21
|
-
end
|
22
|
-
|
23
|
-
def get_bt
|
24
|
-
@last_bt = @native_debugger.execute 'bt'
|
25
|
-
end
|
26
|
-
|
27
|
-
def any_caller_match(bt, pattern)
|
28
|
-
bt =~ /#{pattern}/
|
29
|
-
end
|
30
|
-
|
31
|
-
def is_inside_malloc(bt = get_bt)
|
32
|
-
if any_caller_match(bt, '(malloc)')
|
33
|
-
$stderr.puts "process #{@native_debugger.pid} is currently inside malloc."
|
34
|
-
true
|
35
|
-
else
|
36
|
-
false
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def is_inside_gc(bt = get_bt)
|
41
|
-
if any_caller_match(bt, '(gc\.c)')
|
42
|
-
$stderr.puts "process #{@native_debugger.pid} is currently in garbage collection phase."
|
43
|
-
true
|
44
|
-
else
|
45
|
-
false
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def need_finish_frame
|
50
|
-
bt = get_bt
|
51
|
-
is_inside_malloc(bt) || is_inside_gc(bt)
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
1
|
+
require 'ruby-debug-ide/attach/native_debugger'
|
2
|
+
|
3
|
+
class ProcessThread
|
4
|
+
|
5
|
+
attr_reader :thread_num, :is_main, :thread_info, :last_bt
|
6
|
+
|
7
|
+
def initialize(thread_num, is_main, thread_info, native_debugger)
|
8
|
+
@thread_num = thread_num
|
9
|
+
@is_main = is_main
|
10
|
+
@native_debugger = native_debugger
|
11
|
+
@thread_info = thread_info
|
12
|
+
@last_bt = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def switch
|
16
|
+
@native_debugger.switch_to_thread(thread_num)
|
17
|
+
end
|
18
|
+
|
19
|
+
def finish
|
20
|
+
@native_debugger.execute 'finish'
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_bt
|
24
|
+
@last_bt = @native_debugger.execute 'bt'
|
25
|
+
end
|
26
|
+
|
27
|
+
def any_caller_match(bt, pattern)
|
28
|
+
bt =~ /#{pattern}/
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_inside_malloc(bt = get_bt)
|
32
|
+
if any_caller_match(bt, '(malloc)')
|
33
|
+
$stderr.puts "process #{@native_debugger.pid} is currently inside malloc."
|
34
|
+
true
|
35
|
+
else
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_inside_gc(bt = get_bt)
|
41
|
+
if any_caller_match(bt, '(gc\.c)')
|
42
|
+
$stderr.puts "process #{@native_debugger.pid} is currently in garbage collection phase."
|
43
|
+
true
|
44
|
+
else
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def need_finish_frame
|
50
|
+
bt = get_bt
|
51
|
+
is_inside_malloc(bt) || is_inside_gc(bt)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|