heap_dump 0.0.5 → 0.0.6
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/heap_dump/heap_dump.c +70 -15
- data/lib/heap_dump/version.rb +1 -1
- metadata +8 -8
data/ext/heap_dump/heap_dump.c
CHANGED
@@ -69,6 +69,8 @@ static void flush_yajl(walk_ctx_t *ctx){
|
|
69
69
|
}
|
70
70
|
}
|
71
71
|
|
72
|
+
static inline int is_pointer_to_heap(void *ptr, void* osp);
|
73
|
+
|
72
74
|
static inline const char* rb_builtin_type(VALUE obj){
|
73
75
|
switch(BUILTIN_TYPE(obj)){
|
74
76
|
#define T(t) case t: return #t;
|
@@ -343,8 +345,17 @@ static void dump_node_refs(NODE* obj, walk_ctx_t* ctx){
|
|
343
345
|
|
344
346
|
//iteration func - blocks,procs,lambdas etc:
|
345
347
|
case NODE_IFUNC: //NEN_CFNC, NEN_TVAL, NEN_STATE? / u2 seems to be data for func(context?)
|
346
|
-
|
348
|
+
printf("IFUNC NODE: %p %p %p\n", obj->nd_cfnc, obj->u2.node, (void*)obj->nd_aid /*u3 - aid id- - aka frame_this_func?*/);
|
347
349
|
//FIXME: closures may leak references?
|
350
|
+
if(is_pointer_to_heap(obj->u2.node, 0)){
|
351
|
+
printf("in heap: %p\n", obj->u2.node);
|
352
|
+
//TODO: do we need to dump it inline?
|
353
|
+
yg_id(obj->u2.node);
|
354
|
+
}
|
355
|
+
if(is_pointer_to_heap( (void*)obj->nd_aid, 0)){
|
356
|
+
printf("in heap: %p\n", (void*)obj->nd_aid);
|
357
|
+
yg_id(obj->nd_aid);
|
358
|
+
}
|
348
359
|
break;
|
349
360
|
|
350
361
|
//empty:
|
@@ -396,32 +407,27 @@ static void dump_hash(VALUE obj, walk_ctx_t* ctx){
|
|
396
407
|
yajl_gen_map_close(ctx->yajl);
|
397
408
|
}
|
398
409
|
|
399
|
-
static
|
400
|
-
walk_ctx_t *ctx = (void*)data;
|
401
|
-
if(key == ID_ALLOCATOR) {
|
402
|
-
yg_cstring("___allocator___");
|
403
|
-
} else {
|
404
|
-
yg_cstring(rb_id2name(key));
|
405
|
-
}
|
406
|
-
|
407
|
-
const rb_method_definition_t *def = me->def;
|
408
|
-
|
409
|
-
//gc_mark(objspace, me->klass, lev);?
|
410
|
+
static void dump_method_definition_as_value(const rb_method_definition_t *def, walk_ctx_t *ctx){
|
410
411
|
if (!def) {
|
411
412
|
yajl_gen_null(ctx->yajl);
|
412
|
-
return
|
413
|
+
return;
|
413
414
|
}
|
415
|
+
//printf("mdef %d\n", def->type);
|
414
416
|
|
415
417
|
switch (def->type) {
|
416
418
|
case VM_METHOD_TYPE_ISEQ:
|
419
|
+
//printf("method iseq %p\n", def->body.iseq);
|
420
|
+
//printf("self %p\n", def->body.iseq->self);
|
417
421
|
yg_id(def->body.iseq->self);
|
418
422
|
break;
|
419
423
|
case VM_METHOD_TYPE_CFUNC: yg_cstring("(CFUNC)"); break;
|
420
424
|
case VM_METHOD_TYPE_ATTRSET:
|
421
425
|
case VM_METHOD_TYPE_IVAR:
|
426
|
+
//printf("method ivar\n");
|
422
427
|
yg_id(def->body.attr.location);
|
423
428
|
break;
|
424
429
|
case VM_METHOD_TYPE_BMETHOD:
|
430
|
+
//printf("method binary\n");
|
425
431
|
yg_id(def->body.proc);
|
426
432
|
break;
|
427
433
|
case VM_METHOD_TYPE_ZSUPER: yg_cstring("(ZSUPER)"); break;
|
@@ -433,6 +439,19 @@ static int dump_method_entry_i(ID key, const rb_method_entry_t *me, st_data_t da
|
|
433
439
|
yajl_gen_null(ctx->yajl);
|
434
440
|
break;
|
435
441
|
}
|
442
|
+
}
|
443
|
+
|
444
|
+
static int dump_method_entry_i(ID key, const rb_method_entry_t *me, st_data_t data){
|
445
|
+
walk_ctx_t *ctx = (void*)data;
|
446
|
+
if(key == ID_ALLOCATOR) {
|
447
|
+
yg_cstring("___allocator___");
|
448
|
+
} else {
|
449
|
+
yg_cstring(rb_id2name(key));
|
450
|
+
}
|
451
|
+
|
452
|
+
//gc_mark(objspace, me->klass, lev);?
|
453
|
+
//printf("method entry\n");
|
454
|
+
dump_method_definition_as_value(me->def, ctx);
|
436
455
|
return ST_CONTINUE;
|
437
456
|
}
|
438
457
|
|
@@ -501,13 +520,21 @@ void dump_iseq(const rb_iseq_t* iseq, walk_ctx_t *ctx){
|
|
501
520
|
}
|
502
521
|
}
|
503
522
|
|
523
|
+
//!!! from 1.9.2-p290
|
524
|
+
struct METHOD {
|
525
|
+
VALUE recv;
|
526
|
+
VALUE rclass;
|
527
|
+
ID id;
|
528
|
+
rb_method_entry_t me;
|
529
|
+
};
|
530
|
+
|
504
531
|
void dump_data_if_known(VALUE obj, walk_ctx_t *ctx){
|
505
532
|
|
506
533
|
// VM
|
507
534
|
// VM/env
|
508
535
|
// VM/thread
|
509
536
|
// autoload
|
510
|
-
// binding
|
537
|
+
// binding <-
|
511
538
|
// encoding
|
512
539
|
// iseq <-
|
513
540
|
// method <-
|
@@ -544,6 +571,33 @@ void dump_data_if_known(VALUE obj, walk_ctx_t *ctx){
|
|
544
571
|
return;
|
545
572
|
}
|
546
573
|
|
574
|
+
if(!strcmp("method", typename)){
|
575
|
+
//printf("method\n");
|
576
|
+
struct METHOD *data = RTYPEDDATA_DATA(obj);
|
577
|
+
//printf("method %p: %p %p\n", data, data->rclass, data->recv);
|
578
|
+
ygh_id("rclass", data->rclass);
|
579
|
+
ygh_id("recv", data->recv);
|
580
|
+
ygh_int("method_id", data->id);
|
581
|
+
|
582
|
+
yg_cstring("method");
|
583
|
+
if(data->me.def){
|
584
|
+
//printf("methof def %p\n", &data->me);
|
585
|
+
dump_method_definition_as_value(data->me.def, ctx);
|
586
|
+
//printf("meth end\n");
|
587
|
+
}
|
588
|
+
return;
|
589
|
+
}
|
590
|
+
|
591
|
+
if(!strcmp("binding", typename)){
|
592
|
+
//printf("binding\n");
|
593
|
+
rb_binding_t *bind = RTYPEDDATA_DATA(obj);
|
594
|
+
//printf("binding %p\n", bind);
|
595
|
+
if(!bind) return;
|
596
|
+
ygh_id("env", bind->env);
|
597
|
+
ygh_id("filename", bind->filename);
|
598
|
+
return;
|
599
|
+
}
|
600
|
+
|
547
601
|
if(!strcmp("VM/env", typename)){
|
548
602
|
const rb_env_t* env = RTYPEDDATA_DATA(obj);
|
549
603
|
int i = 0;
|
@@ -1077,8 +1131,9 @@ typedef struct rb_objspace {
|
|
1077
1131
|
#define RANY(o) ((RVALUE*)(o))
|
1078
1132
|
|
1079
1133
|
static inline int
|
1080
|
-
is_pointer_to_heap(void *ptr,
|
1134
|
+
is_pointer_to_heap(void *ptr, void* osp)
|
1081
1135
|
{
|
1136
|
+
rb_objspace_t *objspace = osp;
|
1082
1137
|
if(!ptr) return false;
|
1083
1138
|
if(!objspace) objspace = GET_THREAD()->vm->objspace;
|
1084
1139
|
|
data/lib/heap_dump/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heap_dump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-30 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby-internal
|
16
|
-
requirement: &
|
16
|
+
requirement: &70171206252720 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.8.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70171206252720
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: yajl-ruby
|
27
|
-
requirement: &
|
27
|
+
requirement: &70171206251900 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '1.1'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70171206251900
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake-compiler
|
38
|
-
requirement: &
|
38
|
+
requirement: &70171206251120 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70171206251120
|
47
47
|
description: dump ruby 1.9 heap contents
|
48
48
|
email:
|
49
49
|
- vasilyfedoseyev@gmail.com
|