memprof 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -123,7 +123,7 @@ hook_freelist(int entry, void *tramp)
123
123
  void
124
124
  insert_tramp(const char *trampee, void *tramp)
125
125
  {
126
- void *trampee_addr = bin_find_symbol(trampee, NULL);
126
+ void *trampee_addr = bin_find_symbol(trampee, NULL, 0);
127
127
  int inline_ent = inline_tramp_size;
128
128
 
129
129
  if (trampee_addr == NULL) {
@@ -136,7 +136,7 @@ insert_tramp(const char *trampee, void *tramp)
136
136
  }
137
137
  } else {
138
138
  tramp_table[tramp_size].addr = tramp;
139
- if (bin_update_image(trampee, &tramp_table[tramp_size]) != 0)
139
+ if (bin_update_image(trampee, &tramp_table[tramp_size], NULL) != 0)
140
140
  errx(EX_SOFTWARE, "Failed to insert tramp for %s", trampee);
141
141
  tramp_size++;
142
142
  }
data/ext/util.c CHANGED
@@ -3,6 +3,7 @@
3
3
  * information and a checksum.
4
4
  */
5
5
  #include <stdlib.h>
6
+ #include <util.h>
6
7
  /* !!!! DO NOT MODIFY THIS FUNCTION !!!!
7
8
  * TODO create specs for this!
8
9
  */
data/ext/util.h CHANGED
@@ -13,20 +13,52 @@
13
13
  struct memprof_config {
14
14
  void *gc_sweep;
15
15
  size_t gc_sweep_size;
16
+
16
17
  void *finalize_list;
17
18
  size_t finalize_list_size;
19
+
18
20
  void *rb_gc_force_recycle;
19
21
  size_t rb_gc_force_recycle_size;
22
+
20
23
  void *freelist;
21
24
  void *classname;
22
25
  void *add_freelist;
26
+ void *timeofday;
27
+
23
28
  void *rb_mark_table_add_filename;
29
+
30
+ void *bm_mark;
31
+ void *blk_free;
32
+ void *thread_mark;
33
+
24
34
  void *heaps;
25
35
  void *heaps_used;
36
+
26
37
  size_t sizeof_RVALUE;
27
38
  size_t sizeof_heaps_slot;
28
- int offset_heaps_slot_limit;
29
- int offset_heaps_slot_slot;
39
+
40
+ size_t offset_heaps_slot_limit;
41
+ size_t offset_heaps_slot_slot;
42
+
43
+ size_t offset_BLOCK_body;
44
+ size_t offset_BLOCK_var;
45
+ size_t offset_BLOCK_cref;
46
+ size_t offset_BLOCK_prev;
47
+ size_t offset_BLOCK_self;
48
+ size_t offset_BLOCK_klass;
49
+ size_t offset_BLOCK_wrapper;
50
+ size_t offset_BLOCK_orig_thread;
51
+ size_t offset_BLOCK_block_obj;
52
+ size_t offset_BLOCK_scope;
53
+ size_t offset_BLOCK_dyna_vars;
54
+
55
+ size_t offset_METHOD_klass;
56
+ size_t offset_METHOD_rklass;
57
+ size_t offset_METHOD_recv;
58
+ size_t offset_METHOD_id;
59
+ size_t offset_METHOD_oid;
60
+ size_t offset_METHOD_body;
61
+
30
62
  size_t pagesize;
31
63
  };
32
64
 
@@ -0,0 +1,16 @@
1
+ begin
2
+ require File.expand_path('../../memprof', __FILE__)
3
+ rescue LoadError
4
+ require File.expand_path('../../../ext/memprof', __FILE__)
5
+ end
6
+
7
+ Memprof.start
8
+ old_handler = trap('URG'){
9
+ pid = Process.pid
10
+ fork{
11
+ GC.start
12
+ Memprof.dump_all("/tmp/memprof-#{pid}-#{Time.now.to_i}.json")
13
+ exit!
14
+ }
15
+ old_handler.call if old_handler
16
+ }
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'memprof'
3
- s.version = '0.2.9'
3
+ s.version = '0.3.0'
4
4
  s.date = '2010-03-15'
5
5
  s.summary = 'Ruby Memory Profiler'
6
6
  s.description = "Ruby memory profiler similar to bleak_house, but without patches to the Ruby VM"
@@ -9,5 +9,9 @@ spec = Gem::Specification.new do |s|
9
9
  s.authors = ["Joe Damato", "Aman Gupta", "Jake Douglas", "Rob Benson"]
10
10
  s.email = ["joe@memprof.com", "aman@memprof.com", "jake@memprof.com"]
11
11
  s.extensions = "ext/extconf.rb"
12
+ s.bindir = 'bin'
13
+ s.executables << 'memprof'
12
14
  s.files = `git ls-files`.split
15
+ s.add_dependency('rest-client', '>= 1.4.2')
16
+ s.add_dependency('term-ansicolor')
13
17
  end
@@ -76,7 +76,7 @@ describe Memprof do
76
76
  Memprof.stop
77
77
  Memprof.dump_all(filename)
78
78
 
79
- obj = File.open(filename, 'r').each_line.find do |line|
79
+ obj = File.open(filename, 'r').readlines.find do |line|
80
80
  line =~ /"dump out the entire heap"/
81
81
  end
82
82
 
@@ -90,7 +90,7 @@ describe Memprof do
90
90
  @str = "some random" + " string"
91
91
  Memprof.dump_all(filename)
92
92
 
93
- obj = File.open(filename, 'r').each_line.find do |line|
93
+ obj = File.open(filename, 'r').readlines.find do |line|
94
94
  line =~ /"some random string"/
95
95
  end
96
96
 
@@ -0,0 +1,117 @@
1
+ require 'rubygems'
2
+ require 'bacon'
3
+ Bacon.summary_on_exit
4
+
5
+ describe "MemprofUploader" do
6
+
7
+ it "should display help output with -h" do
8
+ output = `ruby bin/memprof -h`
9
+ output.should =~ /Memprof Uploader/
10
+ output.should =~ /Usage:/
11
+ $?.exitstatus.should == 0
12
+ end
13
+
14
+ it "should fail without a pid being passed" do
15
+ output = `ruby bin/memprof -n SomeLabel -k abcdef`
16
+ output.should =~ /Missing PID!/
17
+ $?.exitstatus.should == 1
18
+ end
19
+
20
+ it "should fail without a name being passed" do
21
+ output = `ruby bin/memprof -p 123 -k abcdef`
22
+ output.should =~ /Missing name!/
23
+ $?.exitstatus.should == 1
24
+ end
25
+
26
+ it "should fail without an API key" do
27
+ output = `ruby bin/memprof -p 123 -n SomeLabel`
28
+ output.should =~ /Missing API key!/
29
+ $?.exitstatus.should == 1
30
+ end
31
+
32
+ it "should fail with an invalid pid" do
33
+ output = `ruby bin/memprof -p 99999999 -n Label -k abcdef`
34
+ output.should =~ Regexp.new("No such process 99999999!")
35
+ $?.exitstatus.should == 1
36
+ end
37
+
38
+ it "should fail when the target process does not create a new file within 5 sec" do
39
+ pid = fork { sleep 5; exit! }
40
+ Process.detach(pid)
41
+ output = `ruby bin/memprof -p #{pid} -n Label -k abcdef`
42
+ output.should =~ Regexp.new("Waiting 5 seconds for process #{pid} to create a new dump...")
43
+ output.should =~ Regexp.new("Timed out after waiting 5 seconds")
44
+ $?.exitstatus.should == 1
45
+ end
46
+
47
+ it "should WORK and wait for a dump to complete if it's IN_PROGRESS" do
48
+ pid = fork {
49
+ # create a fake file
50
+ filename = "/tmp/memprof-#{Process.pid}-#{Time.now.to_i}.json.IN_PROGRESS"
51
+ # simulate dump in progress
52
+ trap("URG") { File.open(filename, "w") {|f| f.write("foo") }; sleep 1 }
53
+ # should get signaled somewhere in here and execute the handler before exiting.
54
+ sleep 5
55
+ # rename the file to simulate completion of the dump writeout.
56
+ File.rename(filename, filename.sub(/\.IN_PROGRESS/, ""))
57
+ exit!
58
+ }
59
+ Process.detach(pid)
60
+ output = `ruby bin/memprof -p #{pid} -n Label -k abcdef -t`
61
+ output.should =~ Regexp.new("Waiting 5 seconds for process #{pid} to create a new dump...")
62
+ output.should =~ Regexp.new("Found file /tmp/memprof-#{pid}-\\d*.json\\.?\\w*")
63
+ output.should =~ Regexp.new("Dump in progress. Waiting 60 seconds for it to complete...")
64
+ output.should =~ Regexp.new("Finished!")
65
+ file = output.slice(Regexp.new("/tmp/memprof-#{pid}-\\d*.json\\.?\\w*"))
66
+ # make sure both files are gone
67
+ File.exist?(file).should == false
68
+ File.exist?(file.sub(/\.IN_PROGRESS/, "") + ".gz").should == false
69
+ $?.exitstatus.should == 0
70
+ end
71
+
72
+ it "should WORK and delete the dump file after it's done, by default" do
73
+ pid = fork {
74
+ require File.dirname(__FILE__) + "/../lib/memprof/signal"
75
+ # should get signaled somewhere in here and execute the handler before exiting.
76
+ sleep 5
77
+ exit!
78
+ }
79
+ Process.detach(pid)
80
+ sleep 2
81
+ output = `ruby bin/memprof -p #{pid} -n TestDump -k abcdef -t`
82
+ output.should =~ Regexp.new("Waiting 5 seconds for process #{pid} to create a new dump...")
83
+ output.should =~ Regexp.new("Found file /tmp/memprof-#{pid}-\\d*.json\\.?\\w*")
84
+ output.should =~ Regexp.new("Finished!")
85
+ file = output.slice(Regexp.new("/tmp/memprof-#{pid}-\\d*.json\\.?\\w*"))
86
+ # make sure both files are gone
87
+ File.exist?(file).should == false
88
+ File.exist?(file.sub(/\.IN_PROGRESS/, "") + ".gz").should == false
89
+ $?.exitstatus.should == 0
90
+ end
91
+
92
+ it "should WORK and leave the dump file after it's done, with --no-delete" do
93
+ pid = fork {
94
+ require File.dirname(__FILE__) + "/../lib/memprof/signal"
95
+ # should get signaled somewhere in here and execute the handler before exiting.
96
+ sleep 5
97
+ exit!
98
+ }
99
+ Process.detach(pid)
100
+ sleep 2
101
+ output = `ruby bin/memprof -p #{pid} -n TestDump -k abcdef -t --no-delete`
102
+ output.should =~ Regexp.new("Waiting 5 seconds for process #{pid} to create a new dump...")
103
+ output.should =~ Regexp.new("Found file /tmp/memprof-#{pid}-\\d*.json\\w*")
104
+ output.should =~ Regexp.new("Finished!")
105
+ file = output.slice(Regexp.new("/tmp/memprof-#{pid}-\\d*.json\\.?\\w*"))
106
+ # Make sure it deleted the temporary one
107
+ if file =~ /\.IN_PROGRESS/
108
+ File.exist?(file).should == false
109
+ end
110
+ # make sure it left the completed one
111
+ file = file.sub(/\.IN_PROGRESS/, "") + ".gz"
112
+ File.exist?(file).should == true
113
+ File.delete(file)
114
+ $?.exitstatus.should == 0
115
+ end
116
+
117
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 9
9
- version: 0.2.9
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joe Damato
@@ -19,15 +19,40 @@ cert_chain: []
19
19
 
20
20
  date: 2010-03-15 00:00:00 -07:00
21
21
  default_executable:
22
- dependencies: []
23
-
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: rest-client
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ segments:
31
+ - 1
32
+ - 4
33
+ - 2
34
+ version: 1.4.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: term-ansicolor
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
24
49
  description: Ruby memory profiler similar to bleak_house, but without patches to the Ruby VM
25
50
  email:
26
51
  - joe@memprof.com
27
52
  - aman@memprof.com
28
53
  - jake@memprof.com
29
- executables: []
30
-
54
+ executables:
55
+ - memprof
31
56
  extensions:
32
57
  - ext/extconf.rb
33
58
  extra_rdoc_files: []
@@ -36,6 +61,7 @@ files:
36
61
  - .gitignore
37
62
  - README
38
63
  - Rakefile
64
+ - bin/memprof
39
65
  - ext/arch.h
40
66
  - ext/bin_api.h
41
67
  - ext/elf.c
@@ -55,9 +81,10 @@ files:
55
81
  - ext/x86_64.h
56
82
  - ext/x86_gen.h
57
83
  - lib/memprof/middleware.rb
58
- - lib/memprof/usr2.rb
84
+ - lib/memprof/signal.rb
59
85
  - memprof.gemspec
60
86
  - spec/memprof_spec.rb
87
+ - spec/memprof_uploader_spec.rb
61
88
  has_rdoc: true
62
89
  homepage: http://github.com/ice799/memprof
63
90
  licenses: []
@@ -1,10 +0,0 @@
1
- require File.expand_path('../../memprof', __FILE__)
2
- Memprof.start
3
- trap('USR2'){
4
- pid = Process.pid
5
- fork{
6
- GC.start
7
- Memprof.dump_all("/tmp/memprof-#{pid}-#{Time.now.to_i}.json")
8
- exit!
9
- }
10
- }