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 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
- return mmap(NULL, pagesize, PROT_WRITE|PROT_READ|PROT_EXEC, MAP_ANON|MAP_PRIVATE|MAP_32BIT, -1, 0);
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
- /* now loop through the symbol table and print it*/
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 (elf_getshstrndx(elf, &shstrndx) == 0)
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
- if (add_define("HAVE_ELF") if have_library('elf', 'gelf_getshdr')) ||
16
- (add_define("HAVE_MACH") if have_header('mach-o/dyld.h'))
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), 2*pagesize, PROT_WRITE|PROT_READ|PROT_EXEC,
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
- memprof_do_dump(st_data_t key, st_data_t record, st_data_t arg)
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, memprof_do_dump, (st_data_t)&res);
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, j = 0;
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 ((tramp_table = bin_allocate_page()) == MAP_FAILED) {
295
- fprintf(stderr, "Failed to allocate memory for stage 1 trampoline.\n");
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
- if ((inline_tramp_table = bin_allocate_page()) == MAP_FAILED) {
300
- fprintf(stderr, "Faied to allocate memory for the stage 1 inline trampoline.\n");
301
- return;
302
- }
305
+ tramp_table = region;
306
+ inline_tramp_table = region + pagesize/2;
303
307
 
304
- for (j = 0; j < pagesize/sizeof(struct tramp_tbl_entry); j ++ ) {
305
- memcpy(tramp_table + j, &ent, sizeof(struct tramp_tbl_entry));
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 (j = 0; j < pagesize/sizeof(struct inline_tramp_tbl_entry); j++) {
309
- memcpy(inline_tramp_table + j, &inline_ent, sizeof(struct inline_tramp_tbl_entry));
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.2'
4
- s.date = '2009-12-10'
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.2
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-10 00:00:00 -08:00
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