hijack 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/hijack.rb +1 -1
  2. data/lib/hijack/gdb.rb +28 -18
  3. metadata +4 -4
data/lib/hijack.rb CHANGED
@@ -31,6 +31,6 @@ module Hijack
31
31
  end
32
32
 
33
33
  def self.version
34
- "0.2.0"
34
+ "0.2.1"
35
35
  end
36
36
  end
data/lib/hijack/gdb.rb CHANGED
@@ -25,7 +25,7 @@ module Hijack
25
25
  protected
26
26
 
27
27
  def previous_frame_inner_to_this_frame?
28
- backtrace.first =~ /previous frame inner to this frame/i
28
+ backtrace.last =~ /previous frame inner to this frame/i
29
29
  end
30
30
 
31
31
  def attach_outside_gc
@@ -53,30 +53,40 @@ module Hijack
53
53
  exit 1
54
54
  end
55
55
 
56
- # TODO: Check for "Unable to attach to process-id 44528: No child processes (10)"
57
- ensure_main_thread_not_blocked_by_join
56
+ break_on_safe_stack_unwind
58
57
  end
59
-
58
+
59
+ def break_on_safe_stack_unwind
60
+ safe = false
61
+ backtrace.each do |line|
62
+ # vm_call_method == 1.9, rb_call == 1.8
63
+ if line =~ /(vm_call_method|rb_call)/
64
+ frame = line.match(/^\#([\d]+)/)[1]
65
+ safe = true
66
+ exec("frame #{frame}")
67
+ exec("break")
68
+ exec("continue")
69
+ exec("delete 1")
70
+ break
71
+ end
72
+ end
73
+
74
+ if !safe
75
+ puts "=> WARNING: Did not detect a safe frame on which to set a breakpoint, hijack may fail."
76
+ end
77
+ end
78
+
60
79
  def during_gc?
61
80
  !!(call("(int)rb_during_gc()").first =~ /\$[\d]+ = 1/)
62
81
  end
63
-
82
+
64
83
  def detach
65
84
  exec("detach")
66
85
  end
67
-
86
+
68
87
  def attach
69
88
  exec("attach #{@pid}")
70
89
  end
71
-
72
- def ensure_main_thread_not_blocked_by_join
73
- if backtrace.any? { |line| line =~ /rb_thread_join/ }
74
- puts "\n=> Unable to hijack #{@pid} because the main thread is blocked waiting for another thread to join."
75
- puts "=> Check that you are using the most recent version of hijack, a newer version may have solved this shortcoming."
76
- detach
77
- exit 1
78
- end
79
- end
80
90
 
81
91
  def ensure_attached_to_ruby_process
82
92
  unless backtrace.any? {|line| line =~ /(rb|ruby)_/}
@@ -87,7 +97,7 @@ module Hijack
87
97
  end
88
98
 
89
99
  def backtrace
90
- @backtrace ||= exec('bt').reverse
100
+ @backtrace ||= exec('bt')
91
101
  end
92
102
 
93
103
  def continue
@@ -99,7 +109,7 @@ module Hijack
99
109
  end
100
110
 
101
111
  def exec(str)
102
- puts("(gdb) #{str}") if @verbose
112
+ puts str if @verbose
103
113
  @gdb.puts(str)
104
114
  wait
105
115
  end
@@ -111,6 +121,7 @@ module Hijack
111
121
  next if result.empty?
112
122
  c = @gdb.read(1)
113
123
  break if c.nil?
124
+ STDOUT.write(c) if @verbose
114
125
  line << c
115
126
  break if line == "(gdb) " || line == " >"
116
127
  if line[-1] == ?\n
@@ -118,7 +129,6 @@ module Hijack
118
129
  line = ""
119
130
  end
120
131
  end
121
- puts lines.map { |l| "> #{l}" } if @verbose
122
132
  lines
123
133
  end
124
134
  end
metadata CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ian Leitch
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-18 00:00:00 +11:00
18
+ date: 2011-02-17 05:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  requirements: []
76
76
 
77
77
  rubyforge_project:
78
- rubygems_version: 1.3.7
78
+ rubygems_version: 1.6.2
79
79
  signing_key:
80
80
  specification_version: 3
81
81
  summary: Provides an irb session to a running ruby process.