Beispiel #1
0
static int idbg_setstackitem( SGS_CTX )
{
	sgs_Bool full = 0;
	sgs_Int off, cnt;
	sgs_Variable* a, *b, *x, tmp;
	SGS_IDBG = (sgs_IDbg*) C->msg_ctx;
	
	SGSFN( "dbg_setstackitem" );
	if( !sgs_LoadArgs( C, "i?v|b", &off, &full ) )
		return 0;
	
	a = full ? C->stack_base : C->stack_base + D->stkoff;
	b = C->stack_base + D->stksize;
	cnt = b - a;
	if( off >= cnt || -off > cnt )
	{
		sgs_Msg( C, SGS_WARNING,
			"index %d out of bounds, count = %d\n", (int) off, (int) cnt );
		return 0;
	}
	
	x = off >= 0 ? a + off : b + off;
	tmp = *x;
	sgs_Acquire( C, &tmp );
	sgs_GetStackItem( C, 1, x );
	sgs_Release( C, &tmp );
	return 0;
}
Beispiel #2
0
static void mode3hook( void* userdata, SGS_CTX, int evid )
{
	sgs_ProfData* P = (sgs_ProfData*) userdata;
	if( P->hfn )
		P->hfn( P->hctx, C, evid );
	
	if( evid == SGS_HOOK_ENTER || evid == SGS_HOOK_CONT ||
		evid == SGS_HOOK_EXIT || evid == SGS_HOOK_PAUSE )
	{
		SGS_SHCTX_USE;
		mode3item CD = { NULL, S->numallocs, S->numfrees, S->numblocks, (double) S->memsize };
		
		sgs_StackFrame* target = NULL, *sf, *lastrec = NULL;
		mode3item* items = SGS_ASSUME_ALIGNED( P->frametmp.ptr, mode3item );
		size_t i, itemcount = P->frametmp.size / sizeof(mode3item);
		
		if( evid == SGS_HOOK_ENTER || evid == SGS_HOOK_CONT )
			target = C->sf_last;
		else if( evid == SGS_HOOK_EXIT )
			target = C->sf_last->prev;
		/* pause => null */
		
		/* ignore the case when target = current */
		if( itemcount && items[ itemcount - 1 ].frame == target )
			return;
		
		/* find target in stack */
		for( i = 0; i < itemcount; ++i )
		{
			if( items[ i ].frame == target )
				break;
		}
		if( i == itemcount )
		{
			/* find last recorded frame in call stack */
			sf = NULL;
			if( itemcount )
			{
				sf = C->sf_first;
				while( sf )
				{
					if( items[ itemcount - 1 ].frame == sf )
						break;
					sf = sf->next;
				}
			}
			lastrec = sf;
			if( sf == NULL || target == NULL )
				i = 0; /* frame not found/req., remove everything */
			/* otherwise, remove nothing, it's an "ENTER" */
		}
		else
			i++; /* remove starting from next frame */
		
		/* if there is anything to remove */
		if( i < itemcount )
		{
			size_t bki = i;
			sf = C->sf_first;
			/* generate core key (from start to first removed incl.) */
			sgs_membuf_resize( &P->keytmp, C, 0 );
			while( sf && sf != items[ i ].frame )
			{
				const char* fname = "<error>";
				sgs_StackFrameInfo( C, sf, &fname, NULL, NULL );
				sgs_membuf_appbuf( &P->keytmp, C, fname, strlen( fname ) );
				sgs_membuf_appchr( &P->keytmp, C, 0 );
				sf = sf->next;
			}
			
			/* iterate removable frames (assuming frame pointers are valid) */
			for( ; i < itemcount; ++i )
			{
				const char* fname = "<error>";
				sgs_StackFrameInfo( C, items[ i ].frame, &fname, NULL, NULL );
				sgs_membuf_appbuf( &P->keytmp, C, fname, strlen( fname ) );
				sgs_membuf_appchr( &P->keytmp, C, 0 );
				
				/* commit memory addition */
				{
					mode3item prevCD = items[ i ], *PD;
					sgs_VHTVar* pair = sgs_vht_get_str( &P->prof->timings, P->keytmp.ptr,
						(uint32_t) P->keytmp.size, sgs_HashFunc( P->keytmp.ptr, P->keytmp.size ) );
					if( pair )
					{
						PD = (mode3item*) pair->val.data.P;
					}
					else
					{
						sgs_Variable key, val;
						val.type = SGS_VT_PTR;
						val.data.P = PD = sgs_Alloc( mode3item );
						memset( PD, 0, sizeof(*PD) );
						sgs_InitStringBuf( C, &key, P->keytmp.ptr, (sgs_SizeVal) P->keytmp.size );
						sgs_vht_set( &P->prof->timings, C, &key, &val );
						sgs_Release( C, &key );
					}
					
					PD->numallocs += CD.numallocs - prevCD.numallocs;
					PD->numfrees += CD.numfrees - prevCD.numfrees;
					PD->numblocks += CD.numblocks - prevCD.numblocks;
					PD->szdelta += CD.szdelta - prevCD.szdelta;
				}
			}
			
			/* commit size */
			sgs_membuf_resize( &P->frametmp, C, bki * sizeof(mode3item) );
			itemcount = bki;
		}
		
		/* add new frame start times */
		if( lastrec || ( target != NULL && itemcount == 0 ) )
		{
			if( lastrec )
				sf = lastrec->next;
			else
				sf = C->sf_first;
			while( sf )
			{
				mode3item NI = CD;
				NI.frame = sf;
				sgs_membuf_appbuf( &P->frametmp, C, &NI, sizeof(NI) );
				if( sf == target )
					break;
				sf = sf->next;
			}
		}
	}
	else if( evid == SGS_HOOK_CREAT )
	{
		sgs_ProfAttach( C, P->prof );
	}
	else if( evid == SGS_HOOK_CFREE )
	{
		sgs_ProfDetach( C, P->prof );
	}
	/* CFORK not supported yet */
}