X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FPrinter.c;h=8290d220a0b0498373ec5ec47e4b370f2b09bcd4;hb=c56641e7752db313effe332b81f9e56275342fbd;hp=b163389b054682565c1ed372285ab909a69e47cd;hpb=ee3e75b51e5a86dda79bb990a83bfaa49915a22a;p=ghc-hetmet.git diff --git a/ghc/rts/Printer.c b/ghc/rts/Printer.c index b163389..8290d22 100644 --- a/ghc/rts/Printer.c +++ b/ghc/rts/Printer.c @@ -1,5 +1,4 @@ /* ----------------------------------------------------------------------------- - * $Id: Printer.c,v 1.34 2001/01/29 17:23:41 simonmar Exp $ * * (c) The GHC Team, 1994-2000. * @@ -7,110 +6,201 @@ * * ---------------------------------------------------------------------------*/ +#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 +#include +#if defined(GRAN) || defined(PAR) // HWL: explicit fixed header size to make debugging easier -int fixed_hs = FIXED_HS, itbl_sz = sizeofW(StgInfoTable), - uf_sz=sizeofW(StgUpdateFrame), sf_sz=sizeofW(StgSeqFrame); +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 -char* lookupHugsItblName ( void* itbl ); -#endif - void printPtr( StgPtr p ) { -#ifdef INTERPRETER - char* str; -#endif 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,", "); + debugBelch(", "); printPtr((StgPtr)obj->payload[i]); } for (j = 0; j < info->layout.payload.nptrs; ++j) { - fprintf(stderr,", %pd#",obj->payload[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 GHCI + + 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; -#endif - 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,", "); + debugBelch(", "); printPtr((P_)ap->payload[i]); } - fprintf(stderr,")\n"); + debugBelch(")\n"); break; } @@ -118,219 +208,236 @@ 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,", "); + debugBelch(", "); printPtr((StgPtr)pap->payload[i]); } - fprintf(stderr,")\n"); + debugBelch(")\n"); break; } - case IND: - fprintf(stderr,"IND("); - printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); - fprintf(stderr,")\n"); + 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_STATIC: - fprintf(stderr,"IND_STATIC("); + case IND: + debugBelch("IND("); printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); - fprintf(stderr,")\n"); + debugBelch(")\n"); break; case IND_OLDGEN: - fprintf(stderr,"IND_OLDGEN("); + debugBelch("IND_OLDGEN("); printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); - fprintf(stderr,")\n"); + debugBelch(")\n"); break; - case CAF_BLACKHOLE: - fprintf(stderr,"CAF_BH("); - printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue); - fprintf(stderr,")\n"); + case IND_PERM: + debugBelch("IND("); + printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + debugBelch(")\n"); break; - case SE_BLACKHOLE: - fprintf(stderr,"SE_BH\n"); + case IND_OLDGEN_PERM: + debugBelch("IND_OLDGEN_PERM("); + printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + debugBelch(")\n"); break; - case SE_CAF_BLACKHOLE: - fprintf(stderr,"SE_CAF_BH\n"); + case IND_STATIC: + debugBelch("IND_STATIC("); + printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + debugBelch(")\n"); break; - case BLACKHOLE: - fprintf(stderr,"BH\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 BLACKHOLE_BQ: - fprintf(stderr,"BQ("); - printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue); - fprintf(stderr,")\n"); + case UPDATE_FRAME: + { + StgUpdateFrame* u = stgCast(StgUpdateFrame*,obj); + debugBelch("UPDATE_FRAME("); + printPtr((StgPtr)GET_INFO(u)); + debugBelch(","); + printPtr((StgPtr)u->updatee); + debugBelch(")\n"); break; + } - case TSO: - fprintf(stderr,"TSO("); - fprintf(stderr,"%d (%p)",((StgTSO*)obj)->id, (StgTSO*)obj); - fprintf(stderr,")\n"); - break; - -#if defined(PAR) - case BLOCKED_FETCH: - fprintf(stderr,"BLOCKED_FETCH("); - printGA(&(stgCast(StgBlockedFetch*,obj)->ga)); - printPtr((StgPtr)(stgCast(StgBlockedFetch*,obj)->node)); - fprintf(stderr,")\n"); - break; - - case FETCH_ME: - fprintf(stderr,"FETCH_ME("); - printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga); - fprintf(stderr,")\n"); - break; - - case FETCH_ME_BQ: - fprintf(stderr,"FETCH_ME_BQ("); - // printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga); - printPtr((StgPtr)stgCast(StgFetchMeBlockingQueue*,obj)->blocking_queue); - fprintf(stderr,")\n"); - break; -#endif -#if defined(GRAN) || defined(PAR) - case RBH: - fprintf(stderr,"RBH("); - printPtr((StgPtr)stgCast(StgRBH*,obj)->blocking_queue); - fprintf(stderr,")\n"); - break; - -#endif - - 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: + case CATCH_FRAME: { - /* 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((StgPtr)obj->payload[i]); - } - for (j = 0; j < info->layout.payload.nptrs; ++j) { - fprintf(stderr,", %p#", obj->payload[i+j]); - } - fprintf(stderr,")\n"); + StgCatchFrame* u = stgCast(StgCatchFrame*,obj); + debugBelch("CATCH_FRAME("); + printPtr((StgPtr)GET_INFO(u)); + debugBelch(","); + printPtr((StgPtr)u->handler); + debugBelch(")\n"); break; } -#ifdef XMLAMBDA -/* rows are mutarrays in xmlambda, maybe we should make a new type: ROW */ - case MUT_ARR_PTRS_FROZEN: - { - StgWord i; - StgMutArrPtrs* p = stgCast(StgMutArrPtrs*,obj); + case STOP_FRAME: + { + StgStopFrame* u = stgCast(StgStopFrame*,obj); + debugBelch("STOP_FRAME("); + printPtr((StgPtr)GET_INFO(u)); + debugBelch(")\n"); + break; + } - fprintf(stderr,"Row<%i>(",p->ptrs); - for (i = 0; i < p->ptrs; ++i) { - if (i > 0) fprintf(stderr,", "); - printPtr((StgPtr)(p->payload[i])); - } - fprintf(stderr,")\n"); + case CAF_BLACKHOLE: + debugBelch("CAF_BH"); break; - } -#endif - 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 BLACKHOLE: + debugBelch("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"); + case SE_BLACKHOLE: + debugBelch("SE_BH\n"); break; - case THUNK_SELECTOR: - printStdObject(obj,"THUNK_SELECTOR"); + case SE_CAF_BLACKHOLE: + debugBelch("SE_CAF_BH\n"); break; case ARR_WORDS: { StgWord i; - fprintf(stderr,"ARR_WORDS(\""); + 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)); } */ for (i=0; i<((StgArrWords *)obj)->words; i++) - fprintf(stderr, "%d", ((StgArrWords *)obj)->payload[i]); - fprintf(stderr,"\")\n"); + debugBelch("%lu", (lnat)((StgArrWords *)obj)->payload[i]); + debugBelch("\")\n"); break; } - 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", + debugBelch("*** printClosure: unknown type %d ****\n", get_itbl(obj)->type ); + barf("printClosure %d",get_itbl(obj)->type); return; } } @@ -342,158 +449,198 @@ void printGraph( StgClosure *obj ) } */ -StgPtr printStackObj( StgPtr sp ) +StgPtr +printStackObj( StgPtr sp ) { - /*fprintf(stderr,"Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */ - - if (IS_ARG_TAG(*sp)) { - nat i; - StgWord tag = *sp++; - fprintf(stderr,"Tagged{"); - for (i = 0; i < tag; i++) { - fprintf(stderr,"0x%x#", (unsigned)(*sp++)); - if (i < tag-1) fprintf(stderr, ", "); - } - fprintf(stderr, "}\n"); - } else { + /*debugBelch("Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */ + StgClosure* c = (StgClosure*)(*sp); printPtr((StgPtr)*sp); -#ifdef GHCI - if (c == (StgClosure*)&stg_ctoi_ret_R1p_info) { - fprintf(stderr, "\t\t\tstg_ctoi_ret_R1p_info\n" ); + if (c == (StgClosure*)&stg_ctoi_R1p_info) { + debugBelch("\t\t\tstg_ctoi_ret_R1p_info\n" ); } else - if (c == (StgClosure*)&stg_ctoi_ret_R1n_info) { - fprintf(stderr, "\t\t\tstg_ctoi_ret_R1n_info\n" ); + if (c == (StgClosure*)&stg_ctoi_R1n_info) { + debugBelch("\t\t\tstg_ctoi_ret_R1n_info\n" ); } else - if (c == (StgClosure*)&stg_ctoi_ret_F1_info) { - fprintf(stderr, "\t\t\tstg_ctoi_ret_F1_info\n" ); + if (c == (StgClosure*)&stg_ctoi_F1_info) { + debugBelch("\t\t\tstg_ctoi_ret_F1_info\n" ); } else - if (c == (StgClosure*)&stg_ctoi_ret_D1_info) { - fprintf(stderr, "\t\t\tstg_ctoi_ret_D1_info\n" ); + 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 -#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 ) +{ + 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 ) { - StgWord32 bitmap; + 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," stk[%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); } /* ----------------------------------------------------------------------------- @@ -503,72 +650,83 @@ void printTSO( StgTSO *tso ) -------------------------------------------------------------------------- */ static char *closure_type_names[] = { - "INVALID_OBJECT", /* 0 */ - "CONSTR", /* 1 */ - "CONSTR_1_0", /* 2 */ - "CONSTR_0_1", /* 3 */ - "CONSTR_2_0", /* 4 */ - "CONSTR_1_1", /* 5 */ - "CONSTR_0_2", /* 6 */ - "CONSTR_INTLIKE", /* 7 */ - "CONSTR_CHARLIKE", /* 8 */ - "CONSTR_STATIC", /* 9 */ - "CONSTR_NOCAF_STATIC", /* 10 */ - "FUN", /* 11 */ - "FUN_1_0", /* 12 */ - "FUN_0_1", /* 13 */ - "FUN_2_0", /* 14 */ - "FUN_1_1", /* 15 */ - "FUN_0_2", /* 16 */ - "FUN_STATIC", /* 17 */ - "THUNK", /* 18 */ - "THUNK_1_0", /* 19 */ - "THUNK_0_1", /* 20 */ - "THUNK_2_0", /* 21 */ - "THUNK_1_1", /* 22 */ - "THUNK_0_2", /* 23 */ - "THUNK_STATIC", /* 24 */ - "THUNK_SELECTOR", /* 25 */ - "BCO", /* 26 */ - "AP_UPD", /* 27 */ - "PAP", /* 28 */ - "IND", /* 29 */ - "IND_OLDGEN", /* 30 */ - "IND_PERM", /* 31 */ - "IND_OLDGEN_PERM", /* 32 */ - "IND_STATIC", /* 33 */ - "CAF_BLACKHOLE", /* 36 */ - "RET_BCO", /* 37 */ - "RET_SMALL", /* 38 */ - "RET_VEC_SMALL", /* 39 */ - "RET_BIG", /* 40 */ - "RET_VEC_BIG", /* 41 */ - "RET_DYN", /* 42 */ - "UPDATE_FRAME", /* 43 */ - "CATCH_FRAME", /* 44 */ - "STOP_FRAME", /* 45 */ - "SEQ_FRAME", /* 46 */ - "BLACKHOLE", /* 47 */ - "BLACKHOLE_BQ", /* 48 */ - "SE_BLACKHOLE", /* 49 */ - "SE_CAF_BLACKHOLE", /* 50 */ - "MVAR", /* 51 */ - "ARR_WORDS", /* 52 */ - "MUT_ARR_PTRS", /* 53 */ - "MUT_ARR_PTRS_FROZEN", /* 54 */ - "MUT_VAR", /* 55 */ - "WEAK", /* 56 */ - "FOREIGN", /* 57 */ - "STABLE_NAME", /* 58 */ - "TSO", /* 59 */ - "BLOCKED_FETCH", /* 60 */ - "FETCH_ME", /* 61 */ - "FETCH_ME_BQ", /* 62 */ - "RBH", /* 63 */ - "EVACUATED", /* 64 */ - "N_CLOSURE_TYPES" /* 65 */ + "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]; @@ -601,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 ) @@ -626,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 ) @@ -771,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; } } @@ -790,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; } } @@ -806,7 +965,7 @@ static void printZcoded( const char *raw ) /* Causing linking trouble on Win32 plats, so I'm disabling this for now. */ -#if defined(HAVE_BFD_H) && !defined(_WIN32) +#ifdef USING_LIBBFD #include @@ -814,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 */ @@ -825,7 +984,6 @@ static rtsBool isReal( flagword flags, const char *name ) return rtsFalse; } #else - (void)flags; /* keep gcc -Wall happy */ if (*name == '\0' || (name[0] == 'g' && name[1] == 'c' && name[2] == 'c') || (name[0] == 'c' && name[1] == 'c' && name[2] == '.')) { @@ -863,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"); @@ -877,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) ); @@ -897,8 +1055,8 @@ extern void DEBUG_LoadSymbols( char *name ) insert( info.value, info.name ); } } - - free(symbol_table); + + stgFree(symbol_table); } prepare_table(); } @@ -912,38 +1070,58 @@ extern void DEBUG_LoadSymbols( char *name STG_UNUSED ) #endif /* HAVE_BFD_H */ -#include "StoragePriv.h" - -void findPtr(P_ p); /* keep gcc -Wall happy */ +void findPtr(P_ p, int); /* keep gcc -Wall happy */ void -findPtr(P_ p) +findPtr(P_ p, int follow) { nat s, g; - P_ q; + 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++) { - for (bd = generations[g].steps[s].blocks; bd; bd = bd->link) { - for (q = bd->start; q < bd->free; q++) { - if (*q == (W_)p) { - printf("%p\n", q); + 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 */