memprof 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/memprof +16 -0
- data/ext/elf.c +31 -29
- data/ext/extconf.rb +11 -5
- data/ext/i386.h +2 -2
- data/ext/json.c +53 -0
- data/ext/json.h +48 -0
- data/ext/mach.c +442 -159
- data/ext/memprof.c +565 -459
- data/ext/mmap.h +73 -0
- data/ext/tracer.c +20 -2
- data/ext/tracer.h +14 -1
- data/ext/tracers/fd.c +204 -0
- data/ext/tracers/gc.c +79 -0
- data/ext/tracers/memcache.c +136 -0
- data/ext/tracers/memory.c +202 -0
- data/ext/tracers/mysql.c +82 -0
- data/ext/tracers/objects.c +160 -0
- data/ext/tramp.c +2 -2
- data/ext/util.c +22 -4
- data/ext/util.h +5 -0
- data/ext/x86_gen.c +3 -3
- data/ext/x86_gen.h +0 -13
- data/lib/memprof/tracer.rb +34 -0
- data/memprof.gemspec +1 -1
- data/spec/memprof_spec.rb +12 -4
- data/spec/tracing_spec.rb +135 -0
- metadata +14 -4
- data/ext/tracers/malloc.c +0 -163
data/ext/util.c
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include <time.h>
|
3
|
+
#include <util.h>
|
4
|
+
|
5
|
+
#include <sys/time.h>
|
6
|
+
|
1
7
|
/* This is the CRC function used by GNU. Stripped executables may contain a
|
2
8
|
* section .gnu_debuglink which holds the name of an elf object with debug
|
3
9
|
* information and a checksum.
|
4
|
-
|
5
|
-
#include <stdlib.h>
|
6
|
-
#include <util.h>
|
7
|
-
/* !!!! DO NOT MODIFY THIS FUNCTION !!!!
|
10
|
+
* !!!! DO NOT MODIFY THIS FUNCTION !!!!
|
8
11
|
* TODO create specs for this!
|
9
12
|
*/
|
10
13
|
unsigned long
|
@@ -71,3 +74,18 @@ gnu_debuglink_crc32(unsigned long crc, unsigned char *buf, size_t len)
|
|
71
74
|
crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
|
72
75
|
return ~crc & 0xffffffff;
|
73
76
|
}
|
77
|
+
|
78
|
+
double
|
79
|
+
timeofday()
|
80
|
+
{
|
81
|
+
struct timeval tv;
|
82
|
+
#ifdef CLOCK_MONOTONIC
|
83
|
+
struct timespec tp;
|
84
|
+
|
85
|
+
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
|
86
|
+
return (double)tp.tv_sec + (double)tp.tv_nsec * 1e-9;
|
87
|
+
}
|
88
|
+
#endif
|
89
|
+
gettimeofday(&tv, NULL);
|
90
|
+
return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
|
91
|
+
}
|
data/ext/util.h
CHANGED
@@ -73,4 +73,9 @@ struct memprof_config {
|
|
73
73
|
unsigned long
|
74
74
|
gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len);
|
75
75
|
|
76
|
+
/* Use this function for time tracking. It will (interally) try to use an
|
77
|
+
* appropriately granual timing function.
|
78
|
+
*/
|
79
|
+
double
|
80
|
+
timeofday();
|
76
81
|
#endif
|
data/ext/x86_gen.c
CHANGED
@@ -27,14 +27,14 @@ arch_insert_st1_tramp(void *start, void *trampee, void *tramp)
|
|
27
27
|
assert(tramp != NULL);
|
28
28
|
|
29
29
|
int32_t fn_addr = 0;
|
30
|
+
int32_t offset = 0;
|
30
31
|
struct st1_base *check = start;
|
31
32
|
|
32
33
|
if (check->call == 0xe8) {
|
33
34
|
fn_addr = check->displacement;
|
34
35
|
if ((trampee - (void *)(check + 1)) == fn_addr) {
|
35
|
-
|
36
|
-
|
37
|
-
(check->displacement = (tramp - (void *)(check + 1))));
|
36
|
+
offset = tramp - (void *)(check + 1);
|
37
|
+
copy_instructions(&check->displacement, &offset, sizeof(offset));
|
38
38
|
return 0;
|
39
39
|
}
|
40
40
|
}
|
data/ext/x86_gen.h
CHANGED
@@ -75,17 +75,4 @@ copy_instructions(void *dest, void *src, size_t count)
|
|
75
75
|
*/
|
76
76
|
return;
|
77
77
|
}
|
78
|
-
|
79
|
-
/*
|
80
|
-
* WRITE_INSTRUCTIONS - page align start, recalculate len to take into account
|
81
|
-
* alignment, set the read/write permissions and execute the code stmt.
|
82
|
-
*/
|
83
|
-
#define WRITE_INSTRUCTIONS(start, len, stmt) do { \
|
84
|
-
void *aligned_addr = page_align((void *)start); \
|
85
|
-
int count = ((void *)start) - aligned_addr + len; \
|
86
|
-
mprotect(aligned_addr, count, PROT_READ | PROT_WRITE | PROT_EXEC); \
|
87
|
-
stmt; \
|
88
|
-
mprotect(aligned_addr, count, PROT_READ | PROT_EXEC); \
|
89
|
-
} while (0)
|
90
|
-
|
91
78
|
#endif
|
@@ -0,0 +1,34 @@
|
|
1
|
+
begin
|
2
|
+
require File.expand_path('../../memprof', __FILE__)
|
3
|
+
rescue LoadError
|
4
|
+
require File.expand_path('../../../ext/memprof', __FILE__)
|
5
|
+
end
|
6
|
+
|
7
|
+
module Memprof
|
8
|
+
# Middleware for tracing requests
|
9
|
+
#
|
10
|
+
# require 'memprof/tracer'
|
11
|
+
# config.middleware.use(Memprof::Tracer)
|
12
|
+
class Tracer
|
13
|
+
def initialize(app)
|
14
|
+
@app=app
|
15
|
+
end
|
16
|
+
def call(env)
|
17
|
+
Memprof.trace_filename ||= "/tmp/memprof_tracer-#{Process.pid}.json"
|
18
|
+
Memprof.trace_request(env){ @app.call(env) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Legacy filter for tracing requests on Rails 2.2
|
23
|
+
#
|
24
|
+
# require 'memprof/tracer'
|
25
|
+
# around_filter(Memprof::Filter)
|
26
|
+
module Filter
|
27
|
+
def self.filter(controller)
|
28
|
+
env = controller.request.env
|
29
|
+
info = controller.request.path_parameters
|
30
|
+
Memprof.trace_filename ||= "/tmp/memprof_tracer-#{Process.pid}.json"
|
31
|
+
Memprof.trace_request(env.merge('action_controller.request.path_parameters' => info)){ yield }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/memprof.gemspec
CHANGED
data/spec/memprof_spec.rb
CHANGED
@@ -61,10 +61,10 @@ describe Memprof do
|
|
61
61
|
1.23+1
|
62
62
|
Memprof.dump(filename)
|
63
63
|
|
64
|
-
filedata.should =~ /"file":
|
65
|
-
filedata.should =~ /"line"
|
66
|
-
filedata.should =~ /"type":
|
67
|
-
filedata.should =~ /"data":
|
64
|
+
filedata.should =~ /"file":"#{__FILE__}"/
|
65
|
+
filedata.should =~ /"line":#{__LINE__-4}/
|
66
|
+
filedata.should =~ /"type":"float"/
|
67
|
+
filedata.should =~ /"data":2\.23/
|
68
68
|
end
|
69
69
|
|
70
70
|
should 'raise error when calling ::stats or ::dump without ::start' do
|
@@ -72,6 +72,14 @@ describe Memprof do
|
|
72
72
|
lambda{ Memprof.dump }.should.raise(RuntimeError).message.should =~ /Memprof.start/
|
73
73
|
end
|
74
74
|
|
75
|
+
should 'dump objects created for block' do
|
76
|
+
Memprof.dump(filename) do
|
77
|
+
2.45+1
|
78
|
+
end
|
79
|
+
|
80
|
+
filedata.should =~ /"data":3\.45/
|
81
|
+
end
|
82
|
+
|
75
83
|
should 'dump out the entire heap' do
|
76
84
|
Memprof.stop
|
77
85
|
Memprof.dump_all(filename)
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../ext/memprof"
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bacon'
|
5
|
+
Bacon.summary_on_exit
|
6
|
+
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
# XXX must require upfront before tracers are installed
|
10
|
+
require 'socket'
|
11
|
+
require 'open-uri'
|
12
|
+
begin; require 'mysql'; rescue LoadError; end
|
13
|
+
begin; require 'memcached'; rescue LoadError; end
|
14
|
+
|
15
|
+
describe 'Memprof tracers' do
|
16
|
+
@tempfile = Tempfile.new('tracing_spec')
|
17
|
+
|
18
|
+
def filename
|
19
|
+
@tempfile.path
|
20
|
+
end
|
21
|
+
|
22
|
+
def filedata
|
23
|
+
File.read(filename)
|
24
|
+
end
|
25
|
+
|
26
|
+
should 'trace i/o for block' do
|
27
|
+
Memprof.trace(filename) do
|
28
|
+
open("http://google.com").read
|
29
|
+
end
|
30
|
+
|
31
|
+
filedata.should =~ /"read":\{"calls":\d+/
|
32
|
+
filedata.should =~ /"write":\{"calls":\d+/
|
33
|
+
filedata.should =~ /"connect":\{"calls":\d+/
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'trace select for block' do
|
37
|
+
Memprof.trace(filename) do
|
38
|
+
select(nil, nil, nil, 0.15)
|
39
|
+
end
|
40
|
+
|
41
|
+
filedata.should =~ /"select":\{"calls":1,"time":0\.1[567]/
|
42
|
+
time = filedata[/"select":\{"calls":\d+,"time":([\d.]+)/, 1].to_f
|
43
|
+
time.should.be.close(0.15, 0.1)
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'trace objects created for block' do
|
47
|
+
Memprof.trace(filename) do
|
48
|
+
10.times{1.1+1.2}
|
49
|
+
end
|
50
|
+
|
51
|
+
filedata.should =~ /"float":10/
|
52
|
+
end
|
53
|
+
|
54
|
+
should 'trace gc runs for block' do
|
55
|
+
Memprof.trace(filename) do
|
56
|
+
10.times{GC.start}
|
57
|
+
end
|
58
|
+
|
59
|
+
filedata.should =~ /"gc":\{"calls":10,"time":[\d.]+/
|
60
|
+
end
|
61
|
+
|
62
|
+
should 'trace memory allocation for block' do
|
63
|
+
Memprof.trace(filename) do
|
64
|
+
10.times{ "abc" << "def" }
|
65
|
+
end
|
66
|
+
|
67
|
+
filedata.should =~ /"malloc":\{"calls":10/
|
68
|
+
filedata.should =~ /"realloc":\{"calls":10/
|
69
|
+
end
|
70
|
+
|
71
|
+
if defined? Mysql
|
72
|
+
begin
|
73
|
+
conn = Mysql.connect('localhost', 'root')
|
74
|
+
|
75
|
+
should 'trace mysql calls for block' do
|
76
|
+
Memprof.trace(filename) do
|
77
|
+
5.times{ conn.query("select sleep(0.05)") }
|
78
|
+
end
|
79
|
+
|
80
|
+
filedata.should =~ /"mysql":\{"queries":5,"time":([\d.]+)/
|
81
|
+
time = filedata[/"mysql":\{"queries":5,"time":([\d.]+)/, 1].to_f
|
82
|
+
time.should.be.close(0.25, 0.1)
|
83
|
+
end
|
84
|
+
rescue Mysql::Error => e
|
85
|
+
raise unless e.message =~ /connect/
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
if defined? Memcached
|
90
|
+
begin
|
91
|
+
conn = Memcached.new("localhost:11211", :show_backtraces => true)
|
92
|
+
conn.stats
|
93
|
+
|
94
|
+
should 'trace memcached calls for block' do
|
95
|
+
Memprof.trace(filename) do
|
96
|
+
conn.delete("memprof") rescue nil
|
97
|
+
conn.get("memprof") rescue nil
|
98
|
+
conn.set("memprof", "is cool")
|
99
|
+
conn.get("memprof")
|
100
|
+
end
|
101
|
+
|
102
|
+
filedata.should =~ /"memcache":\{"get":\{"calls":2,"responses":\{"success":1,"notfound":1/
|
103
|
+
filedata.should =~ /"set":\{"calls":1,"responses":\{"success":1/
|
104
|
+
end
|
105
|
+
rescue Memcached::SomeErrorsWereReported
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'Memprof request tracing' do
|
111
|
+
@tempfile = Tempfile.new('tracing_spec')
|
112
|
+
|
113
|
+
def filename
|
114
|
+
@tempfile.path
|
115
|
+
end
|
116
|
+
|
117
|
+
def filedata
|
118
|
+
File.read(filename)
|
119
|
+
end
|
120
|
+
|
121
|
+
should 'trace request env' do
|
122
|
+
env = {"REQUEST_PATH" => "value"}
|
123
|
+
|
124
|
+
Memprof.trace_filename = filename
|
125
|
+
Memprof.trace_filename.should == filename
|
126
|
+
|
127
|
+
Memprof.trace_request(env) do
|
128
|
+
end
|
129
|
+
|
130
|
+
Memprof.trace_filename = nil
|
131
|
+
Memprof.trace_filename.should.be.nil
|
132
|
+
|
133
|
+
filedata.should =~ /"REQUEST_PATH":"value"/
|
134
|
+
end
|
135
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 3
|
9
|
+
version: 0.3.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Joe Damato
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-04-13 00:00:00 -
|
20
|
+
date: 2010-04-13 00:00:00 -07:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
@@ -68,14 +68,22 @@ files:
|
|
68
68
|
- ext/extconf.rb
|
69
69
|
- ext/i386.c
|
70
70
|
- ext/i386.h
|
71
|
+
- ext/json.c
|
72
|
+
- ext/json.h
|
71
73
|
- ext/mach.c
|
72
74
|
- ext/memprof.c
|
75
|
+
- ext/mmap.h
|
73
76
|
- ext/src/libdwarf-20091118.tar.gz
|
74
77
|
- ext/src/libelf-0.8.13.tar.gz
|
75
78
|
- ext/src/yajl-1.0.9.tar.gz
|
76
79
|
- ext/tracer.c
|
77
80
|
- ext/tracer.h
|
78
|
-
- ext/tracers/
|
81
|
+
- ext/tracers/fd.c
|
82
|
+
- ext/tracers/gc.c
|
83
|
+
- ext/tracers/memcache.c
|
84
|
+
- ext/tracers/memory.c
|
85
|
+
- ext/tracers/mysql.c
|
86
|
+
- ext/tracers/objects.c
|
79
87
|
- ext/tramp.c
|
80
88
|
- ext/tramp.h
|
81
89
|
- ext/util.c
|
@@ -86,9 +94,11 @@ files:
|
|
86
94
|
- ext/x86_gen.h
|
87
95
|
- lib/memprof/middleware.rb
|
88
96
|
- lib/memprof/signal.rb
|
97
|
+
- lib/memprof/tracer.rb
|
89
98
|
- memprof.gemspec
|
90
99
|
- spec/memprof_spec.rb
|
91
100
|
- spec/memprof_uploader_spec.rb
|
101
|
+
- spec/tracing_spec.rb
|
92
102
|
has_rdoc: true
|
93
103
|
homepage: http://github.com/ice799/memprof
|
94
104
|
licenses: []
|
data/ext/tracers/malloc.c
DELETED
@@ -1,163 +0,0 @@
|
|
1
|
-
#include <assert.h>
|
2
|
-
#include <stdio.h>
|
3
|
-
#include <stdlib.h>
|
4
|
-
#include <string.h>
|
5
|
-
|
6
|
-
#include "arch.h"
|
7
|
-
#include "bin_api.h"
|
8
|
-
#include "tracer.h"
|
9
|
-
#include "util.h"
|
10
|
-
|
11
|
-
struct memprof_malloc_stats {
|
12
|
-
size_t malloc_bytes_requested;
|
13
|
-
size_t calloc_bytes_requested;
|
14
|
-
size_t realloc_bytes_requested;
|
15
|
-
|
16
|
-
size_t malloc_bytes_actual;
|
17
|
-
size_t calloc_bytes_actual;
|
18
|
-
size_t realloc_bytes_actual;
|
19
|
-
size_t free_bytes_actual;
|
20
|
-
|
21
|
-
size_t malloc_calls;
|
22
|
-
size_t calloc_calls;
|
23
|
-
size_t realloc_calls;
|
24
|
-
size_t free_calls;
|
25
|
-
};
|
26
|
-
|
27
|
-
static struct tracer tracer;
|
28
|
-
static struct memprof_malloc_stats memprof_malloc_stats;
|
29
|
-
static void *(*orig_malloc)(size_t), *(*orig_realloc)(void *, size_t),
|
30
|
-
*(*orig_calloc)(size_t, size_t), (*orig_free)(void *);
|
31
|
-
static size_t (*malloc_usable_size)(void *ptr);
|
32
|
-
|
33
|
-
static void *
|
34
|
-
malloc_tramp(size_t size)
|
35
|
-
{
|
36
|
-
void *ret = NULL;
|
37
|
-
memprof_malloc_stats.malloc_bytes_requested += size;
|
38
|
-
memprof_malloc_stats.malloc_calls++;
|
39
|
-
ret = orig_malloc(size);
|
40
|
-
memprof_malloc_stats.malloc_bytes_actual += malloc_usable_size(ret);
|
41
|
-
return ret;
|
42
|
-
}
|
43
|
-
|
44
|
-
static void *
|
45
|
-
calloc_tramp(size_t nmemb, size_t size)
|
46
|
-
{
|
47
|
-
void *ret = NULL;
|
48
|
-
memprof_malloc_stats.calloc_bytes_requested += (nmemb * size);
|
49
|
-
memprof_malloc_stats.calloc_calls++;
|
50
|
-
ret = (*orig_calloc)(nmemb, size);
|
51
|
-
memprof_malloc_stats.calloc_bytes_actual += malloc_usable_size(ret);
|
52
|
-
return ret;
|
53
|
-
}
|
54
|
-
|
55
|
-
static void *
|
56
|
-
realloc_tramp(void *ptr, size_t size)
|
57
|
-
{
|
58
|
-
/* TODO need to check malloc_usable_size of before/after i guess? */
|
59
|
-
void *ret = NULL;
|
60
|
-
memprof_malloc_stats.realloc_bytes_requested += size;
|
61
|
-
memprof_malloc_stats.realloc_calls++;
|
62
|
-
ret = orig_realloc(ptr, size);
|
63
|
-
memprof_malloc_stats.realloc_bytes_actual += malloc_usable_size(ptr);
|
64
|
-
return ret;
|
65
|
-
}
|
66
|
-
|
67
|
-
static void
|
68
|
-
free_tramp(void *ptr)
|
69
|
-
{
|
70
|
-
memprof_malloc_stats.free_bytes_actual += malloc_usable_size(ptr);
|
71
|
-
memprof_malloc_stats.free_calls++;
|
72
|
-
orig_free(ptr);
|
73
|
-
}
|
74
|
-
|
75
|
-
static void
|
76
|
-
malloc_trace_stop()
|
77
|
-
{
|
78
|
-
struct tramp_st2_entry tmp;
|
79
|
-
|
80
|
-
tmp.addr = orig_malloc;
|
81
|
-
bin_update_image("malloc", &tmp, NULL);
|
82
|
-
|
83
|
-
tmp.addr = orig_realloc;
|
84
|
-
bin_update_image("realloc", &tmp, NULL);
|
85
|
-
|
86
|
-
if (orig_calloc) {
|
87
|
-
tmp.addr = orig_calloc;
|
88
|
-
bin_update_image("calloc", &tmp, NULL);
|
89
|
-
}
|
90
|
-
|
91
|
-
tmp.addr = orig_free;
|
92
|
-
bin_update_image("free", &tmp, NULL);
|
93
|
-
}
|
94
|
-
|
95
|
-
static void
|
96
|
-
malloc_trace_reset()
|
97
|
-
{
|
98
|
-
memset(&memprof_malloc_stats, 0, sizeof(memprof_malloc_stats));
|
99
|
-
}
|
100
|
-
|
101
|
-
static void
|
102
|
-
malloc_trace_dump()
|
103
|
-
{
|
104
|
-
fprintf(stderr, "================ Requested ====================\n");
|
105
|
-
fprintf(stderr, "Malloced: %zd, Realloced: %zd, Calloced: %zd\n",
|
106
|
-
memprof_malloc_stats.malloc_bytes_requested, memprof_malloc_stats.realloc_bytes_requested,
|
107
|
-
memprof_malloc_stats.calloc_bytes_requested);
|
108
|
-
fprintf(stderr, "================ Actual ====================\n");
|
109
|
-
fprintf(stderr, "Malloced: %zd, Realloced: %zd, Calloced: %zd, Freed: %zd\n",
|
110
|
-
memprof_malloc_stats.malloc_bytes_actual, memprof_malloc_stats.realloc_bytes_actual,
|
111
|
-
memprof_malloc_stats.calloc_bytes_actual, memprof_malloc_stats.free_bytes_actual);
|
112
|
-
fprintf(stderr, "================ Call count ====================\n");
|
113
|
-
fprintf(stderr, "Calls to malloc: %zd, realloc: %zd, calloc: %zd, free: %zd\n",
|
114
|
-
memprof_malloc_stats.malloc_calls,
|
115
|
-
memprof_malloc_stats.realloc_calls,
|
116
|
-
memprof_malloc_stats.calloc_calls,
|
117
|
-
memprof_malloc_stats.free_calls);
|
118
|
-
}
|
119
|
-
|
120
|
-
static void
|
121
|
-
malloc_trace_start()
|
122
|
-
{
|
123
|
-
struct tramp_st2_entry tmp;
|
124
|
-
|
125
|
-
if (!malloc_usable_size) {
|
126
|
-
if ((malloc_usable_size =
|
127
|
-
bin_find_symbol("MallocExtension_GetAllocatedSize", NULL, 1)) == NULL) {
|
128
|
-
malloc_usable_size = bin_find_symbol("malloc_usable_size", NULL, 1);
|
129
|
-
dbg_printf("tcmalloc was not found...\n");
|
130
|
-
}
|
131
|
-
assert(malloc_usable_size != NULL);
|
132
|
-
dbg_printf("malloc_usable_size: %p\n", malloc_usable_size);
|
133
|
-
}
|
134
|
-
|
135
|
-
tmp.addr = malloc_tramp;
|
136
|
-
bin_update_image("malloc", &tmp, (void **)(&orig_malloc));
|
137
|
-
assert(orig_malloc != NULL);
|
138
|
-
dbg_printf("orig_malloc: %p\n", orig_malloc);
|
139
|
-
|
140
|
-
tmp.addr = realloc_tramp;
|
141
|
-
bin_update_image("realloc", &tmp,(void **)(&orig_realloc));
|
142
|
-
dbg_printf("orig_realloc: %p\n", orig_realloc);
|
143
|
-
|
144
|
-
tmp.addr = calloc_tramp;
|
145
|
-
bin_update_image("calloc", &tmp, (void **)(&orig_calloc));
|
146
|
-
dbg_printf("orig_calloc: %p\n", orig_calloc);
|
147
|
-
|
148
|
-
tmp.addr = free_tramp;
|
149
|
-
bin_update_image("free", &tmp, (void **)(&orig_free));
|
150
|
-
assert(orig_free != NULL);
|
151
|
-
dbg_printf("orig_free: %p\n", orig_free);
|
152
|
-
}
|
153
|
-
|
154
|
-
void install_malloc_tracer()
|
155
|
-
{
|
156
|
-
tracer.start = malloc_trace_start;
|
157
|
-
tracer.stop = malloc_trace_stop;
|
158
|
-
tracer.reset = malloc_trace_reset;
|
159
|
-
tracer.dump = malloc_trace_dump;
|
160
|
-
tracer.id = strdup("malloc_tracer");
|
161
|
-
|
162
|
-
trace_insert(&tracer);
|
163
|
-
}
|