memprof 0.2.9 → 0.3.0

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