objspace_helpers 0.0.2 → 0.0.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.
- checksums.yaml +4 -4
- data/ext/objspace_helpers/id2ref.c +46 -0
- data/ext/objspace_helpers/id2ref.h +9 -0
- data/lib/objspace_helpers/leaks.rb +55 -0
- data/lib/objspace_helpers/tracked_object.rb +31 -0
- data/lib/objspace_helpers/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbb176043e7fcf26f81faec74c26725353c914aa
|
4
|
+
data.tar.gz: 3dd9ba529a9b4fbc949cecf0f085c542858d46c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14b5bb3c4aed3a80f68c7873cf681cb6e0df30452ccdc2bf4908649aed509338ef06b7be47aef212798e4e4874e478114ea2b7af01f461d601409313c5f38312
|
7
|
+
data.tar.gz: 60219c051f2596767b4aa28b9a5178a98255a6ec91e9e7862e87014926658b724e07332853a0ab0c3038e5a78c29c7237ffdfa86000501b0a2248607e44dc15e
|
@@ -0,0 +1,46 @@
|
|
1
|
+
/* Note (LukasFittl): Copy of ObjectSpace._id2ref from Ruby 2.1 source,
|
2
|
+
* directly callable without the VM overhead, and more foregiving for internal objects.
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include <id2ref.h>
|
6
|
+
|
7
|
+
#if SIZEOF_LONG == SIZEOF_VOIDP
|
8
|
+
# define nonspecial_obj_id(obj) (VALUE)((SIGNED_VALUE)(obj)|FIXNUM_FLAG)
|
9
|
+
# define obj_id_to_ref(objid) ((objid) ^ FIXNUM_FLAG) /* unset FIXNUM_FLAG */
|
10
|
+
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
|
11
|
+
# define nonspecial_obj_id(obj) LL2NUM((SIGNED_VALUE)(obj) / 2)
|
12
|
+
# define obj_id_to_ref(objid) (FIXNUM_P(objid) ? \
|
13
|
+
((objid) ^ FIXNUM_FLAG) : (NUM2PTR(objid) << 1))
|
14
|
+
#else
|
15
|
+
# error not supported
|
16
|
+
#endif
|
17
|
+
|
18
|
+
VALUE
|
19
|
+
oh_id2ref(VALUE self, VALUE objid)
|
20
|
+
{
|
21
|
+
#if SIZEOF_LONG == SIZEOF_VOIDP
|
22
|
+
#define NUM2PTR(x) NUM2ULONG(x)
|
23
|
+
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
|
24
|
+
#define NUM2PTR(x) NUM2ULL(x)
|
25
|
+
#endif
|
26
|
+
VALUE ptr;
|
27
|
+
void *p0;
|
28
|
+
|
29
|
+
ptr = NUM2PTR(objid);
|
30
|
+
p0 = (void *)ptr;
|
31
|
+
|
32
|
+
if (ptr == Qtrue) return Qtrue;
|
33
|
+
if (ptr == Qfalse) return Qfalse;
|
34
|
+
if (ptr == Qnil) return Qnil;
|
35
|
+
if (FIXNUM_P(ptr)) return (VALUE)ptr;
|
36
|
+
if (FLONUM_P(ptr)) return (VALUE)ptr;
|
37
|
+
ptr = obj_id_to_ref(objid);
|
38
|
+
|
39
|
+
if ((ptr % rb_intern("RVALUE_SIZE")) == (4 << 2)) {
|
40
|
+
ID symid = ptr / rb_intern("RVALUE_SIZE");
|
41
|
+
if (rb_id2name(symid) == 0) return Qundef;
|
42
|
+
return ID2SYM(symid);
|
43
|
+
}
|
44
|
+
|
45
|
+
return (VALUE)ptr;
|
46
|
+
}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class ObjspaceHelpers
|
2
|
+
class << self
|
3
|
+
def find_leaks(trace: false, &block)
|
4
|
+
ObjectSpace::trace_object_allocations_start if trace
|
5
|
+
|
6
|
+
objs_before = _dump_addresses
|
7
|
+
|
8
|
+
block.call
|
9
|
+
|
10
|
+
# Run GC twice to try to get rid of as much false positives as possible
|
11
|
+
ObjectSpace.garbage_collect
|
12
|
+
ObjectSpace.garbage_collect
|
13
|
+
|
14
|
+
objs_after = _dump_addresses
|
15
|
+
|
16
|
+
ObjectSpace::trace_object_allocations_stop if trace
|
17
|
+
|
18
|
+
leaked_addresses = objs_after - objs_before - [objs_after.object_id]
|
19
|
+
|
20
|
+
GC.disable
|
21
|
+
|
22
|
+
# Note (LukasFittl): 2x speedup if we move this to native code
|
23
|
+
referenced_by = {}
|
24
|
+
_addresses_to_references(objs_after).each do |addr, references|
|
25
|
+
(references & leaked_addresses).each do |ref|
|
26
|
+
referenced_by[ref] ||= []
|
27
|
+
referenced_by[ref] << addr
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
GC.enable
|
32
|
+
|
33
|
+
TrackedObject.wrap(leaked_addresses, referenced_by)
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_leak_sources(trace: false, &block)
|
37
|
+
leaks = find_leaks(trace: trace, &block)
|
38
|
+
leaks_by_source = {}
|
39
|
+
top_level_leaks = []
|
40
|
+
|
41
|
+
leaks.each do |leak|
|
42
|
+
if leak.referenced_by.empty?
|
43
|
+
top_level_leaks << leak
|
44
|
+
else
|
45
|
+
leak.referenced_by.each do |source|
|
46
|
+
leaks_by_source[source] ||= []
|
47
|
+
leaks_by_source[source] << leak
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
[top_level_leaks, leaks_by_source]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class ObjspaceHelpers::TrackedObject
|
2
|
+
def self.wrap(addresses, referenced_by = [])
|
3
|
+
Array.new(addresses || []).map do |address|
|
4
|
+
new(address, wrap(referenced_by[address]))
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.for_object(obj)
|
9
|
+
new ObjspaceHelpers._address_of_obj(obj)
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :address
|
13
|
+
attr_reader :referenced_by
|
14
|
+
|
15
|
+
def initialize(address, referenced_by = [])
|
16
|
+
@address = address
|
17
|
+
@referenced_by = referenced_by
|
18
|
+
end
|
19
|
+
|
20
|
+
def info
|
21
|
+
ObjspaceHelpers._addresses_to_info([@address]).values.first
|
22
|
+
end
|
23
|
+
|
24
|
+
def klass
|
25
|
+
self.class.new(info['class'])
|
26
|
+
end
|
27
|
+
|
28
|
+
def dereference
|
29
|
+
ObjspaceHelpers._id2ref(@address)
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: objspace_helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Fittl
|
@@ -62,6 +62,8 @@ files:
|
|
62
62
|
- LICENSE
|
63
63
|
- Rakefile
|
64
64
|
- ext/objspace_helpers/extconf.rb
|
65
|
+
- ext/objspace_helpers/id2ref.c
|
66
|
+
- ext/objspace_helpers/id2ref.h
|
65
67
|
- ext/objspace_helpers/objspace_helpers.c
|
66
68
|
- ext/objspace_helpers/objspace_helpers.h
|
67
69
|
- ext/objspace_helpers/objspace_info.c
|
@@ -71,6 +73,8 @@ files:
|
|
71
73
|
- ext/objspace_helpers/ruby_private/objspace.h
|
72
74
|
- lib/objspace_helpers.rb
|
73
75
|
- lib/objspace_helpers/helpers.rb
|
76
|
+
- lib/objspace_helpers/leaks.rb
|
77
|
+
- lib/objspace_helpers/tracked_object.rb
|
74
78
|
- lib/objspace_helpers/version.rb
|
75
79
|
homepage: http://github.com/lfittl/objspace_helpers
|
76
80
|
licenses:
|