2 Time-stamp: <Mon Mar 20 2000 19:27:38 Stardate: [-30]4534.05 hwloidl>
4 Various debugging routines for GranSim and GUM
7 #if defined(GRAN) || defined(PAR) /* whole file */
9 //@node Debugging routines for GranSim and GUM, , ,
10 //@section Debugging routines for GranSim and GUM
14 //* Constants and Variables::
21 //* Printing info type::
22 //* Printing Pack:et Contents::
27 //@node Includes, Prototypes, Debugging routines for GranSim and GUM, Debugging routines for GranSim and GUM
28 //@subsection Includes
32 #include "GranSimRts.h"
33 #include "ParallelRts.h"
34 #include "StgMiscClosures.h"
37 # include "ParallelDebug.h"
40 //@node Prototypes, Constants and Variables, Includes, Debugging routines for GranSim and GUM
41 //@subsection Prototypes
43 rtsBool isOffset(globalAddr *ga);
44 rtsBool isFixed(globalAddr *ga);
46 //@node Constants and Variables, Closures, Prototypes, Debugging routines for GranSim and GUM
47 //@subsection Constants and Variables
49 #if defined(GRAN) && defined(GRAN_CHECK)
50 //@node Closures, Threads, Constants and Variables, Debugging routines for GranSim and GUM
51 //@subsection Closures
57 StgInfoTable *info_ptr;
59 nat size = 0, ptrs = 0, nonptrs = 0, i, vhs = 0;
60 char info_hdr_ty[80], info_ty[80];
63 fprintf(stderr,"NULL\n");
65 } else if (node==END_TSO_QUEUE) {
66 fprintf(stderr,"END_TSO_QUEUE\n");
69 /* size_and_ptrs(node,&size,&ptrs); */
70 info_ptr = get_closure_info(node, &size, &ptrs, &nonptrs, &vhs, info_hdr_ty);
72 /* vhs = var_hdr_size(node); */
73 display_info_type(info_ptr,info_ty);
75 fprintf(stderr,"Node: 0x%lx", node);
78 fprintf(stderr," [GA: 0x%lx]",GA(node));
81 #if defined(USE_COST_CENTRES)
82 fprintf(stderr," [CC: 0x%lx]",CC_HDR(node));
86 fprintf(stderr," [Bitmask: 0%lo]",PROCS(node));
89 if (info_ptr->type==TSO)
90 fprintf(stderr," TSO: 0x%lx (%x) IP: 0x%lx (%s), type %s \n ",
91 (StgTSO*)node, ((StgTSO*)node)->id, info_ptr, info_hdr_ty, info_ty);
93 fprintf(stderr," IP: 0x%lx (%s), type %s \n VHS: %d, size: %ld, ptrs:%ld, nonptrs: %ld\n ",
94 info_ptr,info_hdr_ty,info_ty,vhs,size,ptrs,nonptrs);
96 /* For now, we ignore the variable header */
98 fprintf(stderr," Ptrs: ");
99 for(i=0; i < ptrs; ++i)
102 fprintf(stderr,"\n ");
103 fprintf(stderr," 0x%lx[P]",node->payload[i]);
106 fprintf(stderr," Data: ");
107 for(i=0; i < nonptrs; ++i)
110 fprintf(stderr,"\n ");
111 fprintf(stderr," %lu[D]",node->payload[ptrs+i]);
113 fprintf(stderr, "\n");
116 switch (info_ptr->type)
119 fprintf(stderr,"\n TSO_LINK: %#lx",
120 ((StgTSO*)node)->link);
125 bqe = ((StgBlockingQueue*)node)->blocking_queue;
126 fprintf(stderr," BQ of %#lx: ", node);
131 printf("Panic: found FETCH_ME or FETCH_ME_BQ Infotable in GrAnSim system.\n");
139 G_PPN(node) /* Extracted from PrintPacket in Pack.lc */
143 nat size = 0, ptrs = 0, nonptrs = 0, i, vhs = 0, locn = 0;
146 /* size_and_ptrs(node,&size,&ptrs); */
147 info = get_closure_info(node, &size, &ptrs, &nonptrs, &vhs, info_type);
149 if (info->type == FETCH_ME || info->type == FETCH_ME_BQ ||
150 info->type == BLACKHOLE || info->type == RBH )
151 size = ptrs = nonptrs = vhs = 0;
153 if (closure_THUNK(node)) {
154 if (!closure_UNPOINTED(node))
155 fputs("SHARED ", stderr);
157 fputs("UNSHARED ", stderr);
159 if (info->type==BLACKHOLE) {
160 fputs("BLACK HOLE\n", stderr);
163 fprintf(stderr, "(%s) FH [%#lx", info_type, node[locn++]);
164 for (i = 1; i < FIXED_HS; i++)
165 fprintf(stderr, " %#lx", node[locn++]);
167 /* Variable header */
169 fprintf(stderr, "] VH [%#lx", node->payload[0]);
171 for (i = 1; i < vhs; i++)
172 fprintf(stderr, " %#lx", node->payload[i]);
175 fprintf(stderr, "] PTRS %u", ptrs);
179 fprintf(stderr, " NPTRS [%#lx", node->payload[ptrs]);
181 for (i = 1; i < nonptrs; i++)
182 fprintf(stderr, " %#lx", node->payload[ptrs+i]);
192 // ToDo: fix this!! -- HWL
197 StgInfoTable *info_ptr;
198 nat size = 0, ptrs = 0, nonptrs = 0, vhs = 0;
199 char info_type[80], hdr_type[80];
201 info_hdr_type(info_ptr, hdr_type);
204 info_ptr = get_closure_info(node, &size, &ptrs, &nonptrs, &vhs, info_type);
205 fprintf(stderr,"%s Info Ptr @0x%lx; Entry: 0x%lx; Size: %lu; Ptrs: %lu\n\n",
206 info_type,info_ptr,(W_) ENTRY_CODE(info_ptr),
208 // INFO_SIZE(info_ptr),INFO_NoPTRS(info_ptr));
210 if (closure_THUNK(node) && !closure_UNPOINTED(node) ) {
211 fprintf(stderr," RBH InfoPtr: %#lx\n",
212 RBH_INFOPTR(info_ptr));
216 fprintf(stderr,"Enter Flush Entry: 0x%lx;\tExit Flush Entry: 0x%lx\n",INFO_FLUSHENT(info_ptr),INFO_FLUSH(info_ptr));
219 #if defined(USE_COST_CENTRES)
220 fprintf(stderr,"Cost Centre (???): 0x%lx\n",INFO_CAT(info_ptr));
223 #if defined(_INFO_COPYING)
224 fprintf(stderr,"Evacuate Entry: 0x%lx;\tScavenge Entry: 0x%lx\n",
225 INFO_EVAC_2S(info_ptr),INFO_SCAV_2S(info_ptr));
228 #if defined(_INFO_COMPACTING)
229 fprintf(stderr,"Scan Link: 0x%lx;\tScan Move: 0x%lx\n",
230 (W_) INFO_SCAN_LINK_1S(info_ptr), (W_) INFO_SCAN_MOVE_1S(info_ptr));
231 fprintf(stderr,"Mark: 0x%lx;\tMarked: 0x%lx;\t",
232 (W_) INFO_MARK_1S(info_ptr), (W_) INFO_MARKED_1S(info_ptr));
233 #if 0 /* avoid INFO_TYPE */
234 if(BASE_INFO_TYPE(info_ptr)==INFO_SPEC_TYPE)
235 fprintf(stderr,"plus specialised code\n");
237 fprintf(stderr,"Marking: 0x%lx\n",(W_) INFO_MARKING_1S(info_ptr));
239 #endif /* _INFO_COMPACTING */
250 char str[80], str0[80];
252 fprintf(stderr,"\n[PE %d] @ %lu BQ: ",
253 CurrentProc,CurrentTime[CurrentProc]);
254 if ( node == (StgClosure*)NULL ) {
255 fprintf(stderr," NULL.\n");
258 if ( node == END_TSO_QUEUE ) {
259 fprintf(stderr," _|_\n");
262 tso = ((StgBlockingQueue*)node)->blocking_queue;
263 while (node != END_TSO_QUEUE) {
266 /* Find where the tso lives */
267 proc = where_is(node);
268 info = get_itbl(node);
270 switch (info->type) {
275 strcpy(str0,"BLOCKED_FETCH");
282 if(proc == CurrentProc)
283 fprintf(stderr," %#lx (%x) L %s,",
284 node, ((StgBlockingQueue*)node)->blocking_queue, str0);
286 fprintf(stderr," %#lx (%x) G (PE %d) %s,",
287 node, ((StgBlockingQueue*)node)->blocking_queue, proc, str0);
292 if ( tso == END_TSO_QUEUE )
293 fprintf(stderr," _|_\n");
296 //@node Threads, Events, Closures, Debugging routines for GranSim and GUM
297 //@subsection Threads
300 G_CURR_THREADQ(verbose)
303 fprintf(stderr,"Thread Queue on proc %d: ", CurrentProc);
304 G_THREADQ(run_queue_hd, verbose);
308 G_THREADQ(closure, verbose)
314 fprintf(stderr,"Thread Queue: ");
315 for (x=closure; x!=END_TSO_QUEUE; x=x->link)
319 fprintf(stderr," %#lx",x);
321 if (closure==END_TSO_QUEUE)
322 fprintf(stderr,"NIL\n");
324 fprintf(stderr,"\n");
328 G_TSO(closure,verbose)
333 if (closure==END_TSO_QUEUE) {
334 fprintf(stderr,"TSO at %#lx is END_TSO_QUEUE!\n");
338 if ( verbose & 0x08 ) { /* short info */
339 fprintf(stderr,"[TSO @ %#lx, PE %d]: Id: %#lx, Link: %#lx\n",
340 closure,where_is(closure),
341 closure->id,closure->link);
345 fprintf(stderr,"TSO at %#lx has the following contents:\n",
348 fprintf(stderr,"> Id: \t%#lx",closure->id);
349 // fprintf(stderr,"\tstate: \t%#lx",closure->state);
350 fprintf(stderr,"\twhat_next: \t%#lx",closure->what_next);
351 fprintf(stderr,"\tlink: \t%#lx\n",closure->link);
352 fprintf(stderr,"\twhy_blocked: \t%d", closure->why_blocked);
353 fprintf(stderr,"\tblock_info: \t%p\n", closure->block_info);
354 // fprintf(stderr,"\tType: \t%s\n",type_name[TSO_TYPE(closure)]);
355 fprintf(stderr,">PRI: \t%#lx", closure->gran.pri);
356 fprintf(stderr,"\tMAGIC: \t%#lx %s\n", closure->gran.magic,
357 (closure->gran.magic==TSO_MAGIC ? "it IS a TSO" : "THIS IS NO TSO!!"));
358 if ( verbose & 0x04 ) {
359 fprintf(stderr, "Stack: stack @ %#lx (stack_size: %u; max_stack_size: %u)\n",
360 closure->stack, closure->stack_size, closure->max_stack_size);
361 fprintf(stderr, " sp: %#lx, su: %#lx, splim: %#lx\n",
362 closure->sp, closure->su, closure->splim);
364 // fprintf(stderr,"\n");
365 if (verbose & 0x01) {
366 // fprintf(stderr,"} LOCKED: \t%#lx",closure->locked);
367 fprintf(stderr,"} SPARKNAME: \t%#lx\n", closure->gran.sparkname);
368 fprintf(stderr,"} STARTEDAT: \t%#lx", closure->gran.startedat);
369 fprintf(stderr,"\tEXPORTED: \t%#lx\n", closure->gran.exported);
370 fprintf(stderr,"} BASICBLOCKS: \t%#lx", closure->gran.basicblocks);
371 fprintf(stderr,"\tALLOCS: \t%#lx\n", closure->gran.allocs);
372 fprintf(stderr,"} EXECTIME: \t%#lx", closure->gran.exectime);
373 fprintf(stderr,"\tFETCHTIME: \t%#lx\n", closure->gran.fetchtime);
374 fprintf(stderr,"} FETCHCOUNT: \t%#lx", closure->gran.fetchcount);
375 fprintf(stderr,"\tBLOCKTIME: \t%#lx\n", closure->gran.blocktime);
376 fprintf(stderr,"} BLOCKCOUNT: \t%#lx", closure->gran.blockcount);
377 fprintf(stderr,"\tBLOCKEDAT: \t%#lx\n", closure->gran.blockedat);
378 fprintf(stderr,"} GLOBALSPARKS:\t%#lx", closure->gran.globalsparks);
379 fprintf(stderr,"\tLOCALSPARKS:\t%#lx\n", closure->gran.localsparks);
381 if ( verbose & 0x02 ) {
382 fprintf(stderr,"BQ that starts with this TSO: ");
387 //@node Events, Sparks, Threads, Debugging routines for GranSim and GUM
391 G_EVENT(event, verbose)
398 fprintf(stderr," %#lx",event);
406 extern rtsEventQ EventHd;
409 fprintf(stderr,"RtsEventQ (hd @%#lx):\n",EventHd);
410 for (x=EventHd; x!=NULL; x=x->next) {
414 fprintf(stderr,"NIL\n");
416 fprintf(stderr,"\n");
424 extern rtsEventQ EventHd;
427 fprintf(stderr,"RtsEventQ (hd @%#lx):\n",EventHd);
428 for (x=EventHd; x!=NULL; x=x->next) {
433 fprintf(stderr,"NIL\n");
435 fprintf(stderr,"\n");
438 //@node Sparks, Processors, Events, Debugging routines for GranSim and GUM
442 G_SPARK(spark, verbose)
446 if (spark==(rtsSpark*)NULL) {
447 belch("G_SPARK: NULL spark; aborting");
453 fprintf(stderr," %#lx",spark);
457 G_SPARKQ(spark,verbose)
463 if (spark==(rtsSpark*)NULL) {
464 belch("G_SPARKQ: NULL spark; aborting");
468 fprintf(stderr,"RtsSparkQ (hd @%#lx):\n",spark);
469 for (x=spark; x!=NULL; x=x->next) {
473 fprintf(stderr,"NIL\n");
475 fprintf(stderr,"\n");
479 G_CURR_SPARKQ(verbose)
482 G_SPARKQ(pending_sparks_hd,verbose);
485 //@node Processors, Shortcuts, Sparks, Debugging routines for GranSim and GUM
486 //@subsection Processors
493 extern rtsEventQ EventHd;
494 extern char *proc_status_names[];
496 fprintf(stderr,"Status of proc %d at time %d (%#lx): %s (%s)\n",
497 proc,CurrentTime[proc],CurrentTime[proc],
498 (CurrentProc==proc)?"ACTIVE":"INACTIVE",
499 proc_status_names[procStatus[proc]]);
500 G_THREADQ(run_queue_hds[proc],verbose & 0x2);
501 if ( (CurrentProc==proc) )
505 fprintf(stderr,"Next event (%s) is on proc %d\n",
506 event_names[EventHd->evttype],EventHd->proc);
509 fprintf(stderr,"\nREQUIRED sparks: ");
510 G_SPARKQ(pending_sparks_hds[proc],1);
511 fprintf(stderr,"\nADVISORY_sparks: ");
512 G_SPARKQ(pending_sparks_hds[proc],1);
516 //@node Shortcuts, Printing info type, Processors, Debugging routines for GranSim and GUM
517 //@subsection Shortcuts
519 /* Debug Processor */
526 /* Debug Current Processor */
528 GCP(){ G_PROC(CurrentProc,2); }
536 /* Debug CurrentTSO */
539 fprintf(stderr,"Current Proc: %d\n",CurrentProc);
543 /* Shorthand for debugging event queue */
545 GEQ() { G_EVENTQ(1); }
547 /* Shorthand for debugging thread queue of a processor */
549 GTQ(PEs p) { G_THREADQ(run_queue_hds[p],1); }
551 /* Shorthand for debugging thread queue of current processor */
553 GCTQ() { G_THREADQ(run_queue_hds[CurrentProc],1); }
555 /* Shorthand for debugging spark queue of a processor */
557 GSQ(PEs p) { G_SPARKQ(pending_sparks_hds[p],1); }
559 /* Shorthand for debugging spark queue of current processor */
561 GCSQ() { G_CURR_SPARKQ(1); }
563 /* Shorthand for printing a node */
565 GN(StgPtr node) { G_PRINT_NODE(node); }
567 /* Shorthand for printing info table */
571 GIT(StgPtr node) { G_INFO_TABLE(node); }
575 printThreadQPtrs(void)
578 for (p=0; p<RtsFlags.GranFlags.proc; p++) {
579 fprintf(stderr,", PE %d: (hd=%p,tl=%p)",
580 run_queue_hds[p], run_queue_tls[p]);
585 printThreadQ(StgTSO *tso) { G_THREADQ(tso, 0); };
588 printSparkQ(rtsSpark *spark) { G_SPARKQ(spark, 0); };
591 printThreadQ_verbose(StgTSO *tso) { G_THREADQ(tso, 1); };
594 printSparkQ_verbose(rtsSpark *spark) { G_SPARKQ(spark, 1); };
596 /* Shorthand for some of ADRs debugging functions */
598 #endif /* GRAN && GRAN_CHECK*/
602 DEBUG_PRINT_NODE(node)
605 W_ info_ptr = INFO_PTR(node);
606 StgInt size = 0, ptrs = 0, i, vhs = 0;
609 info_hdr_type(info_ptr, info_type);
611 size_and_ptrs(node,&size,&ptrs);
612 vhs = var_hdr_size(node);
614 fprintf(stderr,"Node: 0x%lx", (W_) node);
617 fprintf(stderr," [GA: 0x%lx]",GA(node));
620 #if defined(PROFILING)
621 fprintf(stderr," [CC: 0x%lx]",CC_HDR(node));
625 fprintf(stderr," [Bitmask: 0%lo]",PROCS(node));
628 fprintf(stderr," IP: 0x%lx (%s), size %ld, %ld ptrs\n",
629 info_ptr,info_type,size,ptrs);
631 /* For now, we ignore the variable header */
633 for(i=0; i < size; ++i)
636 fprintf(stderr,"Data: ");
639 fprintf(stderr,"\n ");
642 fprintf(stderr," 0x%lx[P]",*(node+_FHS+vhs+i));
644 fprintf(stderr," %lu[D]",*(node+_FHS+vhs+i));
646 fprintf(stderr, "\n");
650 #define INFO_MASK 0x80000000
656 W_ size = 0, ptrs = 0, i, vhs = 0;
658 /* Don't print cycles */
659 if((INFO_PTR(node) & INFO_MASK) != 0)
662 size_and_ptrs(node,&size,&ptrs);
663 vhs = var_hdr_size(node);
665 DEBUG_PRINT_NODE(node);
666 fprintf(stderr, "\n");
668 /* Mark the node -- may be dangerous */
669 INFO_PTR(node) |= INFO_MASK;
671 for(i = 0; i < ptrs; ++i)
672 DEBUG_TREE((StgPtr)node[i+vhs+_FHS]);
674 /* Unmark the node */
675 INFO_PTR(node) &= ~INFO_MASK;
680 DEBUG_INFO_TABLE(node)
683 W_ info_ptr = INFO_PTR(node);
684 char *iStgPtrtype = info_hdr_type(info_ptr);
686 fprintf(stderr,"%s Info Ptr @0x%lx; Entry: 0x%lx; Size: %lu; Ptrs: %lu\n\n",
687 iStgPtrtype,info_ptr,(W_) ENTRY_CODE(info_ptr),INFO_SIZE(info_ptr),INFO_NoPTRS(info_ptr));
689 fprintf(stderr,"Enter Flush Entry: 0x%lx;\tExit Flush Entry: 0x%lx\n",INFO_FLUSHENT(info_ptr),INFO_FLUSH(info_ptr));
692 #if defined(PROFILING)
693 fprintf(stderr,"Cost Centre (???): 0x%lx\n",INFO_CAT(info_ptr));
696 #if defined(_INFO_COPYING)
697 fprintf(stderr,"Evacuate Entry: 0x%lx;\tScavenge Entry: 0x%lx\n",
698 INFO_EVAC_2S(info_ptr),INFO_SCAV_2S(info_ptr));
701 #if defined(_INFO_COMPACTING)
702 fprintf(stderr,"Scan Link: 0x%lx;\tScan Move: 0x%lx\n",
703 (W_) INFO_SCAN_LINK_1S(info_ptr), (W_) INFO_SCAN_MOVE_1S(info_ptr));
704 fprintf(stderr,"Mark: 0x%lx;\tMarked: 0x%lx;\t",
705 (W_) INFO_MARK_1S(info_ptr), (W_) INFO_MARKED_1S(info_ptr));
706 #if 0 /* avoid INFO_TYPE */
707 if(BASE_INFO_TYPE(info_ptr)==INFO_SPEC_TYPE)
708 fprintf(stderr,"plus specialised code\n");
710 fprintf(stderr,"Marking: 0x%lx\n",(W_) INFO_MARKING_1S(info_ptr));
712 #endif /* _INFO_COMPACTING */
716 //@node Printing info type, Printing Packet Contents, Shortcuts, Debugging routines for GranSim and GUM
717 //@subsection Printing info type
720 display_info_type(closure, str)
725 if ( closure_HNF(closure) )
726 strcat(str,"|_HNF ");
727 else if ( closure_BITMAP(closure) )
729 else if ( !closure_SHOULD_SPARK(closure) )
731 else if ( closure_STATIC(closure) )
733 else if ( closure_THUNK(closure) )
735 else if ( closure_MUTABLE(closure) )
737 else if ( closure_UNPOINTED(closure) )
739 else if ( closure_SRT(closure) )
746 PrintPacket is in Pack.c because it makes use of closure queues
749 #if defined(GRAN) || defined(PAR)
752 Print graph rooted at q. The structure of this recursive printing routine
753 should be the same as in the graph traversals when packing a graph in
754 GUM. Thus, it demonstrates the structure of such a generic graph
755 traversal, and in particular, how to extract pointer and non-pointer info
756 from the multitude of different heap objects available.
758 {evacuate}Daq ngoqvam nIHlu'pu'!!
762 PrintGraph(StgClosure *p, int indent_level)
765 rtsBool printed = rtsFalse;
767 const StgInfoTable *info;
769 q = p; /* save ptr to object */
772 for (j=0; j<indent_level; j++)
775 ASSERT(p!=(StgClosure*)NULL);
776 ASSERT(LOOKS_LIKE_STATIC(p) ||
777 LOOKS_LIKE_GHC_INFO(GET_INFO((StgClosure *)p)) ||
778 IS_HUGS_CONSTR_INFO(GET_INFO((StgClosure *)p)));
780 printClosure(p); // prints contents of this one closure
783 for (j=0; j<indent_level; j++)
786 info = get_itbl((StgClosure *)p);
787 /* the rest of this fct recursively traverses the graph */
788 switch (info -> type) {
792 StgBCO* bco = stgCast(StgBCO*,p);
794 fprintf(stderr, "BCO (%p) with %d pointers\n", p, bco->n_ptrs);
795 for (i = 0; i < bco->n_ptrs; i++) {
796 // bcoConstCPtr(bco,i) =
797 PrintGraph(bcoConstCPtr(bco,i), indent_level+1);
799 // p += bco_sizeW(bco);
804 /* treat MVars specially, because we don't want to PrintGraph the
805 * mut_link field in the middle of the closure.
808 StgMVar *mvar = ((StgMVar *)p);
810 fprintf(stderr, "MVAR (%p) with 3 pointers (head, tail, value)\n", p);
811 // (StgClosure *)mvar->head =
812 PrintGraph((StgClosure *)mvar->head, indent_level+1);
813 // (StgClosure *)mvar->tail =
814 PrintGraph((StgClosure *)mvar->tail, indent_level+1);
815 //(StgClosure *)mvar->value =
816 PrintGraph((StgClosure *)mvar->value, indent_level+1);
817 // p += sizeofW(StgMVar);
818 // evac_gen = saved_evac_gen;
824 fprintf(stderr, "THUNK_2_0 (%p) with 2 pointers\n", p);
829 fprintf(stderr, "FUN_2_0 (%p) with 2 pointers\n", p);
832 // scavenge_srt(info);
835 fprintf(stderr, "CONSTR_2_0 (%p) with 2 pointers\n", p);
838 // ((StgClosure *)p)->payload[0] =
839 PrintGraph(((StgClosure *)p)->payload[0],
841 // ((StgClosure *)p)->payload[1] =
842 PrintGraph(((StgClosure *)p)->payload[1],
844 // p += sizeofW(StgHeader) + 2;
848 // scavenge_srt(info);
849 fprintf(stderr, "THUNK_1_0 (%p) with 1 pointer\n", p);
850 // ((StgClosure *)p)->payload[0] =
851 PrintGraph(((StgClosure *)p)->payload[0],
853 // p += sizeofW(StgHeader) + 2; /* MIN_UPD_SIZE */
858 fprintf(stderr, "FUN_1_0 (%p) with 1 pointer\n", p);
861 // scavenge_srt(info);
864 fprintf(stderr, "CONSTR_2_0 (%p) with 2 pointers\n", p);
867 // ((StgClosure *)p)->payload[0] =
868 PrintGraph(((StgClosure *)p)->payload[0],
870 // p += sizeofW(StgHeader) + 1;
874 fprintf(stderr, "THUNK_0_1 (%p) with 0 pointers\n", p);
875 // scavenge_srt(info);
876 // p += sizeofW(StgHeader) + 2; /* MIN_UPD_SIZE */
880 fprintf(stderr, "FUN_0_1 (%p) with 0 pointers\n", p);
881 //scavenge_srt(info);
883 fprintf(stderr, "CONSTR_0_1 (%p) with 0 pointers\n", p);
884 //p += sizeofW(StgHeader) + 1;
889 fprintf(stderr, "THUNK_0_2 (%p) with 0 pointers\n", p);
894 fprintf(stderr, "FUN_0_2 (%p) with 0 pointers\n", p);
897 // scavenge_srt(info);
900 fprintf(stderr, "CONSTR_0_2 (%p) with 0 pointers\n", p);
903 // p += sizeofW(StgHeader) + 2;
908 fprintf(stderr, "THUNK_1_1 (%p) with 1 pointer\n", p);
913 fprintf(stderr, "FUN_1_1 (%p) with 1 pointer\n", p);
916 // scavenge_srt(info);
919 fprintf(stderr, "CONSTR_1_1 (%p) with 1 pointer\n", p);
922 // ((StgClosure *)p)->payload[0] =
923 PrintGraph(((StgClosure *)p)->payload[0],
925 // p += sizeofW(StgHeader) + 2;
930 fprintf(stderr, "FUN (%p) with %d pointers\n", p, info->layout.payload.ptrs);
937 fprintf(stderr, "THUNK (%p) with %d pointers\n", p, info->layout.payload.ptrs);
940 // scavenge_srt(info);
945 fprintf(stderr, "CONSTR (%p) with %d pointers\n", p, info->layout.payload.ptrs);
948 /* basically same as loop in STABLE_NAME case */
949 for (i=0; i<info->layout.payload.ptrs; i++)
950 PrintGraph(((StgClosure *)p)->payload[i],
953 /* NOT fall through */
957 fprintf(stderr, "WEAK (%p) with %d pointers\n", p, info->layout.payload.ptrs);
964 fprintf(stderr, "FOREIGN (%p) with %d pointers\n", p, info->layout.payload.ptrs);
974 fprintf(stderr, "STABLE_NAME (%p) with %d pointers (not followed!)\n",
975 p, info->layout.payload.ptrs);
978 end = (StgPtr)((StgClosure *)p)->payload + info->layout.payload.ptrs;
979 for (p = (StgPtr)((StgClosure *)p)->payload; p < end; p++) {
980 // (StgClosure *)*p =
981 //PrintGraph((StgClosure *)*p, indent_level+1);
982 fprintf(stderr, ", %p", *p);
984 //fputs("\n", stderr);
985 // p += info->layout.payload.nptrs;
990 //if (step->gen->no != 0) {
991 // SET_INFO(((StgClosure *)p), &IND_OLDGEN_PERM_info);
994 fprintf(stderr, "IND_PERM (%p) with indirection to\n",
995 p, ((StgIndOldGen *)p)->indirectee);
1000 case IND_OLDGEN_PERM:
1002 fprintf(stderr, "IND_OLDGEN_PERM (%p) with indirection to %p\n",
1003 p, ((StgIndOldGen *)p)->indirectee);
1006 // ((StgIndOldGen *)p)->indirectee =
1007 PrintGraph(((StgIndOldGen *)p)->indirectee,
1009 //if (failed_to_evac) {
1010 // failed_to_evac = rtsFalse;
1011 // recordOldToNewPtrs((StgMutClosure *)p);
1013 // p += sizeofW(StgIndOldGen);
1018 StgCAF *caf = (StgCAF *)p;
1020 fprintf(stderr, "CAF_UNENTERED (%p) pointing to %p\n", p, caf->body);
1021 PrintGraph(caf->body, indent_level+1);
1022 //if (failed_to_evac) {
1023 // failed_to_evac = rtsFalse;
1024 // recordOldToNewPtrs((StgMutClosure *)p);
1026 // caf->mut_link = NULL;
1028 //p += sizeofW(StgCAF);
1034 StgCAF *caf = (StgCAF *)p;
1036 fprintf(stderr, "CAF_ENTERED (%p) pointing to %p and %p\n",
1037 p, caf->body, caf->value);
1039 PrintGraph(caf->body, indent_level+1);
1041 PrintGraph(caf->value, indent_level+1);
1042 //if (failed_to_evac) {
1043 // failed_to_evac = rtsFalse;
1044 // recordOldToNewPtrs((StgMutClosure *)p);
1046 // caf->mut_link = NULL;
1048 //p += sizeofW(StgCAF);
1053 /* ignore MUT_CONSs */
1054 fprintf(stderr, "MUT_VAR (%p) pointing to %p\n", p, ((StgMutVar *)p)->var);
1055 if (((StgMutVar *)p)->header.info != &MUT_CONS_info) {
1057 PrintGraph(((StgMutVar *)p)->var, indent_level+1);
1058 //evac_gen = saved_evac_gen;
1060 //p += sizeofW(StgMutVar);
1065 fprintf(stderr, "CAF_BLACKHOLE (%p) with 0 pointers\n", p);
1068 case SE_CAF_BLACKHOLE:
1070 fprintf(stderr, "SE_CAF_BLACKHOLE (%p) with 0 pointers\n", p);
1075 fprintf(stderr, "SE_BLACKHOLE (%p) with 0 pointers\n", p);
1080 fprintf(stderr, "BLACKHOLE (%p) with 0 pointers\n", p);
1083 //p += BLACKHOLE_sizeW();
1088 StgBlockingQueue *bh = (StgBlockingQueue *)p;
1089 // (StgClosure *)bh->blocking_queue =
1090 fprintf(stderr, "BLACKHOLE_BQ (%p) pointing to %p\n",
1091 p, (StgClosure *)bh->blocking_queue);
1092 PrintGraph((StgClosure *)bh->blocking_queue, indent_level+1);
1093 //if (failed_to_evac) {
1094 // failed_to_evac = rtsFalse;
1095 // recordMutable((StgMutClosure *)bh);
1097 // p += BLACKHOLE_sizeW();
1101 case THUNK_SELECTOR:
1103 StgSelector *s = (StgSelector *)p;
1104 fprintf(stderr, "THUNK_SELECTOR (%p) pointing to %p\n",
1106 PrintGraph(s->selectee, indent_level+1);
1107 // p += THUNK_SELECTOR_sizeW();
1112 fprintf(stderr, "IND (%p) pointing to %p\n", p, ((StgInd*)p)->indirectee);
1113 PrintGraph(((StgInd*)p)->indirectee, indent_level+1);
1117 fprintf(stderr, "IND_OLDGEN (%p) pointing to %p\n",
1118 p, ((StgIndOldGen*)p)->indirectee);
1119 PrintGraph(((StgIndOldGen*)p)->indirectee, indent_level+1);
1122 case CONSTR_INTLIKE:
1123 fprintf(stderr, "CONSTR_INTLIKE (%p) with 0 pointers\n", p);
1125 case CONSTR_CHARLIKE:
1126 fprintf(stderr, "CONSTR_CHARLIKE (%p) with 0 pointers\n", p);
1129 fprintf(stderr, "CONSTR_STATIC (%p) with 0 pointers\n", p);
1131 case CONSTR_NOCAF_STATIC:
1132 fprintf(stderr, "CONSTR_NOCAF_STATIC (%p) with 0 pointers\n", p);
1135 fprintf(stderr, "THUNK_STATIC (%p) with 0 pointers\n", p);
1138 fprintf(stderr, "FUN_STATIC (%p) with 0 pointers\n", p);
1141 fprintf(stderr, "IND_STATIC (%p) with 0 pointers\n", p);
1145 fprintf(stderr, "RET_BCO (%p) with 0 pointers\n", p);
1148 fprintf(stderr, "RET_SMALL (%p) with 0 pointers\n", p);
1151 fprintf(stderr, "RET_VEC_SMALL (%p) with 0 pointers\n", p);
1154 fprintf(stderr, "RET_BIG (%p) with 0 pointers\n", p);
1157 fprintf(stderr, "RET_VEC_BIG (%p) with 0 pointers\n", p);
1160 fprintf(stderr, "RET_DYN (%p) with 0 pointers\n", p);
1163 fprintf(stderr, "UPDATE_FRAME (%p) with 0 pointers\n", p);
1166 fprintf(stderr, "STOP_FRAME (%p) with 0 pointers\n", p);
1169 fprintf(stderr, "CATCH_FRAME (%p) with 0 pointers\n", p);
1172 fprintf(stderr, "SEQ_FRAME (%p) with 0 pointers\n", p);
1175 case AP_UPD: /* same as PAPs */
1176 fprintf(stderr, "AP_UPD (%p) with 0 pointers\n", p);
1178 /* Treat a PAP just like a section of stack, not forgetting to
1179 * PrintGraph the function pointer too...
1182 StgPAP* pap = stgCast(StgPAP*,p);
1184 fprintf(stderr, "PAP (%p) pointing to %p\n", p, pap->fun);
1186 //PrintGraph(pap->fun, indent_level+1);
1187 //scavenge_stack((P_)pap->payload, (P_)pap->payload + pap->n_args);
1188 //p += pap_sizeW(pap);
1193 /* an array of (non-mutable) words */
1194 fprintf(stderr, "ARR_WORDS (%p) of %d non-ptrs (maybe a string?)\n",
1195 p, ((StgArrWords *)q)->words);
1199 /* follow everything */
1203 fprintf(stderr, "MUT_ARR_PTRS (%p) with %d pointers (not followed)\n",
1204 p, mut_arr_ptrs_sizeW((StgMutArrPtrs*)p));
1205 // evac_gen = 0; /* repeatedly mutable */
1206 next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
1207 for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
1208 // (StgClosure *)*p =
1209 // PrintGraph((StgClosure *)*p, indent_level+1);
1210 fprintf(stderr, ", %p", *p);
1212 fputs("\n", stderr);
1213 //evac_gen = saved_evac_gen;
1217 case MUT_ARR_PTRS_FROZEN:
1218 /* follow everything */
1220 StgPtr start = p, next;
1222 fprintf(stderr, "MUT_ARR_PTRS (%p) with %d pointers (not followed)",
1223 p, mut_arr_ptrs_sizeW((StgMutArrPtrs*)p));
1224 next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
1225 for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
1226 // (StgClosure *)*p =
1227 // PrintGraph((StgClosure *)*p, indent_level+1);
1228 fprintf(stderr, ", %p", *p);
1230 fputs("\n", stderr);
1231 //if (failed_to_evac) {
1232 /* we can do this easier... */
1233 // recordMutable((StgMutClosure *)start);
1234 // failed_to_evac = rtsFalse;
1244 fprintf(stderr, "TSO (%p) with link field %p\n", p, (StgClosure *)tso->link);
1246 /* chase the link field for any TSOs on the same queue */
1247 // (StgClosure *)tso->link =
1248 PrintGraph((StgClosure *)tso->link, indent_level+1);
1249 //if (tso->blocked_on) {
1250 // tso->blocked_on = PrintGraph(tso->blocked_on);
1252 /* scavenge this thread's stack */
1253 //scavenge_stack(tso->sp, &(tso->stack[tso->stack_size]));
1254 //evac_gen = saved_evac_gen;
1255 //p += tso_sizeW(tso);
1259 #if defined(GRAN) || defined(PAR)
1262 StgInfoTable *rip = REVERT_INFOPTR(get_itbl(p));
1263 //if (LOOKS_LIKE_GHC_INFO(rip))
1264 // fprintf(stderr, "RBH (%p) with 0 pointers (reverted type=%s)\n",
1265 // p, info_type_by_ip(rip));
1267 fprintf(stderr, "RBH (%p) with 0 pointers (reverted IP=%x)\n",
1274 fprintf(stderr, "BLOCKED_FETCH (%p) with 0 pointers (link=%p)\n",
1275 p, ((StgBlockedFetch *)p)->link);
1278 fprintf(stderr, "FETCH_ME (%p) with 0 pointers\n", p);
1281 fprintf(stderr, "FETCH_ME_BQ (%p) with 0 pointers (blocking_queue=%p)\n",
1282 p, ((StgFetchMeBlockingQueue *)p)->blocking_queue);
1286 fprintf(stderr, "EVACUATED (%p) with 0 pointers (evacuee=%p)\n",
1287 p, ((StgEvacuated *)p)->evacuee);
1291 barf("PrintGraph: unknown closure %d (%s)",
1292 info -> type, info_type(info));
1295 /* If we didn't manage to promote all the objects pointed to by
1296 * the current object, then we have to designate this object as
1297 * mutable (because it contains old-to-new generation pointers).
1299 //if (failed_to_evac) {
1300 // mkMutCons((StgClosure *)q, &generations[evac_gen]);
1301 // failed_to_evac = rtsFalse;
1306 Do a sanity check on the whole graph, down to a recursion level of level.
1307 Same structure as PrintGraph (nona).
1310 checkGraph(StgClosure *p, int rec_level)
1314 const StgInfoTable *info;
1319 q = p; /* save ptr to object */
1321 /* First, the obvious generic checks */
1322 ASSERT(p!=(StgClosure*)NULL);
1323 checkClosure(p); /* see Sanity.c for what's actually checked */
1325 info = get_itbl((StgClosure *)p);
1326 /* the rest of this fct recursively traverses the graph */
1327 switch (info -> type) {
1331 StgBCO* bco = stgCast(StgBCO*,p);
1333 for (i = 0; i < bco->n_ptrs; i++) {
1334 checkGraph(bcoConstCPtr(bco,i), rec_level-1);
1340 /* treat MVars specially, because we don't want to PrintGraph the
1341 * mut_link field in the middle of the closure.
1344 StgMVar *mvar = ((StgMVar *)p);
1345 checkGraph((StgClosure *)mvar->head, rec_level-1);
1346 checkGraph((StgClosure *)mvar->tail, rec_level-1);
1347 checkGraph((StgClosure *)mvar->value, rec_level-1);
1354 checkGraph(((StgClosure *)p)->payload[0], rec_level-1);
1355 checkGraph(((StgClosure *)p)->payload[1], rec_level-1);
1359 checkGraph(((StgClosure *)p)->payload[0], rec_level-1);
1364 checkGraph(((StgClosure *)p)->payload[0], rec_level-1);
1382 checkGraph(((StgClosure *)p)->payload[0], rec_level-1);
1388 for (i=0; i<info->layout.payload.ptrs; i++)
1389 checkGraph(((StgClosure *)p)->payload[i], rec_level-1);
1398 end = (StgPtr)((StgClosure *)p)->payload + info->layout.payload.ptrs;
1399 for (p = (StgPtr)((StgClosure *)p)->payload; p < end; p++) {
1400 checkGraph(*(StgClosure **)p, rec_level-1);
1406 case IND_OLDGEN_PERM:
1407 checkGraph(((StgIndOldGen *)p)->indirectee, rec_level-1);
1412 StgCAF *caf = (StgCAF *)p;
1414 fprintf(stderr, "CAF_UNENTERED (%p) pointing to %p\n", p, caf->body);
1415 checkGraph(caf->body, rec_level-1);
1421 StgCAF *caf = (StgCAF *)p;
1423 fprintf(stderr, "CAF_ENTERED (%p) pointing to %p and %p\n",
1424 p, caf->body, caf->value);
1425 checkGraph(caf->body, rec_level-1);
1426 checkGraph(caf->value, rec_level-1);
1431 /* ignore MUT_CONSs */
1432 if (((StgMutVar *)p)->header.info != &MUT_CONS_info) {
1433 checkGraph(((StgMutVar *)p)->var, rec_level-1);
1438 case SE_CAF_BLACKHOLE:
1446 case THUNK_SELECTOR:
1448 StgSelector *s = (StgSelector *)p;
1449 checkGraph(s->selectee, rec_level-1);
1454 checkGraph(((StgInd*)p)->indirectee, rec_level-1);
1458 checkGraph(((StgIndOldGen*)p)->indirectee, rec_level-1);
1461 case CONSTR_INTLIKE:
1463 case CONSTR_CHARLIKE:
1467 case CONSTR_NOCAF_STATIC:
1497 case AP_UPD: /* same as PAPs */
1499 /* Treat a PAP just like a section of stack, not forgetting to
1500 * checkGraph the function pointer too...
1503 StgPAP* pap = stgCast(StgPAP*,p);
1505 checkGraph(pap->fun, rec_level-1);
1513 /* follow everything */
1517 next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
1518 for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
1519 checkGraph(*(StgClosure **)p, rec_level-1);
1524 case MUT_ARR_PTRS_FROZEN:
1525 /* follow everything */
1527 StgPtr start = p, next;
1529 next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p);
1530 for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
1531 checkGraph(*(StgClosure **)p, rec_level-1);
1541 checkGraph((StgClosure *)tso->link, rec_level-1);
1545 #if defined(GRAN) || defined(PAR)
1558 barf("checkGraph: found EVACUATED closure %p (%s)",
1568 #endif /* GRAN || PAR */
1570 //@node End of File, , Printing Packet Contents, Debugging routines for GranSim and GUM
1571 //@subsection End of File