Пример #1
0
/* Print status when ^\ pressed */
static void sigquit_handler(int signum, siginfo_t *info, void *uc) {

	int i;

	for(i=0;i<NUM_EVENTS;i++) {
		if (event_data[i].active) {
			perf_pretty_print_event(stdout,
				event_data[i].fd,
				getpid(),
				&event_data[i].attr,
				event_data[i].pid,
				event_data[i].cpu,
				event_data[i].group_fd,
				event_data[i].flags
				);
		}
	}

}
Пример #2
0
static void open_event(char *line) {


	struct perf_event_attr *pe;
	int fd,orig_fd,remapped_group_fd;
	pid_t pid;
	int cpu,group_fd,orig_size;
	long int flags;

	unsigned char zeros[4096];

	/* urgh, necessary.  Took forever to track this down  */
	/* data from the poll structure was leaking in if not */
	/* entirely zero, and also getting E2BIG errors if we */
	/* set the size to a "too big" value and there were   */
	/* non-zero values in that space.                     */
	/* The max size of a struct is the pagesize, so make  */
	/* all events live in a sea of zeros to avoid problems*/

	memset(&zeros,0,4096);
	pe=(struct perf_event_attr *)&zeros;

	/* I hate bitfields */
	int disabled,inherit,pinned,exclusive;
	int exclude_user,exclude_kernel,exclude_hv,exclude_idle;
	int mmap,comm,freq,inherit_stat;
	int enable_on_exec,task,watermark,precise_ip;
	int mmap_data,sample_id_all,exclude_host,exclude_guest;
	int exclude_callchain_user,exclude_callchain_kernel;
	int mmap2,comm_exec;
	sscanf(line,
		"%*c %d %d %d %d %lx "
		"%x %x "
		"%llx %llx %llx %llx "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d "
		"%llx %llx %lld "
		"%d %d %lld %d %d %d",
		&orig_fd,&pid,&cpu,&group_fd,&flags,
		&pe->type,&pe->size,
		&pe->config,&pe->sample_period,&pe->sample_type,&pe->read_format,
		&disabled,&inherit,&pinned,&exclusive,
		&exclude_user,&exclude_kernel,&exclude_hv,&exclude_idle,
		&mmap,&comm,&freq,&inherit_stat,
		&enable_on_exec,&task,&watermark,&precise_ip,
		&mmap_data,&sample_id_all,&exclude_host,&exclude_guest,
		&pe->wakeup_events,&pe->bp_type,
		&pe->config1,&pe->config2,&pe->branch_sample_type,
		&exclude_callchain_kernel,&exclude_callchain_user,
		&pe->sample_regs_user,&pe->sample_stack_user,&mmap2,&comm_exec);

	errno=0;

	/* use recorded value for pid not our actual pid */
	if (pid==original_pid) {
		pid=getpid();
	}

	/* re-populate bitfields */
	/* can't sscanf into them */
	pe->disabled=disabled;
	pe->inherit=inherit;
	pe->pinned=pinned;
	pe->exclusive=exclusive;
	pe->exclude_user=exclude_user;
	pe->exclude_kernel=exclude_kernel;
	pe->exclude_hv=exclude_hv;
	pe->exclude_idle=exclude_idle;
	pe->mmap=mmap;
	pe->comm=comm;
	pe->freq=freq;
	pe->inherit_stat=inherit_stat;
	pe->enable_on_exec=enable_on_exec;
	pe->task=task;
	pe->watermark=watermark;
	pe->precise_ip=precise_ip;
	pe->mmap_data=mmap_data;
	pe->sample_id_all=sample_id_all;
	pe->exclude_host=exclude_host;
	pe->exclude_guest=exclude_guest;
	pe->exclude_callchain_user=exclude_callchain_user;
	pe->exclude_callchain_kernel=exclude_callchain_kernel;
	pe->mmap2=mmap2;
	pe->comm_exec=comm_exec;

	/* kernel over-writes this sometimes :( */
	orig_size=pe->size;

	if (group_fd==-1) {
		remapped_group_fd=-1;
	} else {
		remapped_group_fd=fd_remap[group_fd];
	}


	fd=perf_event_open(pe,pid,cpu,remapped_group_fd,flags);
	if (fd<0) {

		fprintf(stderr,"Line %lld Error opening %s : %s\n",
			line_num,line,strerror(errno));

                perf_pretty_print_event(stderr,orig_fd,original_pid,
				pe, pid, cpu,
				remapped_group_fd,flags);

		if (errno==E2BIG) {
			printf("Too big!  Kernel returns %d we were %d\n",
				pe->size,orig_size);
		}
#if 0
	{
		int i;
		char *blah;

		blah=(char *)&pe;

		printf("BEFORE\n");
		for(i=0;i<100;i++) {
			printf("%d:%2x ",i,blah[i]);
		}
		printf("AFTER\n");
	}
#endif

		error=1;
		return;
	}

	if (orig_fd>FD_REMAP_SIZE) {
		fprintf(stderr,"fd out of range\n");
		error=1;
		return;
	}

	fd_remap[orig_fd]=fd;

	if (fd>FD_REMAP_SIZE) {
		fprintf(stderr,"overflow fd out of range\n");
		error=1;
		return;
	}
	fd_overflows[fd]=0;
	fd_throttles[fd]=0;
}
Пример #3
0
static void open_event(char *line) {

	struct perf_event_attr pe;
	int orig_fd;
	pid_t pid;
	int cpu,group_fd;
	long int flags;

	/* I hate bitfields */
	int disabled,inherit,pinned,exclusive;
	int exclude_user,exclude_kernel,exclude_hv,exclude_idle;
	int mmap,comm,freq,inherit_stat;
	int enable_on_exec,task,watermark,precise_ip;
	int mmap_data,sample_id_all,exclude_host,exclude_guest;
	int exclude_callchain_kernel,exclude_callchain_user;
	int mmap2;

	sscanf(line,
		"%*c %d %d %d %d %lx "
		"%x %x "
		"%llx %llx %llx %llx "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d %d %d "
		"%d %d "
		"%llx %llx %lld "
		"%d %d %lld %d %d ",
		&orig_fd,&pid,&cpu,&group_fd,&flags,
		&pe.type,&pe.size,
		&pe.config,&pe.sample_period,&pe.sample_type,&pe.read_format,
		&disabled,&inherit,&pinned,&exclusive,
		&exclude_user,&exclude_kernel,&exclude_hv,&exclude_idle,
		&mmap,&comm,&freq,&inherit_stat,
		&enable_on_exec,&task,&watermark,&precise_ip,
		&mmap_data,&sample_id_all,&exclude_host,&exclude_guest,
		&pe.wakeup_events,&pe.bp_type,
		&pe.config1,&pe.config2,&pe.branch_sample_type,
		&exclude_callchain_kernel,&exclude_callchain_user,
		&pe.sample_regs_user,&pe.sample_stack_user,&mmap2);

	/* re-populate bitfields */
	/* can't sscanf into them */
	pe.disabled=disabled;
	pe.inherit=inherit;
	pe.pinned=pinned;
	pe.exclusive=exclusive;
	pe.exclude_user=exclude_user;
	pe.exclude_kernel=exclude_kernel;
	pe.exclude_hv=exclude_hv;
	pe.exclude_idle=exclude_idle;
	pe.mmap=mmap;
	pe.comm=comm;
	pe.freq=freq;
	pe.inherit_stat=inherit_stat;
	pe.enable_on_exec=enable_on_exec;
	pe.task=task;
	pe.watermark=watermark;
	pe.precise_ip=precise_ip;
	pe.mmap_data=mmap_data;
	pe.sample_id_all=sample_id_all;
	pe.exclude_host=exclude_host;
	pe.exclude_guest=exclude_guest;
	pe.exclude_callchain_user=exclude_callchain_user;
	pe.exclude_callchain_kernel=exclude_callchain_kernel;
	pe.mmap2=mmap2;

	perf_pretty_print_event(stdout,orig_fd,original_pid,
				&pe,pid,cpu,group_fd,flags);

	printf("\n");

}
Пример #4
0
int main(int argc, char **argv) {

	FILE *logfile;
	char *logfile_name=NULL;
	char line[BUFSIZ];
	char *result;
	long long total_syscalls=0,replay_syscalls=0;
	long long skip_lines=0;

	int i;

	int replay_which=REPLAY_ALL;

	if (argc<2) {
		print_usage(argv[0]);
		exit(1);
	}

	i=1;
	while(1) {
		if (i>=argc) break;

		if (argv[i][0]=='-') {
			switch(argv[i][1]) {
			case 'h':	print_usage(argv[0]);
					exit(1);
					break;
			default:	fprintf(stderr,"Unknown option -%c\n",argv[i][1]);
					exit(1);
					break;
			}
		}
		else {
			logfile_name=strdup(argv[i]);
			i++;
		}
	}

	if (logfile_name==NULL) {
		fprintf(stderr,"Must specify logfile name\n");
		exit(1);
	}

	logfile=fopen(logfile_name,"r");
	if (logfile==NULL) {
		fprintf(stderr,"Error opening %s\n",logfile_name);
		exit(1);
	}

	/* Init structs */
	for(i=0;i<MAX_EVENTS;i++) {
		event_info[i].opened=0;
		event_info[i].enabled=0;
		mmap_info[i].valid=0;
	}

	/* Main loop */

	while(1) {
		result=fgets(line,BUFSIZ,logfile);
		if (result==NULL) break;

		line_num++;

		if (line_num<skip_lines) continue;

		switch(line[0]) {
			case 'C':
				if (replay_which & REPLAY_CLOSE) {
					close_event(line);
					replay_syscalls++;
				}
				break;
			case 'F':
				if (replay_which & REPLAY_FORK) {
					fork_event(line);
					replay_syscalls++;
				}
				break;
			case 'G':
				sscanf(line,"%*c %d",&original_pid);
				printf("Original pid was %d\n",original_pid);
				break;
			case 'I':
				if (replay_which & REPLAY_IOCTL) {
					ioctl_event(line);
					replay_syscalls++;
				}
				break;
			case 'M':
				if (replay_which & REPLAY_MMAP) {
					mmap_event(line);
					replay_syscalls++;
				}
				break;
			case 'O':
				if (replay_which & REPLAY_OPEN) {
					open_event(line);
					replay_syscalls++;
				}
				break;
			case 'o':
				if (replay_which & REPLAY_OVERFLOW) {
					setup_overflow(line);
					replay_syscalls++;
				}
				break;
			case 'P':
				if (replay_which & REPLAY_PRCTL) {
					prctl_event(line);
					replay_syscalls++;
				}
				break;
			case 'p':
				if (replay_which & REPLAY_POLL) {
					poll_event(line);
					replay_syscalls++;
				}
				break;
			case 'Q':
				if (replay_which & REPLAY_TRASH_MMAP) {
					trash_mmap_event(line);
					replay_syscalls++;
				}
				break;
			case 'q':
				fprintf(stderr,"Quitting early\n");
				exit(1);
			case 'R':
				if (replay_which & REPLAY_READ) {
					read_event(line);
					replay_syscalls++;
				}
				break;
			case 'S':
				if (replay_which & REPLAY_SEED) {
					/* don't need to do anything */
					/* as we don't use rand      */
				}
				break;
			case 'U':
				if (replay_which & REPLAY_MUNMAP) {
					munmap_event(line);
					replay_syscalls++;
				}
				break;
			default:
				fprintf(stderr,"Line %lld Unknown log type \'%c\'\n",
					line_num,line[0]);
				break;
		}
		//if (error) break;
		total_syscalls++;
		if (total_syscalls%1000==0) {
			printf("%lld\n",total_syscalls);
		}
	}

	printf("ACTIVE EVENT REPORT\n");
	printf("~~~~~~~~~~~~~~~~~~~\n");
	printf("\tReplayed %lld of %lld syscalls\n",
		replay_syscalls,total_syscalls);

	int total_active=0,total_opened=0;

	for(i=0;i<MAX_EVENTS;i++) {
		if (event_info[i].opened) total_opened++;
		if (event_info[i].enabled) total_active++;
	}
	printf("\t%d events open, %d events active\n",
		total_opened,total_active);

	printf("ENABLED EVENTS\n\n");
	for(i=0;i<MAX_EVENTS;i++) {
		if (event_info[i].enabled) {
			perf_pretty_print_event(stdout,
				i,original_pid,
				&event_info[i].attr,
				event_info[i].pid,
				event_info[i].cpu,
				event_info[i].group_fd,
				event_info[i].flags);
			printf("\n\n");
		}
	}

	printf("SHORT EVENT SUMMARY\n\n");
	for(i=0;i<MAX_EVENTS;i++) {
		if (event_info[i].enabled) {
			perf_pretty_print_event_short(stdout,
				i,original_pid,
				&event_info[i].attr,
				event_info[i].pid,
				event_info[i].cpu,
				event_info[i].group_fd,
				event_info[i].flags);
		}
	}
	return 0;

}