ruby-debug-ide22 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +75 -75
  3. data/ChangeLog.archive +1073 -1073
  4. data/ChangeLog.md +594 -594
  5. data/Gemfile +38 -38
  6. data/MIT-LICENSE +24 -24
  7. data/Rakefile +92 -92
  8. data/bin/gdb_wrapper +96 -96
  9. data/bin/rdebug-ide +200 -200
  10. data/ext/mkrf_conf.rb +44 -44
  11. data/lib/ruby-debug-ide/attach/debugger_loader.rb +20 -20
  12. data/lib/ruby-debug-ide/attach/gdb.rb +73 -73
  13. data/lib/ruby-debug-ide/attach/lldb.rb +71 -71
  14. data/lib/ruby-debug-ide/attach/native_debugger.rb +133 -133
  15. data/lib/ruby-debug-ide/attach/process_thread.rb +54 -54
  16. data/lib/ruby-debug-ide/attach/util.rb +114 -114
  17. data/lib/ruby-debug-ide/command.rb +187 -187
  18. data/lib/ruby-debug-ide/commands/breakpoints.rb +128 -128
  19. data/lib/ruby-debug-ide/commands/catchpoint.rb +64 -64
  20. data/lib/ruby-debug-ide/commands/condition.rb +51 -51
  21. data/lib/ruby-debug-ide/commands/control.rb +164 -158
  22. data/lib/ruby-debug-ide/commands/enable.rb +203 -203
  23. data/lib/ruby-debug-ide/commands/eval.rb +64 -64
  24. data/lib/ruby-debug-ide/commands/expression_info.rb +71 -71
  25. data/lib/ruby-debug-ide/commands/file_filtering.rb +106 -106
  26. data/lib/ruby-debug-ide/commands/frame.rb +155 -155
  27. data/lib/ruby-debug-ide/commands/inspect.rb +25 -25
  28. data/lib/ruby-debug-ide/commands/load.rb +17 -17
  29. data/lib/ruby-debug-ide/commands/stepping.rb +108 -108
  30. data/lib/ruby-debug-ide/commands/threads.rb +178 -178
  31. data/lib/ruby-debug-ide/commands/variables.rb +154 -154
  32. data/lib/ruby-debug-ide/event_processor.rb +71 -71
  33. data/lib/ruby-debug-ide/greeter.rb +42 -42
  34. data/lib/ruby-debug-ide/helper.rb +33 -33
  35. data/lib/ruby-debug-ide/ide_processor.rb +155 -155
  36. data/lib/ruby-debug-ide/interface.rb +47 -45
  37. data/lib/ruby-debug-ide/multiprocess/monkey.rb +46 -46
  38. data/lib/ruby-debug-ide/multiprocess/pre_child.rb +58 -58
  39. data/lib/ruby-debug-ide/multiprocess/starter.rb +10 -10
  40. data/lib/ruby-debug-ide/multiprocess/unmonkey.rb +30 -30
  41. data/lib/ruby-debug-ide/multiprocess.rb +22 -22
  42. data/lib/ruby-debug-ide/thread_alias.rb +26 -26
  43. data/lib/ruby-debug-ide/version.rb +3 -3
  44. data/lib/ruby-debug-ide/xml_printer.rb +570 -570
  45. data/lib/ruby-debug-ide.rb +230 -228
  46. data/ruby-debug-ide.gemspec +47 -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