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 CHANGED
@@ -15,7 +15,7 @@
15
15
  void *
16
16
  arch_get_st2_tramp(size_t *size);
17
17
 
18
- void
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 = malloc(sizeof(*ruby_info));
541
+ ruby_info = calloc(1, sizeof(*ruby_info));
539
542
 
540
543
  if (!ruby_info)
541
544
  return;
@@ -30,7 +30,7 @@ end
30
30
  ###
31
31
  # yajl
32
32
 
33
- yajl = File.basename('yajl-1.0.8.tar.gz')
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
- if arch == 'universal'
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
 
@@ -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, FIX2INT(obj));
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, rb_id2name(id));
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, "address");
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
- yajl_gen_map_close(gen);
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
- fwrite(str, sizeof(char), len, out ? out : stdout);
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 = 1, .indentString = " " };
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
@@ -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 rbx_save;
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
- .rbx_save = 0x53, // push rbx
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 = {'\xff', '\xd3'}, // call rbx
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
 
@@ -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
- void
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 *
@@ -1,7 +1,7 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'memprof'
3
- s.version = '0.2.0'
4
- s.date = '2009-12-14'
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.8.tar.gz
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.0
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: 2009-12-14 00:00:00 -08:00
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.8.tar.gz
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
Binary file