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.
@@ -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
- // printf("IFUNC NODE: %p %p %p\n", obj->nd_cfnc, obj->u2.node, (void*)obj->nd_aid /*u3 - aid id- - aka frame_this_func?*/);
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 int dump_method_entry_i(ID key, const rb_method_entry_t *me, st_data_t data){
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 ST_CONTINUE;
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, rb_objspace_t *objspace)
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
 
@@ -1,3 +1,3 @@
1
1
  module HeapDump
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
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.5
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-29 00:00:00.000000000Z
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: &70104369392280 !ruby/object:Gem::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: *70104369392280
24
+ version_requirements: *70171206252720
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: yajl-ruby
27
- requirement: &70104369391600 !ruby/object:Gem::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: *70104369391600
35
+ version_requirements: *70171206251900
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake-compiler
38
- requirement: &70104369391160 !ruby/object:Gem::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: *70104369391160
46
+ version_requirements: *70171206251120
47
47
  description: dump ruby 1.9 heap contents
48
48
  email:
49
49
  - vasilyfedoseyev@gmail.com