Пример #1
0
/* given a task (preferably stopped), sample all the threads in it */
static void
pet_sample_task( task_t task )
{
	mach_msg_type_number_t threadc;
	thread_array_t threadv;
	kern_return_t kr;

	kr = chudxnu_task_threads(task, &threadv, &threadc);
	if( kr != KERN_SUCCESS )
	{
		BUF_INFO2(PERF_PET_ERROR, ERR_THREAD, kr);
		return;
	}

	pet_sample_thread_list( threadc, threadv );

	chudxnu_free_thread_list(&threadv, &threadc);
}
Пример #2
0
static void
pet_sample_all_tasks(void)
{
	task_array_t taskv = NULL;
	mach_msg_type_number_t taskc = 0;
	kern_return_t kr;

	kr = chudxnu_all_tasks(&taskv, &taskc);

	if( kr != KERN_SUCCESS )
	{
		BUF_INFO2(PERF_PET_ERROR, ERR_TASK, kr);
		return;
	}

	pet_sample_task_list( taskc, taskv );
	chudxnu_free_task_list(&taskv, &taskc);
}
Пример #3
0
static void
pet_sample_pid_filter(void)
{
	task_t *taskv = NULL;
	int *pidv, pidc, i;
	vm_size_t asize;

	kperf_filter_pid_list( &pidc, &pidv );
	if( pidc == 0  )
	{
		BUF_INFO2(PERF_PET_ERROR, ERR_PID, 0);
		return;
	}

	asize = pidc * sizeof(task_t);
	taskv = kalloc( asize );

	if( taskv == NULL )
		goto out;

	/* convert the pid list into a task list */
	for( i = 0; i < pidc; i++ )
	{
		int pid = pidv[i];
		if( pid == -1 )
			taskv[i] = NULL;
		else
			taskv[i] = chudxnu_task_for_pid(pid);
	}

	/* now sample the task list */
	pet_sample_task_list( pidc, taskv );

	kfree(taskv, asize);

out:
	kperf_filter_free_pid_list( &pidc, &pidv );
}
Пример #4
0
static void
callstack_sample( struct callstack *cs, 
                  struct kperf_context *context,
                  uint32_t is_user )
{
	kern_return_t kr;
	mach_msg_type_number_t nframes; /* WTF with the type? */
	uint32_t code;

	if( is_user )
		code = PERF_CS_USAMPLE;
	else
		code = PERF_CS_KSAMPLE;

	BUF_INFO1( code, (uintptr_t)thread_tid(context->cur_thread) );

	/* fill out known flags */
	cs->flags = 0;
	if( !is_user )
	{
		cs->flags |= CALLSTACK_KERNEL;
#ifdef __LP64__
		cs->flags |= CALLSTACK_64BIT;
#endif
	}
	else
	{
		/* FIXME: detect 32 vs 64-bit? */
	}

	/* collect the callstack */
	nframes = MAX_CALLSTACK_FRAMES;
	kr = chudxnu_thread_get_callstack64_kperf( context->cur_thread, 
						   cs->frames, 
						   &nframes,
						   is_user );

	/* check for overflow */
	if( kr == KERN_SUCCESS )
	{
		cs->flags |= CALLSTACK_VALID;
		cs->nframes = nframes;
	}
	else if( kr == KERN_RESOURCE_SHORTAGE )
	{
		/* FIXME: more here */
		cs->flags |= CALLSTACK_TRUNCATED;
		cs->flags |= CALLSTACK_VALID;
		cs->nframes = nframes;
	}
	else
	{
		BUF_INFO2(PERF_CS_ERROR, ERR_GETSTACK, kr);
		cs->nframes = 0;
	}

	if( cs->nframes > MAX_CALLSTACK_FRAMES )
	{
		/* necessary? */
		BUF_INFO1(PERF_CS_ERROR, ERR_FRAMES);
		cs->nframes = 0;
	}

}