small improvements to the debug printer
[ghc-hetmet.git] / ghc / rts / Printer.c
index 092dab3..8290d22 100644 (file)
-
 /* -----------------------------------------------------------------------------
- * $Id: Printer.c,v 1.11 1999/04/27 12:27:49 sewardj Exp $
  *
- * Copyright (c) 1994-1999.
+ * (c) The GHC Team, 1994-2000.
  *
  * Heap printer
  * 
  * ---------------------------------------------------------------------------*/
 
+#include "PosixSource.h"
 #include "Rts.h"
+#include "Printer.h"
+#include "RtsUtils.h"
 
 #ifdef DEBUG
 
-#include "RtsUtils.h"
 #include "RtsFlags.h"
+#include "MBlock.h"
+#include "Storage.h"
 #include "Bytecodes.h"  /* for InstrPtr */
 #include "Disassembler.h"
+#include "Apply.h"
 
-#include "Printer.h"
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(GRAN) || defined(PAR)
+// HWL: explicit fixed header size to make debugging easier
+int fixed_hs = sizeof(StgHeader), itbl_sz = sizeofW(StgInfoTable), 
+    uf_sz=sizeofW(StgUpdateFrame); 
+#endif
 
 /* --------------------------------------------------------------------------
  * local function decls
  * ------------------------------------------------------------------------*/
 
-static void    printStdObject( StgClosure *obj, char* tag );
+static void    printStdObjPayload( StgClosure *obj );
+#ifdef USING_LIBBFD
 static void    reset_table   ( int size );
 static void    prepare_table ( void );
 static void    insert        ( unsigned value, const char *name );
+#endif
 #if 0 /* unused but might be useful sometime */
 static rtsBool lookup_name   ( char *name, unsigned *result );
 static void    enZcode       ( char *in, char *out );
 #endif
 static char    unZcode       ( char ch );
-rtsBool lookupGHCName ( StgPtr addr, const char **result );
+const char *   lookupGHCName ( void *addr );
 static void    printZcoded   ( const char *raw );
 
 /* --------------------------------------------------------------------------
  * Printer
  * ------------------------------------------------------------------------*/
 
-
-#ifdef INTERPRETER
-extern void* itblNames[];
-extern int   nItblNames;
-char* lookupHugsItblName ( void* v )
-{
-   int i;
-   for (i = 0; i < nItblNames; i += 2)
-      if (itblNames[i] == v) return itblNames[i+1];
-   return NULL;
-}
-#endif
-
 void printPtr( StgPtr p )
 {
-    char* str;
     const char *raw;
-    if (lookupGHCName( p, &raw )) {
+    raw = lookupGHCName(p);
+    if (raw != NULL) {
         printZcoded(raw);
-#ifdef INTERPRETER
-    } else if ((raw = lookupHugsName(p)) != 0) {
-        fprintf(stderr, "%s", raw);
-    } else if ((str = lookupHugsItblName(p)) != 0) {
-        fprintf(stderr, "%p=%s", p, str);
-#endif
     } else {
-        fprintf(stderr, "%p", p);
+        debugBelch("%p", p);
     }
 }
   
 void printObj( StgClosure *obj )
 {
-    fprintf(stderr,"Object "); printPtr((StgPtr)obj); fprintf(stderr," = ");
+    debugBelch("Object "); printPtr((StgPtr)obj); debugBelch(" = ");
     printClosure(obj);
 }
 
-static void printStdObject( StgClosure *obj, char* tag )
+STATIC_INLINE void
+printStdObjHdr( StgClosure *obj, char* tag )
 {
-    StgWord i, j;
-    const StgInfoTable* info = get_itbl(obj);
-    fprintf(stderr,"%s(",tag);
+    debugBelch("%s(",tag);
     printPtr((StgPtr)obj->header.info);
+#ifdef PROFILING
+    debugBelch(", %s", obj->header.prof.ccs->cc->label);
+#endif
+}
+
+static void
+printStdObjPayload( StgClosure *obj )
+{
+    StgWord i, j;
+    const StgInfoTable* info;
+
+    info = get_itbl(obj);
     for (i = 0; i < info->layout.payload.ptrs; ++i) {
-        fprintf(stderr,", ");
-        printPtr(payloadPtr(obj,i));
+        debugBelch(", ");
+        printPtr((StgPtr)obj->payload[i]);
     }
     for (j = 0; j < info->layout.payload.nptrs; ++j) {
-        fprintf(stderr,", %xd#",payloadWord(obj,i+j));
+        debugBelch(", %pd#",obj->payload[i+j]);
     }
-    fprintf(stderr,")\n");
+    debugBelch(")\n");
 }
 
-void printClosure( StgClosure *obj )
+static void
+printThunkPayload( StgThunk *obj )
 {
-    switch ( get_itbl(obj)->type ) {
+    StgWord i, j;
+    const StgInfoTable* info;
+
+    info = get_itbl(obj);
+    for (i = 0; i < info->layout.payload.ptrs; ++i) {
+        debugBelch(", ");
+        printPtr((StgPtr)obj->payload[i]);
+    }
+    for (j = 0; j < info->layout.payload.nptrs; ++j) {
+        debugBelch(", %pd#",obj->payload[i+j]);
+    }
+    debugBelch(")\n");
+}
+
+static void
+printThunkObject( StgThunk *obj, char* tag )
+{
+    printStdObjHdr( (StgClosure *)obj, tag );
+    printThunkPayload( obj );
+}
+
+void
+printClosure( StgClosure *obj )
+{
+    StgInfoTable *info;
+    
+    info = get_itbl(obj);
+
+    switch ( info->type ) {
     case INVALID_OBJECT:
             barf("Invalid object");
-#ifdef INTERPRETER
-    case BCO:
-            fprintf(stderr,"BCO\n");
-            disassemble(stgCast(StgBCO*,obj),"\t");
+
+    case CONSTR:
+    case CONSTR_1_0: case CONSTR_0_1:
+    case CONSTR_1_1: case CONSTR_0_2: case CONSTR_2_0:
+    case CONSTR_INTLIKE:
+    case CONSTR_CHARLIKE:
+    case CONSTR_STATIC:
+    case CONSTR_NOCAF_STATIC:
+        {
+            StgWord i, j;
+#ifdef PROFILING
+           debugBelch("%s(", info->prof.closure_desc);
+           debugBelch("%s", obj->header.prof.ccs->cc->label);
+#else
+            debugBelch("CONSTR(");
+            printPtr((StgPtr)obj->header.info);
+            debugBelch("(tag=%d)",info->srt_bitmap);
+#endif
+            for (i = 0; i < info->layout.payload.ptrs; ++i) {
+               debugBelch(", ");
+                printPtr((StgPtr)obj->payload[i]);
+            }
+            for (j = 0; j < info->layout.payload.nptrs; ++j) {
+                debugBelch(", %p#", obj->payload[i+j]);
+            }
+            debugBelch(")\n");
             break;
+        }
+
+    case FUN:
+    case FUN_1_0: case FUN_0_1: 
+    case FUN_1_1: case FUN_0_2: case FUN_2_0:
+    case FUN_STATIC:
+       debugBelch("FUN/%d(",itbl_to_fun_itbl(info)->f.arity);
+       printPtr((StgPtr)obj->header.info);
+#ifdef PROFILING
+       debugBelch(", %s", obj->header.prof.ccs->cc->label);
+#endif
+       printStdObjPayload(obj);
+       break;
+
+    case THUNK:
+    case THUNK_1_0: case THUNK_0_1:
+    case THUNK_1_1: case THUNK_0_2: case THUNK_2_0:
+    case THUNK_STATIC:
+            /* ToDo: will this work for THUNK_STATIC too? */
+#ifdef PROFILING
+           printThunkObject((StgThunk *)obj,info->prof.closure_desc);
+#else
+            printThunkObject((StgThunk *)obj,"THUNK");
 #endif
+            break;
+
+    case THUNK_SELECTOR:
+       printStdObjHdr(obj, "THUNK_SELECTOR");
+       debugBelch(", %p)\n", ((StgSelector *)obj)->selectee);
+       break;
+
+    case BCO:
+            disassemble( (StgBCO*)obj );
+            break;
 
-    case AP_UPD:
+    case AP:
         {
-           StgAP_UPD* ap = stgCast(StgAP_UPD*,obj);
+           StgAP* ap = stgCast(StgAP*,obj);
             StgWord i;
-            fprintf(stderr,"AP_UPD("); printPtr((StgPtr)ap->fun);
+            debugBelch("AP("); printPtr((StgPtr)ap->fun);
             for (i = 0; i < ap->n_args; ++i) {
-                fprintf(stderr,", ");
-                printPtr(payloadPtr(ap,i));
+                debugBelch(", ");
+                printPtr((P_)ap->payload[i]);
             }
-            fprintf(stderr,")\n");
+            debugBelch(")\n");
             break;
         }
 
@@ -120,370 +208,539 @@ void printClosure( StgClosure *obj )
         {
            StgPAP* pap = stgCast(StgPAP*,obj);
             StgWord i;
-            fprintf(stderr,"PAP("); printPtr((StgPtr)pap->fun);
+            debugBelch("PAP/%d(",pap->arity); 
+           printPtr((StgPtr)pap->fun);
             for (i = 0; i < pap->n_args; ++i) {
-                fprintf(stderr,", ");
-                printPtr(payloadPtr(pap,i));
+                debugBelch(", ");
+                printPtr((StgPtr)pap->payload[i]);
             }
-            fprintf(stderr,")\n");
+            debugBelch(")\n");
+            break;
+        }
+
+    case AP_STACK:
+        {
+           StgAP_STACK* ap = stgCast(StgAP_STACK*,obj);
+            StgWord i;
+            debugBelch("AP_STACK("); printPtr((StgPtr)ap->fun);
+            for (i = 0; i < ap->size; ++i) {
+                debugBelch(", ");
+                printPtr((P_)ap->payload[i]);
+            }
+            debugBelch(")\n");
             break;
         }
 
     case IND:
-            fprintf(stderr,"IND("); 
+            debugBelch("IND("); 
             printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
-            fprintf(stderr,")\n"); 
+            debugBelch(")\n"); 
             break;
 
-    case IND_STATIC:
-            fprintf(stderr,"IND_STATIC("); 
+    case IND_OLDGEN:
+            debugBelch("IND_OLDGEN("); 
             printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
-            fprintf(stderr,")\n"); 
+            debugBelch(")\n"); 
             break;
 
-    case IND_OLDGEN:
-            fprintf(stderr,"IND_OLDGEN("); 
+    case IND_PERM:
+            debugBelch("IND("); 
+            printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
+            debugBelch(")\n"); 
+            break;
+
+    case IND_OLDGEN_PERM:
+            debugBelch("IND_OLDGEN_PERM("); 
             printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
-            fprintf(stderr,")\n"); 
+            debugBelch(")\n"); 
             break;
 
-    case CAF_UNENTERED:
+    case IND_STATIC:
+            debugBelch("IND_STATIC("); 
+            printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
+            debugBelch(")\n"); 
+            break;
+
+    /* Cannot happen -- use default case.
+    case RET_BCO:
+    case RET_SMALL:
+    case RET_VEC_SMALL:
+    case RET_BIG:
+    case RET_VEC_BIG:
+    case RET_DYN:
+    case RET_FUN:
+    */
+
+    case UPDATE_FRAME:
         {
-           StgCAF* caf = stgCast(StgCAF*,obj);
-            fprintf(stderr,"CAF_UNENTERED("); 
-            printPtr((StgPtr)caf->body);
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->value); /* should be null */
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->link);  /* should be null */
-            fprintf(stderr,")\n"); 
+            StgUpdateFrame* u = stgCast(StgUpdateFrame*,obj);
+            debugBelch("UPDATE_FRAME(");
+            printPtr((StgPtr)GET_INFO(u));
+            debugBelch(",");
+            printPtr((StgPtr)u->updatee);
+            debugBelch(")\n"); 
             break;
         }
 
-    case CAF_ENTERED:
+    case CATCH_FRAME:
         {
-           StgCAF* caf = stgCast(StgCAF*,obj);
-            fprintf(stderr,"CAF_ENTERED("); 
-            printPtr((StgPtr)caf->body);
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->value);
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->link);
-            fprintf(stderr,")\n"); 
+            StgCatchFrame* u = stgCast(StgCatchFrame*,obj);
+            debugBelch("CATCH_FRAME(");
+            printPtr((StgPtr)GET_INFO(u));
+            debugBelch(",");
+            printPtr((StgPtr)u->handler);
+            debugBelch(")\n"); 
             break;
         }
 
-    case CAF_BLACKHOLE:
-            fprintf(stderr,"CAF_BH("); 
-            printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue);
-            fprintf(stderr,")\n"); 
+    case STOP_FRAME:
+        {
+            StgStopFrame* u = stgCast(StgStopFrame*,obj);
+            debugBelch("STOP_FRAME(");
+            printPtr((StgPtr)GET_INFO(u));
+            debugBelch(")\n"); 
             break;
+        }
 
-    case BLACKHOLE:
-            fprintf(stderr,"BH\n"); 
+    case CAF_BLACKHOLE:
+            debugBelch("CAF_BH"); 
             break;
 
-    case BLACKHOLE_BQ:
-            fprintf(stderr,"BQ("); 
-            printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue);
-            fprintf(stderr,")\n"); 
+    case BLACKHOLE:
+            debugBelch("BH\n"); 
             break;
 
-    case CONSTR:
-    case CONSTR_1_0: case CONSTR_0_1:
-    case CONSTR_1_1: case CONSTR_0_2: case CONSTR_2_0:
-    case CONSTR_INTLIKE:
-    case CONSTR_CHARLIKE:
-    case CONSTR_STATIC:
-    case CONSTR_NOCAF_STATIC:
-        {
-            /* We can't use printStdObject because we want to print the
-             * tag as well.
-            */
-            StgWord i, j;
-            const StgInfoTable* info = get_itbl(obj);
-            fprintf(stderr,"PACK(");
-            printPtr((StgPtr)obj->header.info);
-            fprintf(stderr,"(tag=%d)",info->srt_len);
-            for (i = 0; i < info->layout.payload.ptrs; ++i) {
-                fprintf(stderr,", ");
-                printPtr(payloadPtr(obj,i));
-            }
-            for (j = 0; j < info->layout.payload.nptrs; ++j) {
-                fprintf(stderr,", %x#",payloadWord(obj,i+j));
-            }
-            fprintf(stderr,")\n");
+    case SE_BLACKHOLE:
+            debugBelch("SE_BH\n"); 
             break;
-        }
 
-    case FUN:
-    case FUN_1_0: case FUN_0_1: 
-    case FUN_1_1: case FUN_0_2: case FUN_2_0:
-    case FUN_STATIC:
-            printStdObject(obj,"FUN");
+    case SE_CAF_BLACKHOLE:
+            debugBelch("SE_CAF_BH\n"); 
             break;
 
-    case THUNK:
-    case THUNK_1_0: case THUNK_0_1:
-    case THUNK_1_1: case THUNK_0_2: case THUNK_2_0:
-    case THUNK_STATIC:
-            /* ToDo: will this work for THUNK_STATIC too? */
-            printStdObject(obj,"THUNK");
-            break;
-#if 0
     case ARR_WORDS:
         {
             StgWord i;
-            fprintf(stderr,"ARR_WORDS(\"");
-            /* ToDo: we can't safely assume that this is a string! */
+            debugBelch("ARR_WORDS(\"");
+            /* ToDo: we can't safely assume that this is a string! 
             for (i = 0; arrWordsGetChar(obj,i); ++i) {
                 putchar(arrWordsGetChar(obj,i));
-            }
-            fprintf(stderr,"\")\n");
+               } */
+           for (i=0; i<((StgArrWords *)obj)->words; i++)
+             debugBelch("%lu", (lnat)((StgArrWords *)obj)->payload[i]);
+            debugBelch("\")\n");
             break;
         }
-#endif
-    case UPDATE_FRAME:
+
+    case MUT_ARR_PTRS_CLEAN:
+       debugBelch("MUT_ARR_PTRS_CLEAN(size=%lu)\n", (lnat)((StgMutArrPtrs *)obj)->ptrs);
+       break;
+
+    case MUT_ARR_PTRS_DIRTY:
+       debugBelch("MUT_ARR_PTRS_DIRTY(size=%lu)\n", (lnat)((StgMutArrPtrs *)obj)->ptrs);
+       break;
+
+    case MUT_ARR_PTRS_FROZEN:
+       debugBelch("MUT_ARR_PTRS_FROZEN(size=%lu)\n", (lnat)((StgMutArrPtrs *)obj)->ptrs);
+       break;
+
+    case MVAR:
         {
-            StgUpdateFrame* u = stgCast(StgUpdateFrame*,obj);
-            fprintf(stderr,"UpdateFrame(");
-            printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,",");
-            printPtr((StgPtr)u->updatee);
-            fprintf(stderr,",");
-            printPtr((StgPtr)u->link);
-            fprintf(stderr,")\n"); 
-            break;
+         StgMVar* mv = (StgMVar*)obj;
+         debugBelch("MVAR(head=%p, tail=%p, value=%p)\n", mv->head, mv->tail, mv->value);
+          break;
         }
 
-    case CATCH_FRAME:
+    case MUT_VAR_CLEAN:
         {
-            StgCatchFrame* u = stgCast(StgCatchFrame*,obj);
-            fprintf(stderr,"CatchFrame(");
-            printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,",");
-            printPtr((StgPtr)u->handler);
-            fprintf(stderr,",");
-            printPtr((StgPtr)u->link);
-            fprintf(stderr,")\n"); 
-            break;
+         StgMutVar* mv = (StgMutVar*)obj;
+         debugBelch("MUT_VAR_CLEAN(var=%p)\n", mv->var);
+          break;
         }
 
-    case SEQ_FRAME:
+    case MUT_VAR_DIRTY:
         {
-            StgSeqFrame* u = stgCast(StgSeqFrame*,obj);
-            fprintf(stderr,"SeqFrame(");
-            printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,",");
-            printPtr((StgPtr)u->link);
-            fprintf(stderr,")\n"); 
-            break;
+         StgMutVar* mv = (StgMutVar*)obj;
+         debugBelch("MUT_VAR_DIRTY(var=%p)\n", mv->var);
+          break;
         }
 
-    case STOP_FRAME:
-        {
-            StgStopFrame* u = stgCast(StgStopFrame*,obj);
-            fprintf(stderr,"StopFrame(");
-            printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,")\n"); 
+    case WEAK:
+            debugBelch("WEAK("); 
+           debugBelch(" key=%p value=%p finalizer=%p", 
+                   (StgPtr)(((StgWeak*)obj)->key),
+                   (StgPtr)(((StgWeak*)obj)->value),
+                   (StgPtr)(((StgWeak*)obj)->finalizer));
+            debugBelch(")\n"); 
+           /* ToDo: chase 'link' ? */
             break;
-        }
+
+    case STABLE_NAME:
+            debugBelch("STABLE_NAME(%lu)\n", (lnat)((StgStableName*)obj)->sn); 
+            break;
+
+    case TSO:
+      debugBelch("TSO("); 
+      debugBelch("%d (%p)",((StgTSO*)obj)->id, (StgTSO*)obj);
+      debugBelch(")\n"); 
+      break;
+
+#if defined(PAR)
+    case BLOCKED_FETCH:
+      debugBelch("BLOCKED_FETCH("); 
+      printGA(&(stgCast(StgBlockedFetch*,obj)->ga));
+      printPtr((StgPtr)(stgCast(StgBlockedFetch*,obj)->node));
+      debugBelch(")\n"); 
+      break;
+
+    case FETCH_ME:
+      debugBelch("FETCH_ME("); 
+      printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga);
+      debugBelch(")\n"); 
+      break;
+
+    case FETCH_ME_BQ:
+      debugBelch("FETCH_ME_BQ("); 
+      // printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga);
+      printPtr((StgPtr)stgCast(StgFetchMeBlockingQueue*,obj)->blocking_queue);
+      debugBelch(")\n"); 
+      break;
+#endif
+
+#if defined(GRAN) || defined(PAR)
+    case RBH:
+      debugBelch("RBH("); 
+      printPtr((StgPtr)stgCast(StgRBH*,obj)->blocking_queue);
+      debugBelch(")\n"); 
+      break;
+
+#endif
+
+#if 0
+      /* Symptomatic of a problem elsewhere, have it fall-through & fail */
+    case EVACUATED:
+      debugBelch("EVACUATED("); 
+      printClosure((StgEvacuated*)obj->evacuee);
+      debugBelch(")\n"); 
+      break;
+#endif
+
+#if defined(PAR) && defined(DIST)
+    case REMOTE_REF:
+      debugBelch("REMOTE_REF("); 
+      printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga);
+      debugBelch(")\n"); 
+      break;
+#endif
+
     default:
             //barf("printClosure %d",get_itbl(obj)->type);
-            fprintf(stderr, "*** printClosure: unknown type %d ****\n",get_itbl(obj)->type );
+            debugBelch("*** printClosure: unknown type %d ****\n",
+                    get_itbl(obj)->type );
+            barf("printClosure %d",get_itbl(obj)->type);
             return;
     }
 }
 
-StgPtr printStackObj( StgPtr sp )
+/*
+void printGraph( StgClosure *obj )
 {
-    /*fprintf(stderr,"Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */
-
-    if (IS_ARG_TAG(*sp)) {
-
-#ifdef DEBUG_EXTRA
-        StackTag tag = (StackTag)*sp;
-        switch ( tag ) {
-        case ILLEGAL_TAG:
-                barf("printStackObj: ILLEGAL_TAG");
-                break;
-        case REALWORLD_TAG:
-                fprintf(stderr,"RealWorld#\n");
-                break;
-        case INT_TAG:
-                fprintf(stderr,"Int# %d\n", *(StgInt*)(sp+1));
-                break;
-        case INT64_TAG:
-                fprintf(stderr,"Int64# %lld\n", *(StgInt64*)(sp+1));
-                break;
-        case WORD_TAG:
-                fprintf(stderr,"Word# %d\n", *(StgWord*)(sp+1));
-                break;
-        case ADDR_TAG:
-                fprintf(stderr,"Addr# "); printPtr(*(StgAddr*)(sp+1)); fprintf(stderr,"\n");
-                break;
-        case CHAR_TAG:
-                fprintf(stderr,"Char# %d\n", *(StgChar*)(sp+1));
-                break;
-        case FLOAT_TAG:
-                fprintf(stderr,"Float# %f\n", PK_FLT(sp+1));
-                break;
-        case DOUBLE_TAG:
-                fprintf(stderr,"Double# %f\n", PK_DBL(sp+1));
-                break;
-        default:
-                barf("printStackObj: unrecognised ARGTAG %d",tag);
-        }
-        sp += 1 + ARG_SIZE(tag);
+ printClosure(obj);
+}
+*/
 
-#else /* !DEBUG_EXTRA */
-       {
-           StgWord tag = *sp++;
-           nat i;
-           fprintf(stderr,"Tag: %d words\n", tag);
-           for (i = 0; i < tag; i++) {
-               fprintf(stderr,"Word# %d\n", *sp++);
-           }
-       }
-#endif
+StgPtr
+printStackObj( StgPtr sp )
+{
+    /*debugBelch("Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */
 
-    } else {
         StgClosure* c = (StgClosure*)(*sp);
         printPtr((StgPtr)*sp);
-#ifdef INTERPRETER
-        if (c == &ret_bco_info) {
-           fprintf(stderr, "\t\t");
-           fprintf(stderr, "ret_bco_info\n" );
+        if (c == (StgClosure*)&stg_ctoi_R1p_info) {
+           debugBelch("\t\t\tstg_ctoi_ret_R1p_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_R1n_info) {
+           debugBelch("\t\t\tstg_ctoi_ret_R1n_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_F1_info) {
+           debugBelch("\t\t\tstg_ctoi_ret_F1_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_D1_info) {
+           debugBelch("\t\t\tstg_ctoi_ret_D1_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_V_info) {
+           debugBelch("\t\t\tstg_ctoi_ret_V_info\n" );
        } else
-        if (IS_HUGS_CONSTR_INFO(GET_INFO(c))) {
-           fprintf(stderr, "\t\t\t");
-           fprintf(stderr, "ConstrInfoTable\n" );
-        } else
-#endif
         if (get_itbl(c)->type == BCO) {
-           fprintf(stderr, "\t\t\t");
-           fprintf(stderr, "BCO(...)\n"); 
+           debugBelch("\t\t\t");
+           debugBelch("BCO(...)\n"); 
         }
         else {
-           fprintf(stderr, "\t\t\t");
+           debugBelch("\t\t\t");
            printClosure ( (StgClosure*)(*sp));
         }
         sp += 1;
-    }
+
     return sp;
     
 }
 
-void printStackChunk( StgPtr sp, StgPtr spBottom )
+static void
+printSmallBitmap( StgPtr spBottom, StgPtr payload, StgWord bitmap, nat size )
+{
+    StgPtr p;
+    nat i;
+
+    p = payload;
+    for(i = 0; i < size; i++, bitmap >>= 1 ) {
+       debugBelch("   stk[%ld] (%p) = ", (long)(spBottom-(payload+i)), payload+i);
+       if ((bitmap & 1) == 0) {
+           printPtr((P_)payload[i]);
+           debugBelch("\n");
+       } else {
+           debugBelch("Word# %lu\n", (lnat)payload[i]);
+       }
+    }
+}
+
+static void
+printLargeBitmap( StgPtr spBottom, StgPtr payload, StgLargeBitmap* large_bitmap, nat size )
 {
-    StgWord32 bitmap;
+    StgWord bmp;
+    nat i, j;
+
+    i = 0;
+    for (bmp=0; i < size; bmp++) {
+       StgWord bitmap = large_bitmap->bitmap[bmp];
+       j = 0;
+       for(; i < size && j < BITS_IN(W_); j++, i++, bitmap >>= 1 ) {
+           debugBelch("   stk[%lu] (%p) = ", (lnat)(spBottom-(payload+i)), payload+i);
+           if ((bitmap & 1) == 0) {
+               printPtr((P_)payload[i]);
+               debugBelch("\n");
+           } else {
+               debugBelch("Word# %lu\n", (lnat)payload[i]);
+           }
+       }
+    }
+}
+
+void
+printStackChunk( StgPtr sp, StgPtr spBottom )
+{
+    StgWord bitmap;
     const StgInfoTable *info;
 
     ASSERT(sp <= spBottom);
-    while (sp < spBottom) {
-      if (!IS_ARG_TAG(*sp) && LOOKS_LIKE_GHC_INFO(*sp)) {
+    for (; sp < spBottom; sp += stack_frame_sizeW((StgClosure *)sp)) {
+
        info = get_itbl((StgClosure *)sp);
-       switch (info->type) {
 
+       switch (info->type) {
+           
        case UPDATE_FRAME:
-           printObj( stgCast(StgClosure*,sp) );
-           sp += sizeofW(StgUpdateFrame);
-           continue;
-
-       case SEQ_FRAME:
-           printObj( stgCast(StgClosure*,sp) );
-           sp += sizeofW(StgSeqFrame);
-           continue;
-
        case CATCH_FRAME:
-           printObj( stgCast(StgClosure*,sp) );
-           sp += sizeofW(StgCatchFrame);
+           printObj((StgClosure*)sp);
            continue;
 
        case STOP_FRAME:
-           /* not quite: ASSERT(stgCast(StgPtr,su) == spBottom); */
-           printObj( stgCast(StgClosure*,sp) );
-           continue;
+           printObj((StgClosure*)sp);
+           return;
 
        case RET_DYN:
-         fprintf(stderr, "RET_DYN (%p)\n", sp);
-         bitmap = *++sp;
-         ++sp;
-         fprintf(stderr, "Bitmap: 0x%x\n", bitmap);
-         goto small_bitmap;
+       { 
+           StgRetDyn* r;
+           StgPtr p;
+           StgWord dyn;
+           nat size;
+
+           r = (StgRetDyn *)sp;
+           dyn = r->liveness;
+           debugBelch("RET_DYN (%p)\n", r);
+
+           p = (P_)(r->payload);
+           printSmallBitmap(spBottom, sp,
+                            RET_DYN_LIVENESS(r->liveness), 
+                            RET_DYN_BITMAP_SIZE);
+           p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE;
+
+           for (size = RET_DYN_NONPTRS(dyn); size > 0; size--) {
+               debugBelch("   stk[%ld] (%p) = ", (long)(spBottom-p), p);
+               debugBelch("Word# %ld\n", (long)*p);
+               p++;
+           }
+       
+           for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
+               debugBelch("   stk[%ld] (%p) = ", (long)(spBottom-p), p);
+               printPtr(p);
+               p++;
+           }
+           continue;
+       }
 
        case RET_SMALL:
        case RET_VEC_SMALL:
-         fprintf(stderr, "RET_SMALL (%p)\n", sp);
-         bitmap = info->layout.bitmap;
-         sp++;
-       small_bitmap:
-         while (bitmap != 0) {
-           fprintf(stderr,"Stack[%d] (%p) = ", spBottom-sp, sp);
-           if ((bitmap & 1) == 0) {
-             printPtr((P_)*sp);
-             fprintf(stderr,"\n");
-           } else {
-             fprintf(stderr,"Word# %d\n", *sp++);
-           }         
-           sp++;
-           bitmap = bitmap >> 1;
-           }
-         continue;
+           debugBelch("RET_SMALL (%p)\n", info);
+           bitmap = info->layout.bitmap;
+           printSmallBitmap(spBottom, sp+1, 
+                            BITMAP_BITS(bitmap), BITMAP_SIZE(bitmap));
+           continue;
 
-       case RET_BIG:
-       case RET_VEC_BIG:
-         barf("todo");
+       case RET_BCO: {
+           StgBCO *bco;
+           
+           bco = ((StgBCO *)sp[1]);
 
-       default:
-         break;
+           debugBelch("RET_BCO (%p)\n", sp);
+           printLargeBitmap(spBottom, sp+2,
+                            BCO_BITMAP(bco), BCO_BITMAP_SIZE(bco));
+           continue;
        }
-      }
-      fprintf(stderr,"Stack[%d] (%p) = ", spBottom-sp, sp);
-      sp = printStackObj(sp);
-    }
-}
 
-void printStack( StgPtr sp, StgPtr spBottom, StgUpdateFrame* su )
-{
-    /* check everything down to the first update frame */
-    printStackChunk( sp, stgCast(StgPtr,su) );
-    while ( stgCast(StgPtr,su) < spBottom) {
-       sp = stgCast(StgPtr,su);
-       switch (get_itbl(su)->type) {
-       case UPDATE_FRAME:
-                printObj( stgCast(StgClosure*,su) );
-                sp += sizeofW(StgUpdateFrame);
-               su = su->link;
+       case RET_BIG:
+       case RET_VEC_BIG:
+           barf("todo");
+
+       case RET_FUN:
+       {
+           StgFunInfoTable *fun_info;
+           StgRetFun *ret_fun;
+           nat size;
+
+           ret_fun = (StgRetFun *)sp;
+           fun_info = get_fun_itbl(ret_fun->fun);
+           size = ret_fun->size;
+           debugBelch("RET_FUN (%p) (type=%d)\n", ret_fun->fun, fun_info->f.fun_type);
+           switch (fun_info->f.fun_type) {
+           case ARG_GEN:
+               printSmallBitmap(spBottom, sp+2,
+                                BITMAP_BITS(fun_info->f.b.bitmap),
+                                BITMAP_SIZE(fun_info->f.b.bitmap));
                break;
-       case SEQ_FRAME:
-                printObj( stgCast(StgClosure*,su) );
-                sp += sizeofW(StgSeqFrame);
-               su = stgCast(StgSeqFrame*,su)->link;
+           case ARG_GEN_BIG:
+               printLargeBitmap(spBottom, sp+2,
+                                GET_FUN_LARGE_BITMAP(fun_info),
+                                GET_FUN_LARGE_BITMAP(fun_info)->size);
                break;
-       case CATCH_FRAME:
-                printObj( stgCast(StgClosure*,su) );
-                sp += sizeofW(StgCatchFrame);
-               su = stgCast(StgCatchFrame*,su)->link;
+           default:
+               printSmallBitmap(spBottom, sp+2,
+                                BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]),
+                                BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]));
                break;
-       case STOP_FRAME:
-               /* not quite: ASSERT(stgCast(StgPtr,su) == spBottom); */
-                printObj( stgCast(StgClosure*,su) );
-               return;
+           }
+           continue;
+       }
+          
        default:
-               barf("printStack: weird record found on update frame list.");
+           debugBelch("unknown object %d\n", info->type);
+           barf("printStackChunk");
        }
-       printStackChunk( sp, stgCast(StgPtr,su) );
     }
-    ASSERT(stgCast(StgPtr,su) == spBottom);
 }
 
 void printTSO( StgTSO *tso )
 {
-    printStack( tso->sp, tso->stack+tso->stack_size,tso->su);
-    /* printStackChunk( tso->sp, tso->stack+tso->stack_size); */
+    printStackChunk( tso->sp, tso->stack+tso->stack_size);
 }
 
+/* -----------------------------------------------------------------------------
+   Closure types
+   
+   NOTE: must be kept in sync with the closure types in includes/ClosureTypes.h
+   -------------------------------------------------------------------------- */
+
+static char *closure_type_names[] = {
+    "INVALID_OBJECT",
+    "CONSTR",
+    "CONSTR_1",
+    "CONSTR_0",
+    "CONSTR_2",
+    "CONSTR_1",
+    "CONSTR_0",
+    "CONSTR_INTLIKE",
+    "CONSTR_CHARLIKE",
+    "CONSTR_STATIC",
+    "CONSTR_NOCAF_STATIC",
+    "FUN",
+    "FUN_1_0",
+    "FUN_0_1",
+    "FUN_2_0",
+    "FUN_1_1",
+    "FUN_0",
+    "FUN_STATIC",
+    "THUNK",
+    "THUNK_1_0",
+    "THUNK_0_1",
+    "THUNK_2_0",
+    "THUNK_1_1",
+    "THUNK_0",
+    "THUNK_STATIC",
+    "THUNK_SELECTOR",
+    "BCO",
+    "AP_UPD",
+    "PAP",
+    "AP_STACK",
+    "IND",
+    "IND_OLDGEN",
+    "IND_PERM",
+    "IND_OLDGEN_PERM",
+    "IND_STATIC",
+    "RET_BCO",
+    "RET_SMALL",
+    "RET_VEC_SMALL",
+    "RET_BIG",
+    "RET_VEC_BIG",
+    "RET_DYN",
+    "RET_FUN",
+    "UPDATE_FRAME",
+    "CATCH_FRAME",
+    "STOP_FRAME",
+    "CAF_BLACKHOLE",
+    "BLACKHOLE",
+    "BLACKHOLE_BQ",
+    "SE_BLACKHOLE",
+    "SE_CAF_BLACKHOLE",
+    "MVAR",
+    "ARR_WORDS",
+    "MUT_ARR_PTRS_CLEAN",
+    "MUT_ARR_PTRS_DIRTY",
+    "MUT_ARR_PTRS_FROZEN",
+    "MUT_VAR_CLEAN",
+    "MUT_VAR_DIRTY",
+    "MUT_CONS",
+    "WEAK",
+    "FOREIGN",
+    "STABLE_NAME",
+    "TSO",
+    "BLOCKED_FETCH",
+    "FETCH_ME",
+    "FETCH_ME_BQ",
+    "RBH",
+    "EVACUATED",
+    "REMOTE_REF",
+    "TVAR_WAIT_QUEUE",
+    "TVAR",
+    "TREC_CHUNK",
+    "TREC_HEADER",
+    "ATOMICALLY_FRAME",
+    "CATCH_RETRY_FRAME"
+};
+
+
+char *
+info_type(StgClosure *closure){ 
+  return closure_type_names[get_itbl(closure)->type];
+}
+
+char *
+info_type_by_ip(StgInfoTable *ip){ 
+  return closure_type_names[ip->type];
+}
+
+void
+info_hdr_type(StgClosure *closure, char *res){ 
+  strcpy(res,closure_type_names[get_itbl(closure)->type]);
+}
 
 /* --------------------------------------------------------------------------
  * Address printing code
@@ -502,15 +759,17 @@ struct entry {
     const char *name;
 };
 
-static nat max_table_size;
 static nat table_size;
 static struct entry* table;
 
+#ifdef USING_LIBBFD
+static nat max_table_size;
+
 static void reset_table( int size )
 {
     max_table_size = size;
     table_size = 0;
-    table = (struct entry *) malloc(size * sizeof(struct entry));
+    table = (struct entry *)stgMallocBytes(size * sizeof(struct entry), "Printer.c:reset_table()");
 }
 
 static void prepare_table( void )
@@ -527,7 +786,7 @@ static void insert( unsigned value, const char *name )
     table[table_size].name = name;
     table_size = table_size + 1;
 }
-
+#endif
 
 #if 0
 static rtsBool lookup_name( char *name, unsigned *result )
@@ -672,16 +931,15 @@ static void enZcode( char *in, char *out )
 }
 #endif
 
-rtsBool lookupGHCName( StgPtr addr, const char **result )
+const char *lookupGHCName( void *addr )
 {
     nat i;
     for( i = 0; i < table_size && table[i].value != (unsigned) addr; ++i ) {
     }
     if (i < table_size) {
-        *result = table[i].name;
-        return rtsTrue;
+        return table[i].name;
     } else {
-        return rtsFalse;
+        return NULL;
     }
 }
 
@@ -691,10 +949,10 @@ static void printZcoded( const char *raw )
     
     while ( raw[j] != '\0' ) {
         if (raw[j] == 'Z') {
-            fputc(unZcode(raw[j+1]),stderr);
+            debugBelch("%c", unZcode(raw[j+1]));
             j = j + 2;
         } else {
-            fputc(raw[j],stderr);
+            debugBelch("%c", unZcode(raw[j+1]));
             j = j + 1;
         }
     }
@@ -704,7 +962,10 @@ static void printZcoded( const char *raw )
  * Symbol table loading
  * ------------------------------------------------------------------------*/
 
-#ifdef HAVE_BFD_H
+/* Causing linking trouble on Win32 plats, so I'm
+   disabling this for now. 
+*/
+#ifdef USING_LIBBFD
 
 #include <bfd.h>
 
@@ -712,7 +973,7 @@ static void printZcoded( const char *raw )
  * rubbish like the obj-splitting symbols
  */
 
-static rtsBool isReal( flagword flags, const char *name )
+static rtsBool isReal( flagword flags STG_UNUSED, const char *name )
 {
 #if 0
     /* ToDo: make this work on BFD */
@@ -760,7 +1021,7 @@ extern void DEBUG_LoadSymbols( char *name )
        }     
 #if 0
        if (storage_needed == 0) {
-           belch("no storage needed");
+           debugBelch("no storage needed");
        }
 #endif
        symbol_table = (asymbol **) stgMallocBytes(storage_needed,"DEBUG_LoadSymbols");
@@ -774,14 +1035,14 @@ extern void DEBUG_LoadSymbols( char *name )
         for( i = 0; i != number_of_symbols; ++i ) {
             symbol_info info;
             bfd_get_symbol_info(abfd,symbol_table[i],&info);
-            /*fprintf(stderr,"\t%c\t0x%x      \t%s\n",info.type,(nat)info.value,info.name); */
+            /*debugBelch("\t%c\t0x%x      \t%s\n",info.type,(nat)info.value,info.name); */
             if (isReal(info.type, info.name)) {
                 num_real_syms += 1;
             }
         }
     
-        IF_DEBUG(evaluator,
-                 fprintf(stderr,"Loaded %ld symbols. Of which %ld are real symbols\n", 
+        IF_DEBUG(interpreter,
+                 debugBelch("Loaded %ld symbols. Of which %ld are real symbols\n", 
                          number_of_symbols, num_real_syms)
                  );
 
@@ -794,29 +1055,73 @@ extern void DEBUG_LoadSymbols( char *name )
                 insert( info.value, info.name );
             }
         }
-        
-        free(symbol_table);
+
+        stgFree(symbol_table);
     }
     prepare_table();
 }
 
 #else /* HAVE_BFD_H */
 
-extern void DEBUG_LoadSymbols( char *name )
+extern void DEBUG_LoadSymbols( char *name STG_UNUSED )
 {
   /* nothing, yet */
 }
 
 #endif /* HAVE_BFD_H */
 
+void findPtr(P_ p, int);               /* keep gcc -Wall happy */
+
+void
+findPtr(P_ p, int follow)
+{
+  nat s, g;
+  P_ q, r;
+  bdescr *bd;
+#if defined(__GNUC__)
+  const int arr_size = 1024;
+#else
+#define arr_size 1024
+#endif
+  StgPtr arr[arr_size];
+  int i = 0;
+
+  for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+      for (s = 0; s < generations[g].n_steps; s++) {
+         bd = generations[g].steps[s].blocks;
+         for (; bd; bd = bd->link) {
+             for (q = bd->start; q < bd->free; q++) {
+                 if (*q == (W_)p) {
+                     if (i < arr_size) {
+                         r = q;
+                         while (!LOOKS_LIKE_INFO_PTR(*r) || (P_)*r == NULL) {
+                             r--;
+                         }
+                         debugBelch("%p = ", r);
+                         printClosure((StgClosure *)r);
+                         arr[i++] = r;
+                     } else {
+                         return;
+                     }
+                 }
+             }
+         }
+      }
+  }
+  if (follow && i == 1) {
+      debugBelch("-->\n");
+      findPtr(arr[0], 1);
+  }
+}
+
 #else /* DEBUG */
 void printPtr( StgPtr p )
 {
-    fprintf(stderr, "ptr 0x%p (enable -DDEBUG for more info) " , p );
+    debugBelch("ptr 0x%p (enable -DDEBUG for more info) " , p );
 }
   
 void printObj( StgClosure *obj )
 {
-    fprintf(stderr, "obj 0x%p (enable -DDEBUG for more info) " , obj );
+    debugBelch("obj 0x%p (enable -DDEBUG for more info) " , obj );
 }
 #endif /* DEBUG */