memprof 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/arch.h +4 -1
- data/ext/elf.c +7 -4
- data/ext/extconf.rb +5 -2
- data/ext/memprof.c +36 -15
- data/ext/src/yajl-1.0.9.tar.gz +0 -0
- data/ext/x86_64.h +11 -3
- data/ext/x86_gen.h +3 -2
- data/memprof.gemspec +3 -3
- metadata +3 -3
- data/ext/src/yajl-1.0.8.tar.gz +0 -0
data/ext/arch.h
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
void *
|
16
16
|
arch_get_st2_tramp(size_t *size);
|
17
17
|
|
18
|
-
|
18
|
+
int
|
19
19
|
arch_insert_st1_tramp(void *start, void *trampee, void *tramp);
|
20
20
|
|
21
21
|
/*
|
@@ -27,4 +27,7 @@ arch_get_inline_st2_tramp(size_t *size);
|
|
27
27
|
int
|
28
28
|
arch_insert_inline_st2_tramp(void *addr, void *marker, void *trampoline, void *table_entry);
|
29
29
|
|
30
|
+
void
|
31
|
+
arch_overwrite_got(void *plt, void *tramp);
|
32
|
+
|
30
33
|
#endif
|
data/ext/elf.c
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
#include <dwarf.h>
|
7
7
|
#include <err.h>
|
8
|
+
#include <error.h>
|
8
9
|
#include <fcntl.h>
|
9
10
|
#include <libdwarf.h>
|
10
11
|
#include <libelf/gelf.h>
|
@@ -102,7 +103,6 @@ find_got_addr(char *symname, void *cookie)
|
|
102
103
|
}
|
103
104
|
|
104
105
|
for (i = 0; i < info->relplt_count; ++i) {
|
105
|
-
GElf_Rel rel;
|
106
106
|
GElf_Rela rela;
|
107
107
|
GElf_Sym sym;
|
108
108
|
GElf_Addr addr;
|
@@ -169,9 +169,13 @@ bin_update_image(int entry, char *trampee, struct tramp_st2_entry *tramp)
|
|
169
169
|
unsigned char *byte = ruby_info->text_segment;
|
170
170
|
trampee_addr = bin_find_symbol(trampee, NULL);
|
171
171
|
size_t count = 0;
|
172
|
+
int num = 0;
|
172
173
|
|
173
174
|
for(; count < ruby_info->text_segment_len; byte++, count++) {
|
174
|
-
arch_insert_st1_tramp(byte, trampee_addr, tramp)
|
175
|
+
if (arch_insert_st1_tramp(byte, trampee_addr, tramp)) {
|
176
|
+
// printf("tramped %x\n", byte);
|
177
|
+
num++;
|
178
|
+
}
|
175
179
|
}
|
176
180
|
} else {
|
177
181
|
trampee_addr = find_got_addr(trampee, NULL);
|
@@ -427,7 +431,6 @@ dissect_elf(struct elf_info *info)
|
|
427
431
|
{
|
428
432
|
size_t shstrndx = 0;
|
429
433
|
Elf *elf = info->elf;
|
430
|
-
ElfW(Dyn) *dyn;
|
431
434
|
Elf_Scn *scn = NULL;
|
432
435
|
GElf_Shdr shdr;
|
433
436
|
size_t j = 0;
|
@@ -535,7 +538,7 @@ bin_init()
|
|
535
538
|
{
|
536
539
|
Dwarf_Error dwrf_err;
|
537
540
|
|
538
|
-
ruby_info =
|
541
|
+
ruby_info = calloc(1, sizeof(*ruby_info));
|
539
542
|
|
540
543
|
if (!ruby_info)
|
541
544
|
return;
|
data/ext/extconf.rb
CHANGED
@@ -30,7 +30,7 @@ end
|
|
30
30
|
###
|
31
31
|
# yajl
|
32
32
|
|
33
|
-
yajl = File.basename('yajl-1.0.
|
33
|
+
yajl = File.basename('yajl-1.0.9.tar.gz')
|
34
34
|
dir = File.basename(yajl, '.tar.gz')
|
35
35
|
|
36
36
|
unless File.exists?("#{CWD}/dst/lib/libyajl_ext.a")
|
@@ -148,8 +148,11 @@ if have_header('mach-o/dyld')
|
|
148
148
|
end
|
149
149
|
|
150
150
|
arch = RUBY_PLATFORM[/(.*)-linux/,1]
|
151
|
-
|
151
|
+
case arch
|
152
|
+
when "universal"
|
152
153
|
arch = 'x86_64'
|
154
|
+
when 'i486'
|
155
|
+
arch = 'i386'
|
153
156
|
end
|
154
157
|
add_define "_ARCH_#{arch}_"
|
155
158
|
|
data/ext/memprof.c
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
#ifndef _GNU_SOURCE
|
1
4
|
#define _GNU_SOURCE
|
5
|
+
#endif
|
6
|
+
|
2
7
|
#include <err.h>
|
3
8
|
#include <fcntl.h>
|
4
9
|
#include <stddef.h>
|
@@ -11,13 +16,13 @@
|
|
11
16
|
#include <err.h>
|
12
17
|
|
13
18
|
#include <st.h>
|
14
|
-
#include <ruby.h>
|
15
19
|
#include <intern.h>
|
16
20
|
#include <node.h>
|
17
21
|
|
18
22
|
#include "arch.h"
|
19
23
|
#include "bin_api.h"
|
20
24
|
|
25
|
+
|
21
26
|
size_t pagesize;
|
22
27
|
|
23
28
|
/*
|
@@ -51,7 +56,7 @@ newobj_tramp()
|
|
51
56
|
VALUE ret = rb_newobj();
|
52
57
|
struct obj_track *tracker = NULL;
|
53
58
|
|
54
|
-
if (track_objs) {
|
59
|
+
if (track_objs && objs) {
|
55
60
|
tracker = malloc(sizeof(*tracker));
|
56
61
|
|
57
62
|
if (tracker) {
|
@@ -67,7 +72,9 @@ newobj_tramp()
|
|
67
72
|
}
|
68
73
|
|
69
74
|
tracker->obj = ret;
|
75
|
+
rb_gc_disable();
|
70
76
|
st_insert(objs, (st_data_t)ret, (st_data_t)tracker);
|
77
|
+
rb_gc_enable();
|
71
78
|
} else {
|
72
79
|
fprintf(stderr, "Warning, unable to allocate a tracker. You are running dangerously low on RAM!\n");
|
73
80
|
}
|
@@ -80,7 +87,7 @@ static void
|
|
80
87
|
freelist_tramp(unsigned long rval)
|
81
88
|
{
|
82
89
|
struct obj_track *tracker = NULL;
|
83
|
-
if (track_objs) {
|
90
|
+
if (track_objs && objs) {
|
84
91
|
st_delete(objs, (st_data_t *) &rval, (st_data_t *) &tracker);
|
85
92
|
if (tracker) {
|
86
93
|
free(tracker->source);
|
@@ -285,7 +292,7 @@ yajl_gen_status
|
|
285
292
|
yajl_gen_value(yajl_gen gen, VALUE obj)
|
286
293
|
{
|
287
294
|
if (FIXNUM_P(obj))
|
288
|
-
return yajl_gen_integer(gen,
|
295
|
+
return yajl_gen_integer(gen, NUM2LONG(obj));
|
289
296
|
else if (NIL_P(obj) || obj == Qundef)
|
290
297
|
return yajl_gen_null(gen);
|
291
298
|
else if (obj == Qtrue)
|
@@ -305,8 +312,10 @@ each_hash_entry(st_data_t key, st_data_t record, st_data_t arg)
|
|
305
312
|
VALUE k = (VALUE)key;
|
306
313
|
VALUE v = (VALUE)record;
|
307
314
|
|
315
|
+
yajl_gen_array_open(gen);
|
308
316
|
yajl_gen_value(gen, k);
|
309
317
|
yajl_gen_value(gen, v);
|
318
|
+
yajl_gen_array_close(gen);
|
310
319
|
|
311
320
|
return ST_CONTINUE;
|
312
321
|
}
|
@@ -317,8 +326,9 @@ each_ivar(st_data_t key, st_data_t record, st_data_t arg)
|
|
317
326
|
yajl_gen gen = (yajl_gen)arg;
|
318
327
|
ID id = (ID)key;
|
319
328
|
VALUE val = (VALUE)record;
|
329
|
+
const char *name = rb_id2name(id);
|
320
330
|
|
321
|
-
yajl_gen_cstr(gen,
|
331
|
+
yajl_gen_cstr(gen, name ? name : "(none)");
|
322
332
|
yajl_gen_value(gen, val);
|
323
333
|
|
324
334
|
return ST_CONTINUE;
|
@@ -376,7 +386,7 @@ obj_dump(VALUE obj, yajl_gen gen)
|
|
376
386
|
int type;
|
377
387
|
yajl_gen_map_open(gen);
|
378
388
|
|
379
|
-
yajl_gen_cstr(gen, "
|
389
|
+
yajl_gen_cstr(gen, "_id");
|
380
390
|
yajl_gen_value(gen, obj);
|
381
391
|
|
382
392
|
struct obj_track *tracker = NULL;
|
@@ -632,9 +642,11 @@ obj_dump(VALUE obj, yajl_gen gen)
|
|
632
642
|
|
633
643
|
if (hash->tbl && hash->tbl->num_entries) {
|
634
644
|
yajl_gen_cstr(gen, "data");
|
635
|
-
yajl_gen_map_open(gen);
|
645
|
+
//yajl_gen_map_open(gen);
|
646
|
+
yajl_gen_array_open(gen);
|
636
647
|
st_foreach(hash->tbl, each_hash_entry, (st_data_t)gen);
|
637
|
-
|
648
|
+
yajl_gen_array_close(gen);
|
649
|
+
//yajl_gen_map_close(gen);
|
638
650
|
}
|
639
651
|
break;
|
640
652
|
|
@@ -659,7 +671,11 @@ void
|
|
659
671
|
json_print(void *ctx, const char * str, unsigned int len)
|
660
672
|
{
|
661
673
|
FILE *out = (FILE *)ctx;
|
662
|
-
|
674
|
+
size_t written = 0;
|
675
|
+
while(1) {
|
676
|
+
written += fwrite(str + written, sizeof(char), len - written, out ? out : stdout);
|
677
|
+
if (written == len) break;
|
678
|
+
}
|
663
679
|
}
|
664
680
|
|
665
681
|
static VALUE
|
@@ -723,12 +739,12 @@ memprof_dump_all(int argc, VALUE *argv, VALUE self)
|
|
723
739
|
rb_raise(rb_eArgError, "unable to open output file");
|
724
740
|
}
|
725
741
|
|
726
|
-
yajl_gen_config conf = { .beautify =
|
742
|
+
yajl_gen_config conf = { .beautify = 0, .indentString = " " };
|
727
743
|
yajl_gen gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out);
|
728
744
|
|
729
745
|
track_objs = 0;
|
730
746
|
|
731
|
-
yajl_gen_array_open(gen);
|
747
|
+
//yajl_gen_array_open(gen);
|
732
748
|
|
733
749
|
for (i=0; i < heaps_used; i++) {
|
734
750
|
p = *(char**)(heaps + (i * sizeof_heaps_slot) + offset_slot);
|
@@ -736,14 +752,21 @@ memprof_dump_all(int argc, VALUE *argv, VALUE self)
|
|
736
752
|
pend = p + (sizeof_RVALUE * limit);
|
737
753
|
|
738
754
|
while (p < pend) {
|
739
|
-
if (RBASIC(p)->flags)
|
755
|
+
if (RBASIC(p)->flags) {
|
740
756
|
obj_dump((VALUE)p, gen);
|
757
|
+
// XXX ugh
|
758
|
+
yajl_gen_clear(gen);
|
759
|
+
yajl_gen_free(gen);
|
760
|
+
gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out);
|
761
|
+
while(fputc('\n', out ? out : stdout) == EOF);
|
762
|
+
}
|
741
763
|
|
742
764
|
p += sizeof_RVALUE;
|
743
765
|
}
|
744
766
|
}
|
745
767
|
|
746
|
-
yajl_gen_array_close(gen);
|
768
|
+
//yajl_gen_array_close(gen);
|
769
|
+
yajl_gen_clear(gen);
|
747
770
|
yajl_gen_free(gen);
|
748
771
|
|
749
772
|
if (out)
|
@@ -846,10 +869,8 @@ static void
|
|
846
869
|
insert_tramp(char *trampee, void *tramp)
|
847
870
|
{
|
848
871
|
void *trampee_addr = bin_find_symbol(trampee, NULL);
|
849
|
-
void *plt_addr = NULL;
|
850
872
|
int entry = tramp_size;
|
851
873
|
int inline_ent = inline_tramp_size;
|
852
|
-
void *info;
|
853
874
|
|
854
875
|
if (trampee_addr == NULL) {
|
855
876
|
if (strcmp("add_freelist", trampee) == 0) {
|
Binary file
|
data/ext/x86_64.h
CHANGED
@@ -8,18 +8,26 @@
|
|
8
8
|
* This is the "normal" stage 2 trampoline with a default entry pre-filled
|
9
9
|
*/
|
10
10
|
static struct tramp_st2_entry {
|
11
|
-
unsigned char
|
11
|
+
unsigned char push_rbx;
|
12
|
+
unsigned char push_rbp;
|
13
|
+
unsigned char save_rsp[3];
|
14
|
+
unsigned char align_rsp[4];
|
12
15
|
unsigned char mov[2];
|
13
16
|
void *addr;
|
14
17
|
unsigned char call[2];
|
18
|
+
unsigned char leave;
|
15
19
|
unsigned char rbx_restore;
|
16
20
|
unsigned char ret;
|
17
21
|
} __attribute__((__packed__)) default_st2_tramp = {
|
18
|
-
.
|
22
|
+
.push_rbx = 0x53, // push rbx
|
23
|
+
.push_rbp = 0x55, // push rbp
|
24
|
+
.save_rsp = {0x48, 0x89, 0xe5}, // mov rsp, rbp
|
25
|
+
.align_rsp = {0x48, 0x83, 0xe4, 0xf0}, // andl ~0x1, rsp
|
19
26
|
.mov = {'\x48', '\xbb'}, // mov addr into rbx
|
20
27
|
.addr = 0, // ^^^
|
21
|
-
.call
|
28
|
+
.call = {'\xff', '\xd3'}, // call rbx
|
22
29
|
.rbx_restore = 0x5b, // pop rbx
|
30
|
+
.leave = 0xc9, // leave
|
23
31
|
.ret = 0xc3, // ret
|
24
32
|
};
|
25
33
|
|
data/ext/x86_gen.h
CHANGED
@@ -45,7 +45,7 @@ copy_instructions(void *to, void *from, size_t count)
|
|
45
45
|
mprotect(start, len, PROT_READ | PROT_EXEC); \
|
46
46
|
} while (0)
|
47
47
|
|
48
|
-
|
48
|
+
int
|
49
49
|
arch_insert_st1_tramp(void *start, void *trampee, void *tramp)
|
50
50
|
{
|
51
51
|
int32_t fn_addr = 0;
|
@@ -58,10 +58,11 @@ arch_insert_st1_tramp(void *start, void *trampee, void *tramp)
|
|
58
58
|
WRITE_INSTRUCTIONS(aligned_addr,
|
59
59
|
((void *)&(check->displacement) - aligned_addr) + 10,
|
60
60
|
(check->displacement = (tramp - (void *)(check + 1))));
|
61
|
+
return 1;
|
61
62
|
}
|
62
63
|
}
|
63
64
|
|
64
|
-
return;
|
65
|
+
return 0;
|
65
66
|
}
|
66
67
|
|
67
68
|
static void *
|
data/memprof.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'memprof'
|
3
|
-
s.version = '0.2.
|
4
|
-
s.date = '
|
3
|
+
s.version = '0.2.1'
|
4
|
+
s.date = '2010-02-20'
|
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"
|
@@ -22,7 +22,7 @@ spec = Gem::Specification.new do |s|
|
|
22
22
|
ext/memprof.c
|
23
23
|
ext/src/libdwarf-20091118.tar.gz
|
24
24
|
ext/src/libelf-0.8.13.tar.gz
|
25
|
-
ext/src/yajl-1.0.
|
25
|
+
ext/src/yajl-1.0.9.tar.gz
|
26
26
|
ext/x86_64.c
|
27
27
|
ext/x86_64.h
|
28
28
|
ext/x86_gen.h
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Damato
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date:
|
14
|
+
date: 2010-02-20 00:00:00 -08:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
@@ -36,7 +36,7 @@ files:
|
|
36
36
|
- ext/memprof.c
|
37
37
|
- ext/src/libdwarf-20091118.tar.gz
|
38
38
|
- ext/src/libelf-0.8.13.tar.gz
|
39
|
-
- ext/src/yajl-1.0.
|
39
|
+
- ext/src/yajl-1.0.9.tar.gz
|
40
40
|
- ext/x86_64.c
|
41
41
|
- ext/x86_64.h
|
42
42
|
- ext/x86_gen.h
|
data/ext/src/yajl-1.0.8.tar.gz
DELETED
Binary file
|