⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mal_debugger.mx

📁 一个内存数据库的源代码这是服务器端还有客户端
💻 MX
📖 第 1 页 / 共 4 页
字号:
			b = BATdescriptor(v->val.ival);			if (b) {				nme = getTypeName(n->type);				nmeOnStk = getTypeName(newBatType(b->htype, b->ttype));				if (strcmp(nme, nmeOnStk)) {					printTraceCall(cntxt,mb,stk,pc);					stream_printf(cntxt->fdout, "!ERROR: %s != :%s\n",						nme, nmeOnStk);					stk->cmd='n';				}				BBPunfix(b->batCacheid);				GDKfree(nme);			}		}	}}voidmdbStep(Client cntxt, MalBlkPtr mb, MalStkPtr stk, int pc){	InstrPtr p;	char ch;	mdbSessionActive= 1; /* for name completion */	/* mdbSanityCheck(cntxt, mb, stk, pc); expensive */	switch (stk->cmd) {	case 'c':		p = getInstrPtr(mb, pc);		ch= isBreakpoint(cntxt,mb, p, pc);		if( ch == 't'){			if (cntxt != mal_clients) 				/* help MapiClients with fake prompt */				stream_printf(cntxt->fdout,"mdb>");			printTraceCall(cntxt,mb,stk,pc);		} else if( ch )			mdbCommand(cntxt, mb, stk, p, pc);		break;	case 's':	case 'n':		p = getInstrPtr(mb, pc);		mdbCommand(cntxt, mb, stk, p, pc);		break;	case 'C':		mdbSessionActive= 0; /* for name completion */	}	if( mb->errors) {		MalStkPtr su;		/* return from this debugger */		for (su = stk; su; su = su->up)			su->cmd = 0;		stk->cmd = 'x';	/* will force a graceful termination */	}	if( mdbSessionActive== 0) return;	showErrors();	if (cntxt->flags & timerFlag)		cntxt->timer = GDKusec();	mdbSessionActive= 0; /* for name completion */}@-It would come in handy if at any time you could activatethe debugger on a specific function. This calls for thecreation of a minimal execution environment first.@cstrrunMALDebugger(Symbol s){	Client c = MCgetClient();	c->itrace = 'n';	runMAL(c, s->def, 1, 0, 0, 0);	return MAL_SUCCEED;}@+ UtilitiesDumping a stack on a file is primarilly used for debugging.Printing the stack requires access to both the symbol table andthe stackframes in most cases.Beware that a stack frame need not be initialized with null values.It has been zeroed upon creation.The routine  can also be used to inspect the symbol table ofarbitrary functions.@cvoidprintStack(stream *f, MalBlkPtr mb, MalStkPtr s,int lifespan){	int i = 0;	if (s) {		stream_printf(f, "#Stack '%s' size=%d top=%d\n",				getInstrPtr(mb, 0)->fcnname, s->stksize, s->stktop);		for (; i < mb->vtop; i++)			printStackElm(f, mb, getVar(mb, i), s->stk + i, i, 0, 0,lifespan);	} else		for (; i < mb->vtop; i++)			printStackElm(f, mb, getVar(mb, i), 0, i, 0, 0,lifespan);}voidprintBATelm(stream *f, int i, size_t cnt, size_t first){	BAT *b, *bs;	str tpe ,nme;	b = BATdescriptor(i);	if (b) {		nme= BATgetId(b); 		tpe = getTypeName(newBatType(b->htype, b->ttype));		/* ignore ref count of this call */		stream_printf(f, "[%d] %s %s count=%d lrefs=%d refs=%d \n", 				i, nme, tpe, 				BATcount(b), BBP_lrefs(ABS(b->batCacheid)), 				BBP_refs(ABS(b->batCacheid)) - 1);		/* perform property checking */		if( b->H != b->T)			BATpropcheck(BATmirror(b),BATPROPS_QUICK);		BATpropcheck(b,BATPROPS_QUICK);		if( cnt){			if (cnt < BATcount(b)) {				stream_printf(f, "Sample %d out of %d\n", cnt, BATcount(b));			}			/* cut out a portion of the BAT for display */			bs = BATslice(b, first, first + cnt);			if (bs == NULL)				stream_printf(f, "Failed to take chunk\n");			else				BATmultiprintf(f, 2, &bs, TRUE, 0, TRUE);			BBPunfix(bs->batCacheid);		}		BBPunfix(b->batCacheid);		GDKfree(tpe);	}}voidprintStackElm(stream *f, MalBlkPtr mb, VarPtr n, ValPtr v, int index, size_t cnt, int first, int lifespan){	str nme, nmeOnStk;	char nmebuf[PATHLENGTH];	(void) mb;		/* fool the compiler */	if (n->tmpindex) {		snprintf(nmebuf, PATHLENGTH, "%c%d", TMPMARKER, n->tmpindex);		nme = nmebuf;	} else		nme = n->name;	if( lifespan) {		stream_printf(f, "#[%d,%d:%d,%d]  ", index, 			n->beginLifespan, n->endLifespan,n->lastUpdate);		if( isVarGarbage(mb,index) )			stream_printf(f,"G ");		stream_printf(f, " %s\t= ", nme);	} else stream_printf(f, "#[%d] %s\t= ", index, nme);	/* if (n->type == TYPE_void)		stream_printf(f, "nil");	else */ if (v)		ATOMprint(v->vtype, VALptr(v), f);	nme = getTypeName(n->type);	stream_printf(f, ":%s", nme);	if( lifespan && n->isudftype)		stream_printf(f," udftype");	nmeOnStk = v ? getTypeName(v->vtype) : GDKstrdup(nme);	if (strcmp(nmeOnStk, nme)) {		if (isaBatType(n->type)) {			BAT *b;			b = BATdescriptor(v->val.ival);			if (b) {				nmeOnStk = getTypeName(newBatType(b->htype, b->ttype));				if (strcmp(nme, nmeOnStk))					stream_printf(f, " != :%s", nmeOnStk);				BBPunfix(b->batCacheid);			}		} else if (!(isaBatType(n->type) && strcmp(nmeOnStk, "BAT") == 0))			stream_printf(f, " != %s", nmeOnStk);	}	stream_printf(f, " %s", (n->isaconstant ? " constant" : ""));	stream_printf(f, " %s", (n->isused==0 ? " not used" : ""));	stream_printf(f, " %s", (n->isatypevar ? " type variable" : ""));	GDKfree(nme);	GDKfree(nmeOnStk);	if (cnt && isaBatType(n->type) && v && v->val.ival) {		BAT *b, *bs;		b = BATdescriptor(v->val.ival);		if (b == NULL) {			stream_printf(f, "Could not access descriptor\n");			return;		}		stream_printf(f, "\n");		if (cnt <= BATcount(b)) {			stream_printf(f, "Sample %d out of %d\n", cnt, BATcount(b));		}		/* cut out a portion of the BAT for display */		bs = BATslice(b, first, first + cnt);		if (bs == NULL)			stream_printf(f, "Failed to take chunk\n");		else			BATmultiprintf(f, 2, &bs, TRUE, 0, TRUE);		BBPunfix(bs->batCacheid);		BBPunfix(b->batCacheid);	} else if (isaBatType(n->type) && v) {		BAT *b;		b = BATdescriptor(v->val.ival);		if (b) {			/* ignore ref count of this call */			stream_printf(f, " count=%d lrefs=%d refs=%d", 				BATcount(b), BBP_lrefs(ABS(b->batCacheid)), 				BBP_refs(ABS(b->batCacheid)) - 1);			BBPunfix(b->batCacheid);		}	} 	if( n->props){		nme= propertySet2str(n->props);		stream_printf(f,"%s",nme);		GDKfree(nme);	}	stream_printf(f, "\n");}voidprintBatInfo(stream *f, VarPtr n, ValPtr v){	if (isaBatType(n->type) && v->val.ival) {		int bid;		int ret;		MALfcn fcn;		fcn = getAddress("bat","bat","BKCinfo", 0);		if (fcn) {			BAT *b;			bid = v->val.ival;			stream_printf(f, "Show info for %d\n", bid);			(*fcn) (&ret, &bid);			b = BATdescriptor(ret);			if (b == NULL) {				stream_printf(f, "Could not access descriptor\n");				return;			}			BATmultiprintf(f, 2, &b, TRUE, 0, TRUE);			BBPunfix(b->batCacheid);		}	}}voidprintBatProperties(stream *f, VarPtr n, ValPtr v, str props){	if (isaBatType(n->type) && v->val.ival) {		int bid;		int ret;		MALfcn fcn;		BUN p;		fcn = getAddress("bat","bat","BKCinfo", 0);		if (fcn) {			BAT *b;			bid = v->val.ival;			stream_printf(f, "BAT %d %s= ", bid,props);			(*fcn) (&ret, &bid);			b = BATdescriptor(ret);			if (b == NULL) {				stream_printf(f, "Could not access descriptor\n");				return;			}			p= BUNfnd(b,props);			if( p) {				stream_printf(f," %s\n", (str) BUNtail(b,p));			} else stream_printf(f," not found\n");			BBPunfix(b->batCacheid);		}	}}@-The memory positions for the BATs is useful information toasses for memory fragmentation.@= heapinfohp= b->@1;if(hp && hp->base){	stream_printf(GDKout,"\t@1=%d size=%d\n",hp->base, hp->size);}@= hashinfoh= b->@1;if(h && h->mask){	    stream_printf(GDKout,"\t@1=%d size=%d\n",h, sizeof(*h));	    stream_printf(GDKout,"\t@1link=%d size=%d\n",h->link,	            (h->mask+h->lim+1)*sizeof(int));}@-The memProfileVector routine produces a character string to representthe usage of memory by BAT information. The characters are interpretedas follows:.=unused, X=completely used, [0-9]=small elements within the granuleMore then 9 elements makes it full.@= setVector	start= (((long)@1)-min)/granule;	lim= (((long)@1)-min + @2)/granule;	stream_printf(GDKout,"start %d lim %d\n",start,lim);@cstrmemProfileVector(int cells){	str v = GDKmalloc(cells + 1);	int i;#ifdef HAVE_SBRK	long max = (long) sbrk(0);	long min = 0;	long granule = 0;#endif	if (cells <= 0) {		showException(MAL,"memProfileVector", "positive argument expected");		return GDKstrdup("");	}	v = GDKmalloc(cells + 1);	if (v == 0)		GDKfatal("memProfileVector:malloc failure\n");	for (i = 0; i < cells; i++)		v[i] = '.';	v[i] = 0;	for (i = 1; i < BBPsize; i++)		if (BBP_status(i) & BBPLOADED) {			BAT *b = BATdescriptor(i);			Heap *hp;			Hash *h;#ifdef HAVE_SBRK			long start, lim;#endif			stream_printf(GDKout, "\tdesc=%d size=%d\n", b, sizeof(*b));			hp = b->batBuns;			stream_printf(GDKout, "\tbuns=%d size=%d\n", hp->base, hp->size);#ifdef HAVE_SBRK			if (min == 0) {				min = (long) b;				max = min + GDKmem_heapsize();				granule = (max - min) / cells;				stream_printf(GDKout, "granule %dK\n", granule / 1024);			}			@:setVector(b, sizeof(*b))@			@:setVector(hp->base, hp->size)@#endif			@:heapinfo(hheap)@			@:heapinfo(theap)@			@:hashinfo(hhash)@			@:hashinfo(thash)@			BBPunfix(b->batCacheid);		}	return v;}voidprintBBPinfo(stream *out){	str v;	stream_printf(out, "#BBP memory layout\n");	stream_printf(out, "#heap maximum =%d/M\n", GDKmem_heapsize() / (1024 * 1024));	v = memProfileVector(32);	stream_printf(out, "#%s\n", v);	GDKfree(v);#ifdef GDK_VM_KEEPHISTO	stream_printf(out, "#BBP VM history available\n");#else	stream_printf(out, "#BBP VM history not available\n");#endif}@-Some utilities for the debugger@cvoidmdbHelp(stream *f){	stream_printf(f, "next             -- Advance to next statement\n");	stream_printf(f, "continue         -- Continue program being debugged\n");	stream_printf(f, "catch            -- Catch the next exception \n");	stream_printf(f, "break [<var>]    -- set breakpoint on current instruction or <var>\n");	stream_printf(f, "delete [<var>]   -- remove break/trace point <var>\n");	stream_printf(f, "debug <int>      -- set kernel debugging mask\n");	stream_printf(f, "dot [<int>] [<file>]  -- generate the dependency graph\n");	stream_printf(f, "step             -- advance to next MAL instruction\n");	stream_printf(f, "module           -- display a module signatures\n");	stream_printf(f, "atom             -- show atom list\n");	stream_printf(f, "finish           -- finish current call\n");	stream_printf(f, "exit             -- terminate executionr\n");	stream_printf(f, "quit             -- turn off debugging\n");	stream_printf(f, "list <obj>       -- list current program block\n");	stream_printf(f, "List <obj>       -- list with type information\n");	stream_printf(f, "var  <obj>       -- print symbol table for module\n");	stream_printf(f, "optimizer <obj>  -- display program after optimizer step\n");	stream_printf(f, "print <var>      -- display value of a variable\n");	stream_printf(f, "print <var> <cnt>[<first>] -- display BAT chunk\n");	stream_printf(f, "info <var>       -- display bat variable properties\n");	stream_printf(f, "run              -- restart current procedure\n");	stream_printf(f, "where            -- print stack trace\n");	stream_printf(f, "down             -- go down the stack\n");	stream_printf(f, "up               -- go up the stack\n");	stream_printf(f, "trace <var>      -- trace assignment to variables\n");	stream_printf(f, "set {timer,flow,io,memory} -- set trace switches\n");	stream_printf(f, "unset            -- turn off switches\n");	stream_printf(f, "help             -- this message\n");}@+ Optimizer debuggingThe modular approach to optimize a MAL program brings with it theneed to check individual steps. Two options come to mind. If indebug mode we could stop after each optimizer action for inspection.Alternatively, we keep a history of all MAL program versions foraposteriori analysis.The latter is implemented first.A global stack is used for simplity, later we may have tomake it thread safe by assigning it to a client record.@cint isInvariant(MalBlkPtr mb, int pcf, int pcl, int varid);strdebugOptimizers(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci){	Client cntxt = MCgetClient();	(void) stk;	cntxt->debugOptimizer = cntxt->debugOptimizer ? FALSE : TRUE;	if (pci)		removeInstruction(mb, pci);	return MAL_SUCCEED;}@}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -