bleak_house 3.7.1 → 4.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.
Files changed (87) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +2 -0
  3. data/Manifest +12 -66
  4. data/README +57 -20
  5. data/TODO +2 -2
  6. data/bin/bleak +1 -14
  7. data/bleak_house.gemspec +10 -16
  8. data/ext/{bleak_house/logger/build_ruby.rb → build_ruby.rb} +17 -7
  9. data/ext/build_snapshot.rb +4 -0
  10. data/ext/{bleak_house/logger/extconf.rb → extconf.rb} +1 -1
  11. data/ext/snapshot.c +157 -0
  12. data/ext/{bleak_house/logger/snapshot.h → snapshot.h} +2 -45
  13. data/lib/bleak_house.rb +5 -5
  14. data/lib/bleak_house/analyzer.rb +24 -2
  15. data/lib/bleak_house/hook.rb +25 -0
  16. data/ruby/bleak_house.patch +358 -0
  17. data/ruby/configure.patch +242 -0
  18. data/ruby/gc.patch +116 -0
  19. data/ruby/ruby-1.8.6-p114.tar.bz2 +0 -0
  20. data/ruby/valgrind.patch +136 -0
  21. data/test/benchmark/bench.rb +16 -0
  22. data/test/unit/test_bleak_house.rb +26 -27
  23. metadata +22 -86
  24. metadata.gz.sig +0 -0
  25. data/ext/bleak_house/logger/build_logger.rb +0 -3
  26. data/ext/bleak_house/logger/snapshot.c +0 -204
  27. data/init.rb +0 -3
  28. data/install.rb +0 -2
  29. data/lib/bleak_house/analyzer/analyzer.rb +0 -358
  30. data/lib/bleak_house/logger.rb +0 -2
  31. data/lib/bleak_house/logger/source.rb +0 -21
  32. data/lib/bleak_house/rails.rb +0 -6
  33. data/lib/bleak_house/rails/action_controller.rb +0 -17
  34. data/lib/bleak_house/rails/bleak_house.rb +0 -62
  35. data/lib/bleak_house/rails/dispatcher.rb +0 -36
  36. data/lib/bleak_house/support/core_extensions.rb +0 -61
  37. data/ruby/gc.c.patch +0 -27
  38. data/ruby/parse.y.patch +0 -16
  39. data/ruby/ruby-1.8.6-p110.tar.bz2 +0 -0
  40. data/test/integration/app/README +0 -203
  41. data/test/integration/app/Rakefile +0 -10
  42. data/test/integration/app/app/controllers/application.rb +0 -12
  43. data/test/integration/app/app/controllers/items_controller.rb +0 -6
  44. data/test/integration/app/app/helpers/application_helper.rb +0 -3
  45. data/test/integration/app/app/helpers/items_helper.rb +0 -2
  46. data/test/integration/app/app/views/items/index.rhtml +0 -2
  47. data/test/integration/app/config/boot.rb +0 -109
  48. data/test/integration/app/config/database.yml +0 -19
  49. data/test/integration/app/config/environment.rb +0 -15
  50. data/test/integration/app/config/environments/development.rb +0 -18
  51. data/test/integration/app/config/environments/production.rb +0 -19
  52. data/test/integration/app/config/environments/test.rb +0 -22
  53. data/test/integration/app/config/initializers/inflections.rb +0 -10
  54. data/test/integration/app/config/initializers/mime_types.rb +0 -5
  55. data/test/integration/app/config/routes.rb +0 -35
  56. data/test/integration/app/doc/README_FOR_APP +0 -2
  57. data/test/integration/app/public/404.html +0 -30
  58. data/test/integration/app/public/422.html +0 -30
  59. data/test/integration/app/public/500.html +0 -30
  60. data/test/integration/app/public/dispatch.cgi +0 -10
  61. data/test/integration/app/public/dispatch.fcgi +0 -24
  62. data/test/integration/app/public/dispatch.rb +0 -10
  63. data/test/integration/app/public/favicon.ico +0 -0
  64. data/test/integration/app/public/images/rails.png +0 -0
  65. data/test/integration/app/public/javascripts/application.js +0 -2
  66. data/test/integration/app/public/javascripts/controls.js +0 -963
  67. data/test/integration/app/public/javascripts/dragdrop.js +0 -972
  68. data/test/integration/app/public/javascripts/effects.js +0 -1120
  69. data/test/integration/app/public/javascripts/prototype.js +0 -4225
  70. data/test/integration/app/public/robots.txt +0 -5
  71. data/test/integration/app/script/about +0 -3
  72. data/test/integration/app/script/console +0 -3
  73. data/test/integration/app/script/destroy +0 -3
  74. data/test/integration/app/script/generate +0 -3
  75. data/test/integration/app/script/performance/benchmarker +0 -3
  76. data/test/integration/app/script/performance/profiler +0 -3
  77. data/test/integration/app/script/performance/request +0 -3
  78. data/test/integration/app/script/plugin +0 -3
  79. data/test/integration/app/script/process/inspector +0 -3
  80. data/test/integration/app/script/process/reaper +0 -3
  81. data/test/integration/app/script/process/spawner +0 -3
  82. data/test/integration/app/script/runner +0 -3
  83. data/test/integration/app/script/server +0 -3
  84. data/test/integration/app/test/functional/items_controller_test.rb +0 -8
  85. data/test/integration/app/test/test_helper.rb +0 -38
  86. data/test/integration/server_test.rb +0 -93
  87. data/test/misc/direct.rb +0 -13
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'dike'
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../lib")
6
+ require 'bleak_house'
7
+
8
+ Dike.logfactory("/tmp")
9
+ if ARGV[0]
10
+ Dike.finger
11
+ exec('cat /tmp/0')
12
+ else
13
+ BleakHouse.snapshot("/tmp/0")
14
+ exec("#{$LOAD_PATH.first}/../bin/bleak /tmp/0")
15
+ end
16
+
@@ -1,51 +1,50 @@
1
1
 
2
- DIR = File.dirname(__FILE__) + "/../../"
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../lib")
3
+
4
+ ENV['NO_EXIT_HANDLER'] = "1"
3
5
 
4
6
  require 'rubygems'
7
+ require 'echoe'
5
8
  require 'test/unit'
6
- require 'yaml'
7
- require 'ruby-debug'
8
- require 'ccsv'
9
- Debugger.start
9
+ require 'bleak_house'
10
10
 
11
11
  class BleakHouseTest < Test::Unit::TestCase
12
- require "#{DIR}lib/bleak_house/logger"
13
12
 
14
- SNAPSHOT_FILE = "/tmp/bleak_house.dump"
13
+ # Match the default hook filename, for convenience
14
+ FILE = "/tmp/bleak.#{Process.pid}.0.dump"
15
15
 
16
16
  def setup
17
- File.delete SNAPSHOT_FILE rescue nil
17
+ File.delete FILE rescue nil
18
18
  end
19
19
 
20
20
  def test_snapshot
21
21
  symbol_count = Symbol.all_symbols.size
22
- ::BleakHouse::Logger.new.snapshot(SNAPSHOT_FILE, "test", false, 0)
23
- assert_equal symbol_count, Symbol.all_symbols.size # Test that no symbols leaked
24
- assert File.exist?(SNAPSHOT_FILE)
25
- assert_equal 0, sample_ratio(SNAPSHOT_FILE)
26
- end
27
-
28
- def test_sampling
29
- ::BleakHouse::Logger.new.snapshot(SNAPSHOT_FILE, "test", false, 0.5)
30
- ratio = sample_ratio(SNAPSHOT_FILE)
31
- assert(ratio > 0.45)
32
- assert(ratio < 0.55)
22
+ BleakHouse.snapshot(FILE)
23
+ assert File.exist?(FILE)
24
+ assert BleakHouse.heaps_used > 0
25
+ assert BleakHouse.heaps_length > 0
33
26
  end
34
27
 
35
28
  def test_exception
36
29
  assert_raises(RuntimeError) do
37
- ::BleakHouse::Logger.new.snapshot("/", "test", false, 0)
30
+ BleakHouse.snapshot("/")
38
31
  end
39
32
  end
40
33
 
41
- def sample_ratio(file)
42
- rows = 0
43
- samples = 0
44
- Ccsv.foreach(file) do |row|
45
- rows += 1
46
- samples += 1 if row[2]
34
+ def test_analyze
35
+ BleakHouse.snapshot(FILE)
36
+ Dir.chdir(File.dirname(__FILE__) + "/../../bin") do
37
+ output = `./bleak #{FILE}`.split("\n")
38
+ # require 'ruby-debug/debugger'
39
+ assert_match(/\d+ __null__:__null__:__node__/, output[3])
47
40
  end
48
- samples / rows.to_f
49
41
  end
50
42
 
43
+ def test_signal
44
+ Echoe.silence do
45
+ system("kill -s SIGUSR2 #{Process.pid}")
46
+ end
47
+ assert File.exist?(FILE)
48
+ end
49
+
51
50
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bleak_house
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.1
4
+ version: "4.0"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Weaver
@@ -30,32 +30,22 @@ cert_chain:
30
30
  yZ0=
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2008-03-30 00:00:00 -04:00
33
+ date: 2008-04-06 00:00:00 -04:00
34
34
  default_executable:
35
- dependencies:
36
- - !ruby/object:Gem::Dependency
37
- name: ccsv
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: "0.1"
44
- version:
35
+ dependencies: []
36
+
45
37
  description: A library for finding memory leaks.
46
38
  email: ""
47
39
  executables:
48
40
  - bleak
49
41
  extensions:
50
- - ext/bleak_house/logger/extconf.rb
42
+ - ext/extconf.rb
51
43
  extra_rdoc_files:
52
44
  - CHANGELOG
53
- - ext/bleak_house/logger/snapshot.c
54
- - lib/bleak_house/analyzer/analyzer.rb
45
+ - ext/snapshot.c
55
46
  - lib/bleak_house/analyzer.rb
56
- - lib/bleak_house/logger/source.rb
57
- - lib/bleak_house/logger.rb
58
- - lib/bleak_house/rails/bleak_house.rb
47
+ - lib/bleak_house/hook.rb
48
+ - lib/bleak_house.rb
59
49
  - LICENSE
60
50
  - LICENSE_BSD
61
51
  - README
@@ -63,78 +53,24 @@ extra_rdoc_files:
63
53
  files:
64
54
  - bin/bleak
65
55
  - CHANGELOG
66
- - ext/bleak_house/logger/build_logger.rb
67
- - ext/bleak_house/logger/build_ruby.rb
68
- - ext/bleak_house/logger/extconf.rb
69
- - ext/bleak_house/logger/snapshot.c
70
- - ext/bleak_house/logger/snapshot.h
71
- - init.rb
72
- - install.rb
73
- - lib/bleak_house/analyzer/analyzer.rb
56
+ - ext/build_ruby.rb
57
+ - ext/build_snapshot.rb
58
+ - ext/extconf.rb
59
+ - ext/snapshot.c
60
+ - ext/snapshot.h
74
61
  - lib/bleak_house/analyzer.rb
75
- - lib/bleak_house/logger/source.rb
76
- - lib/bleak_house/logger.rb
77
- - lib/bleak_house/rails/action_controller.rb
78
- - lib/bleak_house/rails/bleak_house.rb
79
- - lib/bleak_house/rails/dispatcher.rb
80
- - lib/bleak_house/rails.rb
81
- - lib/bleak_house/support/core_extensions.rb
62
+ - lib/bleak_house/hook.rb
82
63
  - lib/bleak_house.rb
83
64
  - LICENSE
84
65
  - LICENSE_BSD
85
66
  - Manifest
86
67
  - README
87
- - ruby/gc.c.patch
88
- - ruby/parse.y.patch
89
- - ruby/ruby-1.8.6-p110.tar.bz2
90
- - test/integration/app/app/controllers/application.rb
91
- - test/integration/app/app/controllers/items_controller.rb
92
- - test/integration/app/app/helpers/application_helper.rb
93
- - test/integration/app/app/helpers/items_helper.rb
94
- - test/integration/app/app/views/items/index.rhtml
95
- - test/integration/app/config/boot.rb
96
- - test/integration/app/config/database.yml
97
- - test/integration/app/config/environment.rb
98
- - test/integration/app/config/environments/development.rb
99
- - test/integration/app/config/environments/production.rb
100
- - test/integration/app/config/environments/test.rb
101
- - test/integration/app/config/initializers/inflections.rb
102
- - test/integration/app/config/initializers/mime_types.rb
103
- - test/integration/app/config/routes.rb
104
- - test/integration/app/doc/README_FOR_APP
105
- - test/integration/app/public/404.html
106
- - test/integration/app/public/422.html
107
- - test/integration/app/public/500.html
108
- - test/integration/app/public/dispatch.cgi
109
- - test/integration/app/public/dispatch.fcgi
110
- - test/integration/app/public/dispatch.rb
111
- - test/integration/app/public/favicon.ico
112
- - test/integration/app/public/images/rails.png
113
- - test/integration/app/public/javascripts/application.js
114
- - test/integration/app/public/javascripts/controls.js
115
- - test/integration/app/public/javascripts/dragdrop.js
116
- - test/integration/app/public/javascripts/effects.js
117
- - test/integration/app/public/javascripts/prototype.js
118
- - test/integration/app/public/robots.txt
119
- - test/integration/app/Rakefile
120
- - test/integration/app/README
121
- - test/integration/app/script/about
122
- - test/integration/app/script/console
123
- - test/integration/app/script/destroy
124
- - test/integration/app/script/generate
125
- - test/integration/app/script/performance/benchmarker
126
- - test/integration/app/script/performance/profiler
127
- - test/integration/app/script/performance/request
128
- - test/integration/app/script/plugin
129
- - test/integration/app/script/process/inspector
130
- - test/integration/app/script/process/reaper
131
- - test/integration/app/script/process/spawner
132
- - test/integration/app/script/runner
133
- - test/integration/app/script/server
134
- - test/integration/app/test/functional/items_controller_test.rb
135
- - test/integration/app/test/test_helper.rb
136
- - test/integration/server_test.rb
137
- - test/misc/direct.rb
68
+ - ruby/bleak_house.patch
69
+ - ruby/configure.patch
70
+ - ruby/gc.patch
71
+ - ruby/ruby-1.8.6-p114.tar.bz2
72
+ - ruby/valgrind.patch
73
+ - test/benchmark/bench.rb
138
74
  - test/test_helper.rb
139
75
  - test/unit/test_bleak_house.rb
140
76
  - TODO
@@ -167,10 +103,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
103
  requirements: []
168
104
 
169
105
  rubyforge_project: fauna
170
- rubygems_version: 1.0.1
106
+ rubygems_version: 1.1.0
171
107
  signing_key:
172
108
  specification_version: 2
173
109
  summary: A library for finding memory leaks.
174
110
  test_files:
175
- - test/integration/server_test.rb
111
+ - test/test_helper.rb
176
112
  - test/unit/test_bleak_house.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,3 +0,0 @@
1
- require 'mkmf'
2
- dir_config('snapshot')
3
- create_makefile('bleak_house/logger/snapshot')
@@ -1,204 +0,0 @@
1
- #include <time.h>
2
- #include "snapshot.h"
3
-
4
- static VALUE rb_mBleakHouse;
5
- static VALUE rb_cC;
6
-
7
- /* Number of struct heaps_slots used */
8
- static VALUE heaps_used(VALUE self) {
9
- return INT2FIX(rb_gc_heaps_used());
10
- }
11
-
12
- /* Length of the struct heaps_slots allocated */
13
- static VALUE heaps_length(VALUE self) {
14
- return INT2FIX(rb_gc_heaps_length());
15
- }
16
-
17
- /* Count the live objects on the heap and in the symbol table and write a CSV frame to <tt>_logfile</tt>. Set <tt>_specials = true</tt> if you also want to count AST nodes and var scopes; otherwise, use <tt>false</tt>. Note that common classes in the CSV output are hashed to small integers in order to save space.*/
18
- static VALUE snapshot(VALUE self, VALUE _logfile, VALUE tag, VALUE _specials, VALUE _sampler) {
19
- Check_Type(_logfile, T_STRING);
20
- Check_Type(tag, T_STRING);
21
-
22
- RVALUE *obj, *obj_end;
23
- st_table_entry *sym;
24
-
25
- /* printf("Requested: %f\n", rb_num2dbl(_sampler)); */
26
-
27
- struct heaps_slot * heaps = rb_gc_heap_slots();
28
- struct st_table * sym_tbl = rb_parse_sym_tbl();
29
-
30
- int specials = RTEST(_specials);
31
- int hashed;
32
-
33
- /* see if the logfile exists already */
34
- FILE *logfile = fopen(StringValueCStr(_logfile), "r");
35
- int is_new;
36
- if (!(is_new = (logfile == NULL)))
37
- fclose(logfile);
38
-
39
- /* reopen for writing */
40
- if ((logfile = fopen(StringValueCStr(_logfile), "a+")) == NULL)
41
- rb_raise(rb_eRuntimeError, "couldn't open snapshot file");
42
-
43
- /* write the time */
44
- fprintf(logfile, "-1,%li\n", time(0));
45
-
46
- /* get and write the memory usage */
47
- /* VALUE mem = rb_funcall(self, rb_intern("mem_usage"), 0);
48
- fprintf(logfile, "-2,%li\n", NUM2INT(RARRAY_PTR(mem)[0]));
49
- fprintf(logfile, "-3,%li\n", NUM2INT(RARRAY_PTR(mem)[1])); */
50
-
51
- int filled_slots = 0;
52
- int free_slots = 0;
53
-
54
- /* write the tag header */
55
- fprintf(logfile, "-4,%s\n", StringValueCStr(tag));
56
-
57
- int i;
58
-
59
- /* walk the heap */
60
- for (i = 0; i < rb_gc_heaps_used(); i++) {
61
- obj = heaps[i].slot;
62
- obj_end = obj + heaps[i].limit;
63
- for (; obj < obj_end; obj++) {
64
- if (obj->as.basic.flags) { /* always 0 for freed objects */
65
- filled_slots ++;
66
- switch (TYPE(obj)) {
67
- case T_NONE:
68
- hashed = BUILTINS_SIZE + 0; break;
69
- case T_BLKTAG:
70
- hashed = BUILTINS_SIZE + 1; break;
71
- case T_UNDEF:
72
- hashed = BUILTINS_SIZE + 2; break;
73
- case T_VARMAP:
74
- hashed = BUILTINS_SIZE + 3; break;
75
- case T_SCOPE:
76
- hashed = BUILTINS_SIZE + 4; break;
77
- case T_NODE:
78
- hashed = BUILTINS_SIZE + 5; break;
79
- default:
80
- if (!obj->as.basic.klass) {
81
- hashed = BUILTINS_SIZE + 6;
82
- } else {
83
- hashed = lookup_builtin(rb_obj_classname((VALUE)obj));
84
- }
85
- }
86
-
87
- /* write to log */
88
- if (specials || hashed < BUILTINS_SIZE) {
89
- /* write classname */
90
- if (hashed < 0) {
91
- /* regular classname */
92
- fprintf(logfile, "%s", rb_obj_classname((VALUE)obj));
93
- } else {
94
- /* builtins key */
95
- /* 0 is not used for 'hashed' because Ruby's to_i turns any String into 0 */
96
- fprintf(logfile, "%i", hashed + 1);
97
- }
98
-
99
- /* write id */
100
- fprintf(logfile, ",%lu", FIX2ULONG(rb_obj_id((VALUE)obj)));
101
-
102
- /* write sample, if requested */
103
- if (hashed < BUILTINS_SIZE) {
104
- if (rand()/((double)RAND_MAX + 1) < rb_num2dbl(_sampler)) {
105
- fprintf(logfile, ",%s", rb_rescue(inspect, (VALUE)obj, handle_exception, Qnil));
106
- }
107
- }
108
-
109
- /* write newline */
110
- fprintf(logfile, "\n");
111
- }
112
- } else {
113
- free_slots ++;
114
- }
115
- }
116
- }
117
-
118
- /* walk the symbol table */
119
- hashed = lookup_builtin("Symbol");
120
- for (i = 0; i < sym_tbl->num_bins; i++) {
121
- for (sym = sym_tbl->bins[i]; sym != 0; sym = sym->next) {
122
- fprintf(logfile, "%i,%lu\n", hashed + 1, sym->record);
123
- }
124
- }
125
-
126
- fprintf(logfile, "-5,%i\n", filled_slots);
127
- fprintf(logfile, "-6,%i\n", free_slots);
128
- fclose(logfile);
129
-
130
- for (i = 0; i < 3; i++) {
131
- /* request GC run */
132
- rb_funcall(rb_mGC, rb_intern("start"), 0);
133
- }
134
-
135
- return Qtrue;
136
- }
137
-
138
- char * inspect(VALUE obj) {
139
- VALUE value;
140
- char * string;
141
- int i, length;
142
-
143
- value = rb_funcall((VALUE)obj, rb_intern("inspect"), 0);
144
- string = StringValueCStr(value);
145
- length = strlen(string);
146
-
147
- if (length > MAX_SAMPLE_LENGTH) {
148
- string[MAX_SAMPLE_LENGTH] = '\0';
149
- length = MAX_SAMPLE_LENGTH;
150
- }
151
-
152
- /* Replace control characters */
153
- for (i = 0; i < length; i++) {
154
- if (string[i] == '\n') {
155
- string[i] = ' ';
156
- } if (string[i] == ',') {
157
- string[i] = ' ';
158
- }
159
- }
160
-
161
- /* result = rb_funcall(result, rb_intern("gsub"), 2, rb_str_new2(","), rb_str_new2(",")); */
162
- return string;
163
- }
164
-
165
- char * handle_exception(VALUE unused) {
166
- return "";
167
- }
168
-
169
- int lookup_builtin(char * name) {
170
- int i;
171
- for (i = 0; i < BUILTINS_SIZE; i++) {
172
- if (!strcmp(builtins[i], name)) return i;
173
- }
174
- return -1;
175
- }
176
-
177
- /*
178
-
179
- This class performs the actual object logging of BleakHouse. To use it directly, you need to make calls to BleakHouse::Logger#snapshot.
180
-
181
- == Example
182
-
183
- At the start of your app, put:
184
- require 'rubygems'
185
- require 'bleak_house'
186
- $memlogger = BleakHouse::Logger.new
187
- File.delete($logfile = "/path/to/logfile") rescue nil
188
-
189
- Now, at the points of interest, put:
190
- $memlogger.snapshot($logfile, "tag/subtag", false)
191
-
192
- Run your app. Once you are done, analyze your data:
193
- bleak /path/to/logfile
194
-
195
- */
196
- void
197
- Init_snapshot()
198
- {
199
- rb_mBleakHouse = rb_define_module("BleakHouse");
200
- rb_cC = rb_define_class_under(rb_mBleakHouse, "Logger", rb_cObject);
201
- rb_define_method(rb_cC, "snapshot", snapshot, 4);
202
- rb_define_method(rb_cC, "heaps_used", heaps_used, 0);
203
- rb_define_method(rb_cC, "heaps_length", heaps_length, 0);
204
- }