hijack 0.2.0.rc1 → 0.2.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -119,3 +119,7 @@ DRb cannot dump objects to the hijack client for types that are not loaded in th
119
119
  isn't loaded in the hijack client.
120
120
 
121
121
  To work around this, when hijack connects to a remote process it will inspect all the files required by the process and also attempt to require them itself. This may not work for all object types however so you may still get a warning when an object cannot be dumped.
122
+
123
+ == Contributors
124
+
125
+ * jugyo (十行) (https://github.com/jugyo)
data/lib/hijack/gdb.rb CHANGED
@@ -6,16 +6,16 @@ module Hijack
6
6
  @pid = pid
7
7
  @verbose = Hijack.options[:debug]
8
8
  @exec_path = File.join(Config::CONFIG['bindir'], Config::CONFIG['RUBY_INSTALL_NAME'] + Config::CONFIG['EXEEXT'])
9
- attach
9
+ attach_outside_gc
10
10
  end
11
11
 
12
12
  def eval(cmd)
13
13
  call("(void)rb_eval_string(#{cmd.strip.gsub(/"/, '\"').inspect})")
14
14
  end
15
15
 
16
- def detach
16
+ def quit
17
17
  return unless @gdb
18
- exec('detach')
18
+ detach
19
19
  exec('quit')
20
20
  @backtrace = nil
21
21
  @gdb.close
@@ -24,35 +24,53 @@ module Hijack
24
24
 
25
25
  protected
26
26
 
27
- def attach
28
- loop do
29
- @gdb = IO.popen("gdb -q #{@exec_path} #{@pid} 2>&1", 'r+')
30
- wait
31
- if backtrace.first =~ /previous frame inner to this frame/i
27
+ def previous_frame_inner_to_this_frame?
28
+ backtrace.first =~ /previous frame inner to this frame/i
29
+ end
30
+
31
+ def attach_outside_gc
32
+ @gdb = IO.popen("gdb -q #{@exec_path} #{@pid} 2>&1", 'r+')
33
+ wait
34
+ ensure_attached_to_ruby_process
35
+ attached = false
36
+
37
+ 3.times do |i|
38
+ attach unless i == 0
39
+
40
+ if previous_frame_inner_to_this_frame? || during_gc?
32
41
  detach
33
42
  sleep 0.1
34
43
  else
44
+ attached = true
35
45
  break
36
46
  end
37
47
  end
38
-
48
+
49
+ unless attached
50
+ puts
51
+ puts "=> Tried 3 times to attach to #{@pid} whilst GC wasn't running but failed."
52
+ puts "=> This means either the process calls GC.start frequently or its GC runs are slow - try hijacking again."
53
+ exit 1
54
+ end
55
+
39
56
  # TODO: Check for "Unable to attach to process-id 44528: No child processes (10)"
40
57
  ensure_main_thread_not_blocked_by_join
41
- set_breakpoint
42
- continue
43
- delete_breakpoint
44
58
  end
45
59
 
46
- def set_breakpoint
47
- exec("break rb_call")
60
+ def during_gc?
61
+ backtrace.any? { |line| line =~ /garbage_collect/i }
48
62
  end
49
-
50
- def delete_breakpoint
51
- exec("delete breakpoints")
63
+
64
+ def detach
65
+ exec("detach")
52
66
  end
53
-
67
+
68
+ def attach
69
+ exec("attach #{@pid}")
70
+ end
71
+
54
72
  def ensure_main_thread_not_blocked_by_join
55
- if backtrace.any? {|line| line =~ /rb_thread_join/}
73
+ if backtrace.any? { |line| line =~ /rb_thread_join/ }
56
74
  puts "\n=> Unable to hijack #{@pid} because the main thread is blocked waiting for another thread to join."
57
75
  puts "=> Check that you are using the most recent version of hijack, a newer version may have solved this shortcoming."
58
76
  detach
@@ -8,7 +8,7 @@ module Hijack
8
8
  end
9
9
  gdb = GDB.new(pid)
10
10
  gdb.eval(payload(pid))
11
- gdb.detach
11
+ gdb.quit
12
12
  exit if @received_sigint
13
13
  end
14
14
 
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.rc1"
34
+ "0.2.0.rc2"
35
35
  end
36
36
  end
data/tasks/gem.rake CHANGED
@@ -1,18 +1,17 @@
1
1
  require 'rake/gempackagetask'
2
2
  require 'yaml'
3
-
4
- HIJACK_VERSION = '0.1.9'
3
+ require './lib/hijack'
5
4
 
6
5
  task :clean => :clobber_package
7
6
 
8
7
  spec = Gem::Specification.new do |s|
9
8
  s.name = 'hijack'
10
- s.version = HIJACK_VERSION
9
+ s.version = Hijack.version
11
10
  s.platform = Gem::Platform::RUBY
12
11
  s.summary =
13
- s.description = 'Provides an irb session to an existing ruby process.'
12
+ s.description = 'Provides an irb session to a running ruby process.'
14
13
  s.author = "Ian Leitch"
15
- s.email = 'ian.leitch@systino.net'
14
+ s.email = 'port001@gmail.com'
16
15
  s.homepage = 'http://github.com/ileitch/hijack'
17
16
  s.has_rdoc = false
18
17
  s.files = %w(COPYING TODO README.rdoc Rakefile) + Dir.glob("{lib,test,tasks,bin,examples}/**/*")
@@ -26,8 +25,8 @@ Rake::GemPackageTask.new(spec) do |p|
26
25
  end
27
26
 
28
27
  namespace :gem do
29
- desc "Update the gemspec for GitHub's gem server"
30
- task :github do
28
+ desc "Update the gemspec"
29
+ task :spec do
31
30
  File.open("hijack.gemspec", 'w') { |f| f << YAML.dump(spec) }
32
31
  end
33
32
  end
data/test/gc.rb CHANGED
@@ -7,7 +7,7 @@ class MyObject
7
7
  end
8
8
 
9
9
  puts Process.pid
10
- n = 0
10
+ n = 10000
11
11
  loop do
12
12
  (n+=1).times {|i| MyObject.new(i)}
13
13
  GC.start
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hijack
3
3
  version: !ruby/object:Gem::Version
4
- hash: 977940574
4
+ hash: 977940575
5
+ prerelease: true
5
6
  segments:
6
7
  - 0
7
8
  - 2
8
9
  - 0
9
- - rc1
10
- version: 0.2.0.rc1
10
+ - rc2
11
+ version: 0.2.0.rc2
11
12
  platform: ruby
12
13
  authors:
13
14
  - Ian Leitch
@@ -15,11 +16,11 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2009-09-20 14:00:00 +10:00
19
+ date: 2010-11-26 00:00:00 +11:00
19
20
  default_executable:
20
21
  dependencies: []
21
22
 
22
- description: Provides an irb session to an existing ruby process.
23
+ description: Provides an irb session to a running ruby process.
23
24
  email: port001@gmail.com
24
25
  executables:
25
26
  - hijack
@@ -35,9 +36,9 @@ files:
35
36
  - lib/hijack/console.rb
36
37
  - lib/hijack/gdb.rb
37
38
  - lib/hijack/helper.rb
39
+ - lib/hijack/output_receiver.rb
38
40
  - lib/hijack/payload.rb
39
41
  - lib/hijack/workspace.rb
40
- - lib/hijack/output_receiver.rb
41
42
  - lib/hijack.rb
42
43
  - test/app.rb
43
44
  - test/gc.rb
@@ -55,6 +56,7 @@ rdoc_options: []
55
56
  require_paths:
56
57
  - lib
57
58
  required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
58
60
  requirements:
59
61
  - - ">="
60
62
  - !ruby/object:Gem::Version
@@ -62,22 +64,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
62
64
  segments:
63
65
  - 0
64
66
  version: "0"
65
- version:
66
67
  required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
67
69
  requirements:
68
- - - ">="
70
+ - - ">"
69
71
  - !ruby/object:Gem::Version
70
- hash: 3
72
+ hash: 25
71
73
  segments:
72
- - 0
73
- version: "0"
74
- version:
74
+ - 1
75
+ - 3
76
+ - 1
77
+ version: 1.3.1
75
78
  requirements: []
76
79
 
77
80
  rubyforge_project:
78
81
  rubygems_version: 1.3.7
79
82
  signing_key:
80
83
  specification_version: 3
81
- summary: Provides an irb session to an existing ruby process.
84
+ summary: Provides an irb session to a running ruby process.
82
85
  test_files: []
83
86