hijack 0.2.0 → 0.2.1

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.
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.