memprof 0.2.7 → 0.2.9

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.
@@ -0,0 +1,143 @@
1
+ #include <ruby.h>
2
+
3
+ #ifndef _GNU_SOURCE
4
+ #define _GNU_SOURCE
5
+ #endif
6
+
7
+ #include <sysexits.h>
8
+ #include <sys/mman.h>
9
+ #include <err.h>
10
+ #include <assert.h>
11
+
12
+ #include "arch.h"
13
+ #include "bin_api.h"
14
+ #include "util.h"
15
+
16
+ #define FREELIST_INLINES 3
17
+
18
+ /*
19
+ * trampoline specific stuff
20
+ */
21
+ static struct tramp_st2_entry *tramp_table;
22
+ static size_t tramp_size;
23
+
24
+ /*
25
+ * inline trampoline specific stuff
26
+ */
27
+ static size_t inline_tramp_size;
28
+ static struct inline_tramp_st2_entry *inline_tramp_table;
29
+
30
+ extern struct memprof_config memprof_config;
31
+
32
+ void
33
+ create_tramp_table()
34
+ {
35
+ size_t i;
36
+ void *region, *ent, *inline_ent;
37
+ size_t tramp_sz = 0, inline_tramp_sz = 0;
38
+
39
+ ent = arch_get_st2_tramp(&tramp_sz);
40
+ inline_ent = arch_get_inline_st2_tramp(&inline_tramp_sz);
41
+ assert(ent && inline_ent);
42
+
43
+ region = bin_allocate_page();
44
+ if (region == MAP_FAILED)
45
+ errx(EX_SOFTWARE, "Failed to allocate memory for stage 1 trampolines.");
46
+
47
+ tramp_table = region;
48
+ inline_tramp_table = region + memprof_config.pagesize / 2;
49
+
50
+ for (i = 0; i < (memprof_config.pagesize / 2) / tramp_sz; i++) {
51
+ memcpy(tramp_table + i, ent, tramp_sz);
52
+ }
53
+
54
+ for (i = 0; i < (memprof_config.pagesize / 2) / inline_tramp_sz; i++) {
55
+ memcpy(inline_tramp_table + i, inline_ent, inline_tramp_sz);
56
+ }
57
+ }
58
+
59
+ static void
60
+ hook_freelist(int entry, void *tramp)
61
+ {
62
+ size_t sizes[FREELIST_INLINES];
63
+ void *freelist_inliners[FREELIST_INLINES];
64
+ void *freelist = NULL;
65
+ unsigned char *byte = NULL;
66
+ int i = 0, tramps_completed = 0;
67
+
68
+ assert(memprof_config.gc_sweep != NULL);
69
+ assert(memprof_config.finalize_list != NULL);
70
+ assert(memprof_config.rb_gc_force_recycle != NULL);
71
+ assert(memprof_config.freelist != NULL);
72
+ assert(memprof_config.gc_sweep_size > 0);
73
+ assert(memprof_config.finalize_list_size > 0);
74
+ assert(memprof_config.rb_gc_force_recycle_size > 0);
75
+
76
+ freelist_inliners[0] = memprof_config.gc_sweep;
77
+ freelist_inliners[1] = memprof_config.finalize_list;
78
+ freelist_inliners[2] = memprof_config.rb_gc_force_recycle;
79
+ sizes[0] = memprof_config.gc_sweep_size;
80
+ sizes[1] = memprof_config.finalize_list_size;
81
+ sizes[2] = memprof_config.rb_gc_force_recycle_size;
82
+
83
+ freelist = memprof_config.freelist;
84
+
85
+ /* start the search for places to insert the inline tramp */
86
+ byte = freelist_inliners[i];
87
+
88
+ while (i < FREELIST_INLINES) {
89
+ if (arch_insert_inline_st2_tramp(byte, freelist, tramp,
90
+ &inline_tramp_table[entry]) == 0) {
91
+ /* insert occurred, so increment internal counters for the tramp table */
92
+ entry++;
93
+ inline_tramp_size++;
94
+
95
+ /*
96
+ * add_freelist() only gets inlined *ONCE* into any of the 3 functions
97
+ * that we're scanning, so move on to the next 'inliner' after we
98
+ * tramp the first instruction we find. REE's gc_sweep has 2 calls,
99
+ * but this gets optimized into a single inlining and a jmp to it.
100
+ * older patchlevels of 1.8.7 don't have an add_freelist(), but the
101
+ * instruction should be the same.
102
+ */
103
+ tramps_completed++;
104
+ i++;
105
+ byte = freelist_inliners[i];
106
+ continue;
107
+ }
108
+
109
+ /* if we've looked at all the bytes in this function... */
110
+ if (((void *)byte - freelist_inliners[i]) >= sizes[i]) {
111
+ /* move on to the next function */
112
+ i++;
113
+ byte = freelist_inliners[i];
114
+ }
115
+ byte++;
116
+ }
117
+
118
+ if (tramps_completed != 3)
119
+ errx(EX_SOFTWARE, "Inline add_freelist tramp insertion failed! "
120
+ "Only inserted %d tramps.", tramps_completed);
121
+ }
122
+
123
+ void
124
+ insert_tramp(const char *trampee, void *tramp)
125
+ {
126
+ void *trampee_addr = bin_find_symbol(trampee, NULL);
127
+ int inline_ent = inline_tramp_size;
128
+
129
+ if (trampee_addr == NULL) {
130
+ if (strcmp("add_freelist", trampee) == 0) {
131
+ /* XXX super hack */
132
+ inline_tramp_size++;
133
+ hook_freelist(inline_ent, tramp /* freelist_tramp() */);
134
+ } else {
135
+ errx(EX_SOFTWARE, "Failed to locate required symbol %s", trampee);
136
+ }
137
+ } else {
138
+ tramp_table[tramp_size].addr = tramp;
139
+ if (bin_update_image(trampee, &tramp_table[tramp_size]) != 0)
140
+ errx(EX_SOFTWARE, "Failed to insert tramp for %s", trampee);
141
+ tramp_size++;
142
+ }
143
+ }
@@ -0,0 +1,23 @@
1
+ #if !defined(TRAMP__)
2
+ #define TRAMP__
3
+
4
+ /*
5
+ * create_tramp_table - create the trampoline tables.
6
+ */
7
+ void
8
+ create_tramp_table();
9
+
10
+ /*
11
+ * insert_tramp - insert a trampoline.
12
+ *
13
+ * Given:
14
+ * - trampee: function in which we want to install the trampoline.
15
+ * - tramp: pointer to the function to be called from the trampoline.
16
+ *
17
+ * This function is responsible for installing the requested trampoline
18
+ * at the location of "trampee". This results in tramp() being called
19
+ * whenever trampee() is executed.
20
+ */
21
+ void
22
+ insert_tramp(const char *trampee, void *tramp);
23
+ #endif
@@ -0,0 +1,72 @@
1
+ /* This is the CRC function used by GNU. Stripped executables may contain a
2
+ * section .gnu_debuglink which holds the name of an elf object with debug
3
+ * information and a checksum.
4
+ */
5
+ #include <stdlib.h>
6
+ /* !!!! DO NOT MODIFY THIS FUNCTION !!!!
7
+ * TODO create specs for this!
8
+ */
9
+ unsigned long
10
+ gnu_debuglink_crc32(unsigned long crc, unsigned char *buf, size_t len)
11
+ {
12
+ static const unsigned int crc32_table[256] = {
13
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
14
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
15
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
16
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
17
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
18
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
19
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
20
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
21
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
22
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
23
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
24
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
25
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
26
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
27
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
28
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
29
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
30
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
31
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
32
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
33
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
34
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
35
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
36
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
37
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
38
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
39
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
40
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
41
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
42
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
43
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
44
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
45
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
46
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
47
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
48
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
49
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
50
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
51
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
52
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
53
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
54
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
55
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
56
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
57
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
58
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
59
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
60
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
61
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
62
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
63
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
64
+ 0x2d02ef8d
65
+ };
66
+ unsigned char *end;
67
+
68
+ crc = ~crc & 0xffffffff;
69
+ for (end = buf + len; buf < end; ++buf)
70
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
71
+ return ~crc & 0xffffffff;
72
+ }
@@ -0,0 +1,40 @@
1
+ #if !defined(__util_h__)
2
+ #define __util_h__
3
+
4
+ #if defined(_MEMPROF_DEBUG)
5
+ #define dbg_printf(...) fprintf(stderr, __VA_ARGS__)
6
+ #else
7
+ #define dbg_printf(...)
8
+ #endif
9
+
10
+ #define ASSERT_ON_COMPILE(pred) \
11
+ switch(0){case 0:case pred:;}
12
+
13
+ struct memprof_config {
14
+ void *gc_sweep;
15
+ size_t gc_sweep_size;
16
+ void *finalize_list;
17
+ size_t finalize_list_size;
18
+ void *rb_gc_force_recycle;
19
+ size_t rb_gc_force_recycle_size;
20
+ void *freelist;
21
+ void *classname;
22
+ void *add_freelist;
23
+ void *rb_mark_table_add_filename;
24
+ void *heaps;
25
+ void *heaps_used;
26
+ size_t sizeof_RVALUE;
27
+ size_t sizeof_heaps_slot;
28
+ int offset_heaps_slot_limit;
29
+ int offset_heaps_slot_slot;
30
+ size_t pagesize;
31
+ };
32
+
33
+ /* This is the CRC function used by GNU. Stripped executables may contain a
34
+ * section .gnu_debuglink which holds the name of an elf object with debug
35
+ * information and a checksum.
36
+ */
37
+ unsigned long
38
+ gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len);
39
+
40
+ #endif
@@ -6,6 +6,7 @@
6
6
 
7
7
  #include "arch.h"
8
8
  #include "x86_gen.h"
9
+ #include "util.h"
9
10
 
10
11
  /*
11
12
  * inline_st1_tramp - inline stage 1 trampoline
@@ -124,8 +125,7 @@ arch_insert_inline_st2_tramp(void *addr, void *marker, void *trampoline, void *t
124
125
  struct inline_st1_base *base = addr;
125
126
  struct inline_tramp_st2_entry *entry = table_entry;
126
127
 
127
- /* TODO make this a compile time assert */
128
- assert(sizeof(struct inline_st1_base) ==
128
+ ASSERT_ON_COMPILE(sizeof(struct inline_st1_base) ==
129
129
  sizeof(struct inline_st1_tramp));
130
130
 
131
131
  if (!arch_check_ins(base))
@@ -3,6 +3,7 @@ Memprof.start
3
3
  trap('USR2'){
4
4
  pid = Process.pid
5
5
  fork{
6
+ GC.start
6
7
  Memprof.dump_all("/tmp/memprof-#{pid}-#{Time.now.to_i}.json")
7
8
  exit!
8
9
  }
@@ -1,12 +1,12 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'memprof'
3
- s.version = '0.2.7'
4
- s.date = '2010-03-13'
3
+ s.version = '0.2.9'
4
+ s.date = '2010-03-15'
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.homepage = "http://github.com/ice799/memprof"
8
8
  s.has_rdoc = false
9
- s.authors = ["Joe Damato", "Aman Gupta", "Jake Douglas"]
9
+ s.authors = ["Joe Damato", "Aman Gupta", "Jake Douglas", "Rob Benson"]
10
10
  s.email = ["joe@memprof.com", "aman@memprof.com", "jake@memprof.com"]
11
11
  s.extensions = "ext/extconf.rb"
12
12
  s.files = `git ls-files`.split
metadata CHANGED
@@ -1,17 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memprof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 9
9
+ version: 0.2.9
5
10
  platform: ruby
6
11
  authors:
7
12
  - Joe Damato
8
13
  - Aman Gupta
9
14
  - Jake Douglas
15
+ - Rob Benson
10
16
  autorequire:
11
17
  bindir: bin
12
18
  cert_chain: []
13
19
 
14
- date: 2010-03-13 00:00:00 -08:00
20
+ date: 2010-03-15 00:00:00 -07:00
15
21
  default_executable:
16
22
  dependencies: []
17
23
 
@@ -41,6 +47,10 @@ files:
41
47
  - ext/src/libdwarf-20091118.tar.gz
42
48
  - ext/src/libelf-0.8.13.tar.gz
43
49
  - ext/src/yajl-1.0.9.tar.gz
50
+ - ext/tramp.c
51
+ - ext/tramp.h
52
+ - ext/util.c
53
+ - ext/util.h
44
54
  - ext/x86_64.c
45
55
  - ext/x86_64.h
46
56
  - ext/x86_gen.h
@@ -61,18 +71,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
71
  requirements:
62
72
  - - ">="
63
73
  - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
64
76
  version: "0"
65
- version:
66
77
  required_rubygems_version: !ruby/object:Gem::Requirement
67
78
  requirements:
68
79
  - - ">="
69
80
  - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
70
83
  version: "0"
71
- version:
72
84
  requirements: []
73
85
 
74
86
  rubyforge_project:
75
- rubygems_version: 1.3.5
87
+ rubygems_version: 1.3.6
76
88
  signing_key:
77
89
  specification_version: 3
78
90
  summary: Ruby Memory Profiler