memprof 0.1.2 → 0.1.3
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.
- 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
|