memprof 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/elf.c +15 -5
- data/ext/extconf.rb +56 -2
- data/ext/mach.c +5 -2
- data/ext/memprof.c +17 -13
- data/ext/src/libelf-0.8.13.tar.gz +0 -0
- data/memprof.gemspec +4 -3
- metadata +5 -2
data/ext/elf.c
CHANGED
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
#include "bin_api.h"
|
4
4
|
|
5
|
-
#include <stdio.h>
|
6
5
|
#include <fcntl.h>
|
7
6
|
#include <gelf.h>
|
8
7
|
#include <link.h>
|
8
|
+
#include <stdio.h>
|
9
|
+
#include <string.h>
|
9
10
|
#include <sysexits.h>
|
10
11
|
#include <unistd.h>
|
11
12
|
|
@@ -18,7 +19,14 @@ static Elf_Data *symtab_data = NULL;
|
|
18
19
|
void *
|
19
20
|
bin_allocate_page()
|
20
21
|
{
|
21
|
-
|
22
|
+
void * ret = NULL;
|
23
|
+
ret = mmap(NULL, pagesize, PROT_WRITE|PROT_READ|PROT_EXEC, MAP_ANON|MAP_PRIVATE|MAP_32BIT, -1, 0);
|
24
|
+
|
25
|
+
if (ret != MAP_FAILED) {
|
26
|
+
memset(ret, 0x90, pagesize);
|
27
|
+
}
|
28
|
+
|
29
|
+
return ret;
|
22
30
|
}
|
23
31
|
|
24
32
|
void
|
@@ -32,15 +40,17 @@ bin_find_symbol(char *sym, size_t *size)
|
|
32
40
|
{
|
33
41
|
char *name = NULL;
|
34
42
|
|
35
|
-
/*now print the symbols*/
|
36
43
|
ElfW(Sym) *esym = (ElfW(Sym)*) symtab_data->d_buf;
|
37
44
|
ElfW(Sym) *lastsym = (ElfW(Sym)*) ((char*) symtab_data->d_buf + symtab_data->d_size);
|
38
|
-
|
45
|
+
|
39
46
|
for (; esym < lastsym; esym++){
|
47
|
+
/* ignore weak/numeric/empty symbols */
|
40
48
|
if ((esym->st_value == 0) ||
|
41
49
|
(ELF32_ST_BIND(esym->st_info)== STB_WEAK) ||
|
42
50
|
(ELF32_ST_BIND(esym->st_info)== STB_NUM))
|
43
51
|
continue;
|
52
|
+
|
53
|
+
|
44
54
|
name = elf_strptr(elf, symtab_shdr.sh_link, (size_t)esym->st_name);
|
45
55
|
if (strcmp(name, sym) == 0) {
|
46
56
|
if (size) {
|
@@ -78,7 +88,7 @@ bin_init()
|
|
78
88
|
if (elf_kind(elf) != ELF_K_ELF)
|
79
89
|
errx(EX_DATAERR, "%s is not an ELF object.", filename);
|
80
90
|
|
81
|
-
if (
|
91
|
+
if (elf_getshdrstrndx(elf, &shstrndx) == -1)
|
82
92
|
errx(EX_SOFTWARE, "getshstrndx() failed: %s.",
|
83
93
|
elf_errmsg(-1));
|
84
94
|
|
data/ext/extconf.rb
CHANGED
@@ -7,12 +7,66 @@ if RUBY_VERSION >= "1.9"
|
|
7
7
|
end
|
8
8
|
|
9
9
|
require 'mkmf'
|
10
|
+
require 'fileutils'
|
11
|
+
|
12
|
+
CWD = File.expand_path(File.dirname(__FILE__))
|
13
|
+
|
14
|
+
def sys(cmd)
|
15
|
+
puts " -- #{cmd}"
|
16
|
+
unless ret = xsystem(cmd)
|
17
|
+
raise "#{cmd} failed, please report to http://github.com/ice799/memprof/issues with pastie.org link to #{CWD}/mkmf.log"
|
18
|
+
end
|
19
|
+
ret
|
20
|
+
end
|
10
21
|
|
11
22
|
def add_define(name)
|
12
23
|
$defs.push("-D#{name}")
|
13
24
|
end
|
14
25
|
|
15
|
-
|
16
|
-
|
26
|
+
###
|
27
|
+
# libelf
|
28
|
+
|
29
|
+
if RUBY_PLATFORM =~ /linux/
|
30
|
+
libelf = File.basename('libelf-0.8.13.tar.gz')
|
31
|
+
dir = File.basename(libelf, '.tar.gz')
|
32
|
+
|
33
|
+
unless File.exists?("#{CWD}/dst/lib/libelf_ext.so")
|
34
|
+
puts "(I'm about to compile libelf.. this will definitely take a while)"
|
35
|
+
|
36
|
+
Dir.chdir('src') do
|
37
|
+
FileUtils.rm_rf(dir) if File.exists?(dir)
|
38
|
+
|
39
|
+
sys("tar zxvf #{libelf}")
|
40
|
+
Dir.chdir(dir) do
|
41
|
+
sys("./configure --prefix=#{CWD}/dst")
|
42
|
+
sys("make")
|
43
|
+
sys("make install")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Dir.chdir('dst/lib') do
|
48
|
+
FileUtils.ln_s 'libelf.so', 'libelf_ext.so'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
$LIBPATH.unshift "#{CWD}/dst/lib"
|
53
|
+
$INCFLAGS[0,0] = "-I#{CWD}/dst/include "
|
54
|
+
|
55
|
+
unless have_library('elf', 'gelf_getshdr')
|
56
|
+
raise 'libelf build failed'
|
57
|
+
end
|
58
|
+
|
59
|
+
is_elf = true
|
60
|
+
add_define 'HAVE_ELF'
|
61
|
+
end
|
62
|
+
|
63
|
+
if have_header('mach-o/dyld')
|
64
|
+
is_macho = true
|
65
|
+
add_define 'HAVE_MACH'
|
66
|
+
end
|
67
|
+
|
68
|
+
if is_elf or is_macho
|
17
69
|
create_makefile('memprof')
|
70
|
+
else
|
71
|
+
raise 'unsupported platform'
|
18
72
|
end
|
data/ext/mach.c
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#include "bin_api.h"
|
4
4
|
|
5
5
|
#include <limits.h>
|
6
|
+
#include <string.h>
|
6
7
|
#include <sysexits.h>
|
7
8
|
#include <sys/mman.h>
|
8
9
|
|
@@ -43,11 +44,13 @@ bin_allocate_page()
|
|
43
44
|
size_t i = 0;
|
44
45
|
|
45
46
|
for (i = pagesize; i < INT_MAX - pagesize; i += pagesize) {
|
46
|
-
ret = mmap((void*)(NULL + i),
|
47
|
+
ret = mmap((void*)(NULL + i), pagesize, PROT_WRITE|PROT_READ|PROT_EXEC,
|
47
48
|
MAP_ANON|MAP_PRIVATE, -1, 0);
|
48
49
|
|
49
|
-
if (tramp_table != MAP_FAILED)
|
50
|
+
if (tramp_table != MAP_FAILED) {
|
51
|
+
memset(tramp_table, 0x90, pagesize);
|
50
52
|
return ret;
|
53
|
+
}
|
51
54
|
}
|
52
55
|
return NULL;
|
53
56
|
}
|
data/ext/memprof.c
CHANGED
@@ -102,6 +102,7 @@ objs_free(st_data_t key, st_data_t record, st_data_t arg)
|
|
102
102
|
{
|
103
103
|
struct obj_track *tracker = (struct obj_track *)record;
|
104
104
|
free(tracker->source);
|
105
|
+
free(tracker);
|
105
106
|
return ST_DELETE;
|
106
107
|
}
|
107
108
|
|
@@ -150,7 +151,7 @@ struct results {
|
|
150
151
|
};
|
151
152
|
|
152
153
|
static int
|
153
|
-
|
154
|
+
objs_to_array(st_data_t key, st_data_t record, st_data_t arg)
|
154
155
|
{
|
155
156
|
struct results *res = (struct results *)arg;
|
156
157
|
unsigned long count = (unsigned long)record;
|
@@ -200,6 +201,9 @@ memprof_stats(int argc, VALUE *argv, VALUE self)
|
|
200
201
|
VALUE str;
|
201
202
|
FILE *out = NULL;
|
202
203
|
|
204
|
+
if (!track_objs)
|
205
|
+
rb_raise(rb_eRuntimeError, "object tracking disabled, call Memprof.start first");
|
206
|
+
|
203
207
|
rb_scan_args(argc, argv, "01", &str);
|
204
208
|
|
205
209
|
if (RTEST(str)) {
|
@@ -216,10 +220,11 @@ memprof_stats(int argc, VALUE *argv, VALUE self)
|
|
216
220
|
res.num_entries = 0;
|
217
221
|
res.entries = malloc(sizeof(char*) * tmp_table->num_entries);
|
218
222
|
|
219
|
-
st_foreach(tmp_table,
|
223
|
+
st_foreach(tmp_table, objs_to_array, (st_data_t)&res);
|
220
224
|
st_free_table(tmp_table);
|
221
225
|
|
222
226
|
qsort(res.entries, res.num_entries, sizeof(char*), &memprof_strcmp);
|
227
|
+
|
223
228
|
for (i=0; i < res.num_entries; i++) {
|
224
229
|
fprintf(out ? out : stderr, "%s\n", res.entries[i]);
|
225
230
|
free(res.entries[i]);
|
@@ -254,7 +259,8 @@ memprof_track(int argc, VALUE *argv, VALUE self)
|
|
254
259
|
static void
|
255
260
|
create_tramp_table()
|
256
261
|
{
|
257
|
-
int i
|
262
|
+
int i = 0;
|
263
|
+
void *region = NULL;
|
258
264
|
|
259
265
|
struct tramp_tbl_entry ent = {
|
260
266
|
.rbx_save = {'\x53'}, // push rbx
|
@@ -291,22 +297,20 @@ create_tramp_table()
|
|
291
297
|
.jmp_displacement = 0,
|
292
298
|
};
|
293
299
|
|
294
|
-
if ((
|
295
|
-
fprintf(stderr, "Failed to allocate memory for stage 1
|
300
|
+
if ((region = bin_allocate_page()) == MAP_FAILED) {
|
301
|
+
fprintf(stderr, "Failed to allocate memory for stage 1 trampolines.\n");
|
296
302
|
return;
|
297
303
|
}
|
298
304
|
|
299
|
-
|
300
|
-
|
301
|
-
return;
|
302
|
-
}
|
305
|
+
tramp_table = region;
|
306
|
+
inline_tramp_table = region + pagesize/2;
|
303
307
|
|
304
|
-
for (
|
305
|
-
memcpy(tramp_table +
|
308
|
+
for (i = 0; i < (pagesize/2)/sizeof(struct tramp_tbl_entry); i++) {
|
309
|
+
memcpy(tramp_table + i, &ent, sizeof(struct tramp_tbl_entry));
|
306
310
|
}
|
307
311
|
|
308
|
-
for (
|
309
|
-
memcpy(inline_tramp_table +
|
312
|
+
for (i = 0; i < (pagesize/2)/sizeof(struct inline_tramp_tbl_entry); i++) {
|
313
|
+
memcpy(inline_tramp_table + i, &inline_ent, sizeof(struct inline_tramp_tbl_entry));
|
310
314
|
}
|
311
315
|
}
|
312
316
|
|
Binary file
|
data/memprof.gemspec
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'memprof'
|
3
|
-
s.version = '0.1.
|
4
|
-
s.date = '2009-12-
|
3
|
+
s.version = '0.1.3'
|
4
|
+
s.date = '2009-12-14'
|
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"
|
7
7
|
s.email = "ice799@gmail.com"
|
8
8
|
s.homepage = "http://github.com/ice799/memprof"
|
9
9
|
s.has_rdoc = false
|
10
|
-
s.authors = ["Joe Damato"]
|
10
|
+
s.authors = ["Joe Damato", "Aman Gupta", "Jake Douglas"]
|
11
11
|
s.extensions = "ext/extconf.rb"
|
12
12
|
s.files = %w[
|
13
13
|
.gitignore
|
@@ -17,6 +17,7 @@ spec = Gem::Specification.new do |s|
|
|
17
17
|
ext/extconf.rb
|
18
18
|
ext/mach.c
|
19
19
|
ext/memprof.c
|
20
|
+
ext/src/libelf-0.8.13.tar.gz
|
20
21
|
memprof.gemspec
|
21
22
|
]
|
22
23
|
end
|
metadata
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Damato
|
8
|
+
- Aman Gupta
|
9
|
+
- Jake Douglas
|
8
10
|
autorequire:
|
9
11
|
bindir: bin
|
10
12
|
cert_chain: []
|
11
13
|
|
12
|
-
date: 2009-12-
|
14
|
+
date: 2009-12-14 00:00:00 -08:00
|
13
15
|
default_executable:
|
14
16
|
dependencies: []
|
15
17
|
|
@@ -29,6 +31,7 @@ files:
|
|
29
31
|
- ext/extconf.rb
|
30
32
|
- ext/mach.c
|
31
33
|
- ext/memprof.c
|
34
|
+
- ext/src/libelf-0.8.13.tar.gz
|
32
35
|
- memprof.gemspec
|
33
36
|
has_rdoc: true
|
34
37
|
homepage: http://github.com/ice799/memprof
|