bleak_house 4.6 → 5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +0,0 @@
1
- RUBY_VERSION = `ruby -v`.split(" ")[1]
2
- require 'mkmf'
3
- $CFLAGS = ENV['CFLAGS']
4
- dir_config('snapshot')
5
- create_makefile('snapshot')
@@ -1,26 +0,0 @@
1
- require 'fileutils'
2
-
3
- module BleakHouse
4
-
5
- LOGDIR = File.expand_path('../../log', __FILE__)
6
- LOGFILE = File.join(LOGDIR, 'bleak_house.log')
7
-
8
- FileUtils.mkdir_p(LOGDIR)
9
-
10
- def self.write_to_log(message)
11
- File.open(LOGFILE, 'a') { |f| f.puts message }
12
- end
13
-
14
- def self.execute(command)
15
- unless system(command)
16
- puts File.open(LOGFILE).read
17
- exit -1
18
- end
19
- end
20
- end
21
-
22
- BleakHouse.write_to_log('-%{ BUILDING RUBY }%-')
23
- BleakHouse.execute("ruby build_ruby.rb >> #{BleakHouse::LOGFILE} 2>&1")
24
-
25
- BleakHouse.write_to_log('-%{ BUILDING SNAPSHOT }%-')
26
- BleakHouse.execute("ruby-bleak-house build_snapshot.rb >> #{BleakHouse::LOGFILE} 2>&1")
@@ -1,151 +0,0 @@
1
- #include <time.h>
2
- #include "snapshot.h"
3
-
4
- static VALUE rb_mB;
5
- static VALUE rb_cC;
6
-
7
- /* Number of filled <tt>heaps_slots</tt> */
8
- static VALUE heaps_used(VALUE self) {
9
- return INT2FIX(rb_gc_heaps_used());
10
- }
11
-
12
- /* Number of allocated <tt>heaps_slots</tt> */
13
- static VALUE heaps_length(VALUE self) {
14
- return INT2FIX(rb_gc_heaps_length());
15
- }
16
-
17
- /* Inner method; call BleakHouse.snapshot instead. */
18
- static VALUE ext_snapshot(VALUE self, VALUE _logfile, VALUE _gc_runs) {
19
- Check_Type(_logfile, T_STRING);
20
- Check_Type(_gc_runs, T_FIXNUM);
21
-
22
- RVALUE *obj, *obj_end;
23
- st_table_entry *sym;
24
-
25
- struct heaps_slot * heaps = rb_gc_heap_slots();
26
- struct st_table * sym_tbl = rb_parse_sym_tbl();
27
-
28
- /* see if the logfile exists already */
29
- FILE *logfile = fopen(StringValueCStr(_logfile), "r");
30
- int is_new;
31
- if (!(is_new = (logfile == NULL)))
32
- fclose(logfile);
33
-
34
- /* reopen for writing */
35
- if ((logfile = fopen(StringValueCStr(_logfile), "w")) == NULL)
36
- rb_raise(rb_eRuntimeError, "couldn't open snapshot file");
37
-
38
- int filled_slots = 0;
39
- int free_slots = 0;
40
-
41
- int i;
42
- char * chr;
43
-
44
- for (i = 0; i < FIX2INT(_gc_runs); i++) {
45
- /* request GC run */
46
- rb_funcall(rb_mGC, rb_intern("start"), 0);
47
- rb_thread_schedule();
48
- }
49
-
50
- /* walk the heap */
51
- for (i = 0; i < rb_gc_heaps_used(); i++) {
52
- obj = heaps[i].slot;
53
- obj_end = obj + heaps[i].limit;
54
- for (; obj < obj_end; obj++) {
55
- if (obj->as.basic.flags) { /* always 0 for freed objects */
56
- filled_slots ++;
57
-
58
- /* write the source file*/
59
- if (obj->file) {
60
- chr = obj->file;
61
- if (*chr != '\0') {
62
- fprintf(logfile, "%s", obj->file);
63
- } else {
64
- fprintf(logfile, "__empty__");
65
- }
66
- } else {
67
- fprintf(logfile, "__null__");
68
- }
69
-
70
- /* write the source line */
71
- fprintf(logfile, ":");
72
- if (obj->line) {
73
- fprintf(logfile, "%i", obj->line);
74
- } else {
75
- fprintf(logfile, "__null__");
76
- }
77
-
78
- /* write the class */
79
- fprintf(logfile, ":");
80
- switch (TYPE(obj)) {
81
- case T_NONE:
82
- fprintf(logfile, "__none__"); break;
83
- case T_BLKTAG:
84
- fprintf(logfile, "__blktag__"); break;
85
- case T_UNDEF:
86
- fprintf(logfile, "__undef__"); break;
87
- case T_VARMAP:
88
- fprintf(logfile, "__varmap__"); break;
89
- case T_SCOPE:
90
- fprintf(logfile, "__scope__"); break;
91
- case T_NODE:
92
- fprintf(logfile, "__node__"); break;
93
- default:
94
- if (!obj->as.basic.klass) {
95
- fprintf(logfile, "__unknown__");
96
- } else {
97
- fprintf(logfile, rb_obj_classname((VALUE)obj));
98
- }
99
- }
100
-
101
- /* write newline */
102
- fprintf(logfile, "\n");
103
- } else {
104
- free_slots ++;
105
- }
106
- }
107
- }
108
-
109
- /* walk the symbol table */
110
- /* hashed = lookup_builtin("Symbol");
111
- for (i = 0; i < sym_tbl->num_bins; i++) {
112
- for (sym = sym_tbl->bins[i]; sym != 0; sym = sym->next) {
113
- fprintf(logfile, "%i,%lu\n", hashed + 1, sym->record);
114
- }
115
- } */
116
-
117
- fprintf(logfile, "%i filled\n", filled_slots);
118
- fprintf(logfile, "%i free\n", free_slots);
119
- fclose(logfile);
120
-
121
- return Qnil;
122
- }
123
-
124
-
125
- /*
126
-
127
- This class performs the actual object logging of BleakHouse. To use it directly, you need to make calls to BleakHouse.snapshot.
128
-
129
- By default, BleakHouse records a snapshot on exit. You can disable this by setting the environment variable <tt>NO_EXIT_HANDLER</tt> before startup.
130
-
131
- It is also possible to externally trigger the snapshot at any time by sending <tt>SIGUSR2</tt> to the process.
132
-
133
- == Example
134
-
135
- At the start of your app, put:
136
- require 'rubygems'
137
- require 'bleak_house'
138
- $logfile = "/path/to/logfile"
139
-
140
- Run your app. Once it exits, analyze your data:
141
- bleak /path/to/logfile
142
-
143
- */
144
- void
145
- Init_snapshot()
146
- {
147
- rb_mB = rb_define_module("BleakHouse");
148
- rb_define_singleton_method(rb_mB, "ext_snapshot", ext_snapshot, 2);
149
- rb_define_singleton_method(rb_mB, "heaps_used", heaps_used, 0);
150
- rb_define_singleton_method(rb_mB, "heaps_length", heaps_length, 0);
151
- }
@@ -1,59 +0,0 @@
1
- #include "ruby.h"
2
- #include "env.h"
3
- #include "node.h"
4
- #include "st.h"
5
- #include "re.h"
6
- #include "util.h"
7
- #include "intern.h"
8
- #include "string.h"
9
-
10
- typedef struct RVALUE {
11
- union {
12
- struct {
13
- unsigned long flags; /* always 0 for freed obj */
14
- struct RVALUE *next;
15
- } free;
16
- struct RBasic basic;
17
- struct RObject object;
18
- struct RClass klass;
19
- struct RFloat flonum;
20
- struct RString string;
21
- struct RArray array;
22
- struct RRegexp regexp;
23
- struct RHash hash;
24
- struct RData data;
25
- struct RStruct rstruct;
26
- struct RBignum bignum;
27
- struct RFile file;
28
- struct RNode node;
29
- struct RMatch match;
30
- struct RVarmap varmap;
31
- struct SCOPE scope;
32
- } as;
33
- char *file;
34
- int line;
35
- } RVALUE;
36
-
37
- struct heaps_slot {
38
- void *membase;
39
- RVALUE *slot;
40
- int limit;
41
- };
42
-
43
- typedef struct st_table_entry st_table_entry;
44
-
45
- struct st_table_entry {
46
- unsigned int hash;
47
- st_data_t key;
48
- st_data_t record;
49
- st_table_entry *next;
50
- };
51
-
52
- struct st_table * rb_parse_sym_tbl();
53
- struct heaps_slot * rb_gc_heap_slots();
54
- int rb_gc_heaps_used();
55
- int rb_gc_heaps_length();
56
-
57
- char * inspect(VALUE);
58
- char * handle_exception(VALUE);
59
- int lookup_builtin(char *);
@@ -1,54 +0,0 @@
1
-
2
- module BleakHouse
3
- module Analyzer
4
-
5
- # Analyze a compatible <tt>bleak.dump</tt>. Accepts one or more filename and the number of lines to display.
6
- def self.run(*args)
7
- lines = args.last[/^\d+$/] ? args.pop.to_i : 20
8
-
9
- raise "Can't diff more than 2 files" if args.size > 2
10
-
11
- outputs = args.map do |file|
12
- filled, free = `tail -n 2 #{file}`.split("\n")
13
- unless filled =~ /filled/ and free =~ /free/
14
- raise "#{file} is incomplete or corrupted"
15
- end
16
-
17
- length = `wc #{file}`.to_i - 2
18
- cmd = ENV['NO_TRACE'] ? "awk -F: '{print $3}' " + file : "cat #{file}"
19
- cmd += " | sort | uniq -c | sort -nr | head -#{lines}"
20
-
21
- ["#{length} total objects", "#{filled} heap slots", "#{free} heap slots"] + `#{cmd}`.split("\n")
22
- end
23
-
24
- if outputs.size == 1
25
- # Just output the data
26
- puts "Displaying top #{lines} most common line/class pairs"
27
- puts outputs.first
28
- else
29
- puts "Displaying change in top #{lines} most common line/class pairs"
30
- puts diff(outputs)
31
- end
32
-
33
- end
34
-
35
- def self.diff(outputs)
36
- # Calculate the diff
37
- diff = Hash.new(0)
38
- # Iterate each item
39
- outputs.each_with_index do |output, index|
40
- output[3..-1].each do |line|
41
- c, key = line.split(" ", 2)
42
- index.zero? ? diff[key] -= c.to_i : diff[key] += c.to_i
43
- end
44
- end
45
- # Format the lines in descending order
46
- diff.sort_by do |key, value|
47
- -value
48
- end.map do |key, value|
49
- "#{value.to_s.rjust(6)} #{key}"
50
- end
51
- end
52
-
53
- end
54
- end
@@ -1,24 +0,0 @@
1
-
2
- module BleakHouse
3
- # The body of the exit handler and <tt>SIGUSR2</tt> trap. It writes a snapshot to a dumpfile named after the current Process.pid.
4
- def self.hook
5
- @count ||= 0
6
- filename = "/tmp/bleak.%s.%03i.dump" % [Process.pid,@count]
7
- STDERR.puts "** BleakHouse: working..."
8
- BleakHouse.snapshot(filename)
9
- STDERR.puts "** BleakHouse: complete\n** Bleakhouse: Run 'bleak #{filename}' to analyze."
10
- @count += 1
11
- end
12
- end
13
-
14
- unless ENV['NO_EXIT_HANDLER']
15
- Kernel.at_exit do
16
- BleakHouse.hook
17
- end
18
- STDERR.puts "** Bleakhouse: installed"
19
- end
20
-
21
- Kernel.trap("USR2") do
22
- STDERR.puts "** BleakHouse: we get signal."
23
- BleakHouse.hook
24
- end
Binary file
@@ -1,483 +0,0 @@
1
- diff --git a/Makefile.in b/Makefile.in
2
- index a37bcf6..52f723c 100644
3
- --- a/Makefile.in
4
- +++ b/Makefile.in
5
- @@ -34,7 +34,7 @@ RIDATADIR = $(DESTDIR)$(datadir)/ri/$(MAJOR).$(MINOR)/system
6
-
7
- empty =
8
- OUTFLAG = @OUTFLAG@$(empty)
9
- -CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@
10
- +CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@ @VALGRIND_CFLAGS@
11
- cflags = @cflags@
12
- optflags = @optflags@
13
- debugflags = @debugflags@
14
- diff --git a/configure b/configure
15
- index faf2b45..16287ca 100755
16
- --- a/configure
17
- +++ b/configure
18
- @@ -724,6 +724,7 @@ cflags
19
- optflags
20
- debugflags
21
- XCFLAGS
22
- +VALGRIND_CFLAGS
23
- XLDFLAGS
24
- LIBRUBY_LDSHARED
25
- LIBRUBY_DLDFLAGS
26
- @@ -1353,6 +1354,7 @@ Optional Features:
27
- --enable-setreuid use setreuid()/setregid() according to need even if obsolete.
28
- --disable-rpath embed run path into extension libraries.
29
- --enable-shared build a shared library for Ruby.
30
- + --enable-valgrind Use valgrind support
31
- --enable-install-doc build and install rdoc indexes during install
32
-
33
- Optional Packages:
34
- @@ -13012,12 +13014,11 @@ cat confdefs.h >>conftest.$ac_ext
35
- cat >>conftest.$ac_ext <<_ACEOF
36
- /* end confdefs.h. */
37
- #include <sys/types.h> /* for off_t */
38
- - #include <stdio.h>
39
- +#include <stdio.h>
40
- int
41
- main ()
42
- {
43
- -int (*fp) (FILE *, off_t, int) = fseeko;
44
- - return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
45
- +return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
46
- ;
47
- return 0;
48
- }
49
- @@ -16462,6 +16463,173 @@ done
50
- fi
51
- fi
52
-
53
- +# Check whether --enable-valgrind was given.
54
- +if test "${enable_valgrind+set}" = set; then
55
- + enableval=$enable_valgrind; want_valgrind=$enableval
56
- +else
57
- + want_valgrind=auto
58
- +fi
59
- +
60
- +
61
- +if test x"$want_valgrind" != xno; then
62
- +
63
- +for ac_header in valgrind/memcheck.h
64
- +do
65
- +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
66
- +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
67
- + { echo "$as_me:$LINENO: checking for $ac_header" >&5
68
- +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
69
- +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
70
- + echo $ECHO_N "(cached) $ECHO_C" >&6
71
- +fi
72
- +ac_res=`eval echo '${'$as_ac_Header'}'`
73
- + { echo "$as_me:$LINENO: result: $ac_res" >&5
74
- +echo "${ECHO_T}$ac_res" >&6; }
75
- +else
76
- + # Is the header compilable?
77
- +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
78
- +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
79
- +cat >conftest.$ac_ext <<_ACEOF
80
- +/* confdefs.h. */
81
- +_ACEOF
82
- +cat confdefs.h >>conftest.$ac_ext
83
- +cat >>conftest.$ac_ext <<_ACEOF
84
- +/* end confdefs.h. */
85
- +$ac_includes_default
86
- +#include <$ac_header>
87
- +_ACEOF
88
- +rm -f conftest.$ac_objext
89
- +if { (ac_try="$ac_compile"
90
- +case "(($ac_try" in
91
- + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
92
- + *) ac_try_echo=$ac_try;;
93
- +esac
94
- +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
95
- + (eval "$ac_compile") 2>conftest.er1
96
- + ac_status=$?
97
- + grep -v '^ *+' conftest.er1 >conftest.err
98
- + rm -f conftest.er1
99
- + cat conftest.err >&5
100
- + echo "$as_me:$LINENO: \$? = $ac_status" >&5
101
- + (exit $ac_status); } && {
102
- + test -z "$ac_c_werror_flag" ||
103
- + test ! -s conftest.err
104
- + } && test -s conftest.$ac_objext; then
105
- + ac_header_compiler=yes
106
- +else
107
- + echo "$as_me: failed program was:" >&5
108
- +sed 's/^/| /' conftest.$ac_ext >&5
109
- +
110
- + ac_header_compiler=no
111
- +fi
112
- +
113
- +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
114
- +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
115
- +echo "${ECHO_T}$ac_header_compiler" >&6; }
116
- +
117
- +# Is the header present?
118
- +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
119
- +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
120
- +cat >conftest.$ac_ext <<_ACEOF
121
- +/* confdefs.h. */
122
- +_ACEOF
123
- +cat confdefs.h >>conftest.$ac_ext
124
- +cat >>conftest.$ac_ext <<_ACEOF
125
- +/* end confdefs.h. */
126
- +#include <$ac_header>
127
- +_ACEOF
128
- +if { (ac_try="$ac_cpp conftest.$ac_ext"
129
- +case "(($ac_try" in
130
- + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
131
- + *) ac_try_echo=$ac_try;;
132
- +esac
133
- +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
134
- + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
135
- + ac_status=$?
136
- + grep -v '^ *+' conftest.er1 >conftest.err
137
- + rm -f conftest.er1
138
- + cat conftest.err >&5
139
- + echo "$as_me:$LINENO: \$? = $ac_status" >&5
140
- + (exit $ac_status); } >/dev/null && {
141
- + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
142
- + test ! -s conftest.err
143
- + }; then
144
- + ac_header_preproc=yes
145
- +else
146
- + echo "$as_me: failed program was:" >&5
147
- +sed 's/^/| /' conftest.$ac_ext >&5
148
- +
149
- + ac_header_preproc=no
150
- +fi
151
- +
152
- +rm -f conftest.err conftest.$ac_ext
153
- +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
154
- +echo "${ECHO_T}$ac_header_preproc" >&6; }
155
- +
156
- +# So? What about this header?
157
- +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
158
- + yes:no: )
159
- + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
160
- +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
161
- + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
162
- +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
163
- + ac_header_preproc=yes
164
- + ;;
165
- + no:yes:* )
166
- + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
167
- +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
168
- + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
169
- +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
170
- + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
171
- +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
172
- + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
173
- +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
174
- + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
175
- +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
176
- + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
177
- +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
178
- +
179
- + ;;
180
- +esac
181
- +{ echo "$as_me:$LINENO: checking for $ac_header" >&5
182
- +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
183
- +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
184
- + echo $ECHO_N "(cached) $ECHO_C" >&6
185
- +else
186
- + eval "$as_ac_Header=\$ac_header_preproc"
187
- +fi
188
- +ac_res=`eval echo '${'$as_ac_Header'}'`
189
- + { echo "$as_me:$LINENO: result: $ac_res" >&5
190
- +echo "${ECHO_T}$ac_res" >&6; }
191
- +
192
- +fi
193
- +if test `eval echo '${'$as_ac_Header'}'` = yes; then
194
- + cat >>confdefs.h <<_ACEOF
195
- +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
196
- +_ACEOF
197
- + have_valgrind=yes
198
- +else
199
- + have_valgrind=no
200
- +fi
201
- +
202
- +done
203
- +
204
- + if test x"$have_valgrind" = xyes; then
205
- + cat >>confdefs.h <<\_ACEOF
206
- +#define HAVE_VALGRIND 1
207
- +_ACEOF
208
- +
209
- + VALGRIND_CFLAGS="";
210
- + elif test x"$want_valgrind" = xyes -a x"$have_valgrind" = xno; then
211
- + { { echo "$as_me:$LINENO: error: valgrind support requested but valgrind not found" >&5
212
- +echo "$as_me: error: valgrind support requested but valgrind not found" >&2;}
213
- + { (exit 1); exit 1; }; }
214
- + else
215
- + VALGRIND_CFLAGS="";
216
- + fi
217
- +fi
218
- +
219
- +
220
- DEFAULT_KCODE="KCODE_NONE"
221
-
222
-
223
- @@ -18588,6 +18756,7 @@ cflags!$cflags$ac_delim
224
- optflags!$optflags$ac_delim
225
- debugflags!$debugflags$ac_delim
226
- XCFLAGS!$XCFLAGS$ac_delim
227
- +VALGRIND_CFLAGS!$VALGRIND_CFLAGS$ac_delim
228
- XLDFLAGS!$XLDFLAGS$ac_delim
229
- LIBRUBY_LDSHARED!$LIBRUBY_LDSHARED$ac_delim
230
- LIBRUBY_DLDFLAGS!$LIBRUBY_DLDFLAGS$ac_delim
231
- @@ -18622,7 +18791,7 @@ MANTYPE!$MANTYPE$ac_delim
232
- LTLIBOBJS!$LTLIBOBJS$ac_delim
233
- _ACEOF
234
-
235
- - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 47; then
236
- + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 48; then
237
- break
238
- elif $ac_last_try; then
239
- { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
240
- diff --git a/configure.in b/configure.in
241
- index fe63c0c..e0cdcdd 100644
242
- --- a/configure.in
243
- +++ b/configure.in
244
- @@ -1043,6 +1043,23 @@ if test x"$ac_cv_header_ucontext_h" = xyes; then
245
- fi
246
- fi
247
-
248
- +AC_ARG_ENABLE(valgrind,
249
- + [ --enable-valgrind use valgrind support],
250
- + [want_valgrind=$enableval], [want_valgrind=auto])
251
- +
252
- +if test x"$want_valgrind" != xno; then
253
- + AC_CHECK_HEADERS(valgrind/memcheck.h, have_valgrind=yes, have_valgrind=no)
254
- + if test x"$have_valgrind" = xyes; then
255
- + AC_DEFINE(HAVE_VALGRIND)
256
- + VALGRIND_CFLAGS="";
257
- + elif test x"$want_valgrind" = xyes -a x"$have_valgrind" = xno; then
258
- + AC_MSG_ERROR(valgrind support requested but valgrind not found)
259
- + else
260
- + VALGRIND_CFLAGS="";
261
- + fi
262
- +fi
263
- +
264
- +
265
- dnl default value for $KANJI
266
- DEFAULT_KCODE="KCODE_NONE"
267
-
268
- @@ -1663,6 +1680,7 @@ AC_SUBST(cflags, ['${optflags} ${debugflags}'])dnl
269
- AC_SUBST(optflags)dnl
270
- AC_SUBST(debugflags)dnl
271
- AC_SUBST(XCFLAGS)dnl
272
- +AC_SUBST(VALGRIND_CFLAGS)dnl
273
- AC_SUBST(XLDFLAGS)dnl
274
- AC_SUBST(LIBRUBY_LDSHARED)
275
- AC_SUBST(LIBRUBY_DLDFLAGS)
276
- diff --git a/eval.c b/eval.c
277
- index 11264f7..09ec7a6 100644
278
- --- a/eval.c
279
- +++ b/eval.c
280
- @@ -28,6 +28,12 @@
281
- #define EXIT_FAILURE 1
282
- #endif
283
-
284
- +#ifdef HAVE_VALGRIND
285
- +#include <valgrind/memcheck.h>
286
- +#else
287
- +#define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
288
- +#endif
289
- +
290
- #include <stdio.h>
291
-
292
- #include "st.h"
293
- @@ -1149,7 +1149,7 @@ static VALUE trace_func = 0;
294
- static int tracing = 0;
295
- static void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE));
296
-
297
- -#if 0
298
- +#if 1
299
- #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \
300
- ruby_sourceline = nd_line(ruby_current_node))
301
- #else
302
- @@ -5290,6 +5296,9 @@ assign(self, lhs, val, pcall)
303
- int pcall;
304
- {
305
- ruby_current_node = lhs;
306
- +
307
- + VALGRIND_MAKE_MEM_DEFINED(&val, sizeof(val));
308
- +
309
- if (val == Qundef) {
310
- rb_warning("assigning void value");
311
- val = Qnil;
312
- diff --git a/gc.c b/gc.c
313
- index 45facf0..933b76e 100644
314
- --- a/gc.c
315
- +++ b/gc.c
316
- @@ -30,6 +30,12 @@
317
- #include <sys/resource.h>
318
- #endif
319
-
320
- +#ifdef HAVE_VALGRIND
321
- +#include <valgrind/memcheck.h>
322
- +#else
323
- +#define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
324
- +#endif
325
- +
326
- #if defined _WIN32 || defined __CYGWIN__
327
- #include <windows.h>
328
- #endif
329
- @@ -138,6 +144,9 @@ ruby_xmalloc(size)
330
- {
331
- void *mem;
332
-
333
- + VALGRIND_MAKE_MEM_DEFINED(&malloc_increase, sizeof(malloc_increase));
334
- + VALGRIND_MAKE_MEM_DEFINED(&malloc_limit, sizeof(malloc_limit));
335
- +
336
- if (size < 0) {
337
- rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
338
- }
339
- @@ -297,8 +306,6 @@ rb_gc_unregister_address(addr)
340
- }
341
- }
342
-
343
- -#undef GC_DEBUG
344
- -
345
- void
346
- rb_global_variable(var)
347
- VALUE *var;
348
- @@ -333,10 +340,8 @@ typedef struct RVALUE {
349
- struct RVarmap varmap;
350
- struct SCOPE scope;
351
- } as;
352
- -#ifdef GC_DEBUG
353
- char *file;
354
- int line;
355
- -#endif
356
- } RVALUE;
357
-
358
- #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
359
- @@ -355,6 +360,22 @@ static struct heaps_slot {
360
- static int heaps_length = 0;
361
- static int heaps_used = 0;
362
-
363
- +struct heaps_slot *
364
- +rb_gc_heap_slots()
365
- +{
366
- + return heaps;
367
- +}
368
- +
369
- +int
370
- +rb_gc_heaps_used() {
371
- + return heaps_used;
372
- +}
373
- +
374
- +int
375
- +rb_gc_heaps_length() {
376
- + return heaps_length;
377
- +}
378
- +
379
- #define HEAP_MIN_SLOTS 10000
380
- static int heap_slots = HEAP_MIN_SLOTS;
381
-
382
- @@ -438,10 +438,8 @@ rb_newobj()
383
- obj = (VALUE)freelist;
384
- freelist = freelist->as.free.next;
385
- MEMZERO((void*)obj, RVALUE, 1);
386
- -#ifdef GC_DEBUG
387
- RANY(obj)->file = ruby_sourcefile;
388
- RANY(obj)->line = ruby_sourceline;
389
- -#endif
390
- return obj;
391
- }
392
-
393
- @@ -678,6 +704,9 @@ mark_locations_array(x, n)
394
- register long n;
395
- {
396
- VALUE v;
397
- +
398
- + VALGRIND_MAKE_MEM_DEFINED(x, sizeof(*x) * n);
399
- +
400
- while (n--) {
401
- v = *x;
402
- if (is_pointer_to_heap((void *)v)) {
403
- @@ -768,12 +797,18 @@ gc_mark(ptr, lev)
404
- {
405
- register RVALUE *obj;
406
-
407
- + VALGRIND_MAKE_MEM_DEFINED(&ptr, sizeof(ptr));
408
- obj = RANY(ptr);
409
- + VALGRIND_MAKE_MEM_DEFINED(obj, sizeof(*obj));
410
- +
411
- if (rb_special_const_p(ptr)) return; /* special const not marked */
412
- if (obj->as.basic.flags == 0) return; /* free cell */
413
- if (obj->as.basic.flags & FL_MARK) return; /* already marked */
414
- obj->as.basic.flags |= FL_MARK;
415
-
416
- + /* mark our new reference point for sourcefile objects */
417
- + mark_source_filename(RANY(obj)->file);
418
- +
419
- if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
420
- if (!mark_stack_overflow) {
421
- if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
422
- @@ -1077,6 +1078,10 @@ gc_mark(ptr, lev)
423
- if (obj->as.basic.flags == 0) return; /* free cell */
424
- if (obj->as.basic.flags & FL_MARK) return; /* already marked */
425
- obj->as.basic.flags |= FL_MARK;
426
- +
427
- + /* mark our new reference point for sourcefile objects */
428
- + mark_source_filename(RANY(obj)->file);
429
- +
430
-
431
- if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
432
- if (!mark_stack_overflow) {
433
- @@ -1115,6 +1120,10 @@ gc_mark_children(ptr, lev)
434
- if (obj->as.basic.flags == 0) return; /* free cell */
435
- if (obj->as.basic.flags & FL_MARK) return; /* already marked */
436
- obj->as.basic.flags |= FL_MARK;
437
- +
438
- + /* mark our new reference point for sourcefile objects */
439
- + mark_source_filename(RANY(obj)->file);
440
- +
441
-
442
- marking:
443
- if (FL_TEST(obj, FL_EXIVAR)) {
444
- diff --git a/parse.c b/parse.c
445
- index 6b3d80d..b320cf2 100644
446
- --- a/parse.c
447
- +++ b/parse.c
448
- @@ -11403,6 +11403,11 @@ symbols_i(key, value, ary)
449
- * :wait2, :$>]
450
- */
451
-
452
- +struct st_table *
453
- +rb_parse_sym_tbl() {
454
- + return sym_tbl;
455
- +}
456
- +
457
- VALUE
458
- rb_sym_all_symbols()
459
- {
460
- diff --git a/parse.y b/parse.y
461
- index ab0b83c..3ce1dfb 100644
462
- --- a/parse.y
463
- +++ b/parse.y
464
- @@ -6263,6 +6263,11 @@ symbols_i(key, value, ary)
465
- * :wait2, :$>]
466
- */
467
-
468
- +struct st_table *
469
- +rb_parse_sym_tbl() {
470
- + return sym_tbl;
471
- +}
472
- +
473
- VALUE
474
- rb_sym_all_symbols()
475
- {
476
- diff --git a/version.h b/version.h
477
- index 70fc28a..76aa188 100644
478
- --- a/version.h
479
- +++ b/version.h
480
- @@ -5,2 +5,2 @@
481
- -#define RUBY_PATCHLEVEL 174
482
- +#define RUBY_PATCHLEVEL 905
483
-