memprof 0.2.0 → 0.2.1

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/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