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 +4 -0
- data/lib/hijack/gdb.rb +37 -19
- data/lib/hijack/payload.rb +1 -1
- data/lib/hijack.rb +1 -1
- data/tasks/gem.rake +6 -7
- data/test/gc.rb +1 -1
- metadata +16 -13
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
|
-
|
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
|
16
|
+
def quit
|
17
17
|
return unless @gdb
|
18
|
-
|
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
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
47
|
-
|
60
|
+
def during_gc?
|
61
|
+
backtrace.any? { |line| line =~ /garbage_collect/i }
|
48
62
|
end
|
49
|
-
|
50
|
-
def
|
51
|
-
exec("
|
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
|
data/lib/hijack/payload.rb
CHANGED
data/lib/hijack.rb
CHANGED
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 =
|
9
|
+
s.version = Hijack.version
|
11
10
|
s.platform = Gem::Platform::RUBY
|
12
11
|
s.summary =
|
13
|
-
s.description = 'Provides an irb session to
|
12
|
+
s.description = 'Provides an irb session to a running ruby process.'
|
14
13
|
s.author = "Ian Leitch"
|
15
|
-
s.email = '
|
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
|
30
|
-
task :
|
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
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:
|
4
|
+
hash: 977940575
|
5
|
+
prerelease: true
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 2
|
8
9
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.2.0.
|
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:
|
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
|
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:
|
72
|
+
hash: 25
|
71
73
|
segments:
|
72
|
-
-
|
73
|
-
|
74
|
-
|
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
|
84
|
+
summary: Provides an irb session to a running ruby process.
|
82
85
|
test_files: []
|
83
86
|
|