heap_dump 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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