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

📄 ctrace.c

📁 linux下的多线程调试c++代码,适合多线程linux下程序的调试
💻 C
📖 第 1 页 / 共 2 页
字号:
	return ret;}/* ----------------------------------------------------------------------   int			// 0=false, 1=true   trc_valid_level(	// function name   tlevel_t tlevel)	// trace level(s)    desc: validate tlevel    --------------------------------------------------------------------*/int trc_valid_level(tlevel_t tlevel){	return ((tlevel & ~(TRC_ALL)) == 0) ;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_set_level(	// function name   tlevel_t tlevel)	// trace level(s)   desc: set level=<level> in all added threads    --------------------------------------------------------------------*/int trc_set_level(tlevel_t level){	uint_t i;	tthread_t *t = NULL;	if(!trc_valid_level(level))		return 1;	HASH_WRITE_ENTER();	_tlevel = level;	for(i=0; i<THRDMAX; i++)		for(t=_thread[i]; _thread[i] && t!=NULL; t=t->next)			t->level = level;	HASH_WRITE_EXIT();	return 0;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_add_level(	// function name   tlevel_t tlevel)	// trace level(s)   desc: add <level> to all added threads    --------------------------------------------------------------------*/int trc_add_level(tlevel_t level){	uint_t i;	tthread_t *t = NULL;	if(!trc_valid_level(level)) return 1;	HASH_WRITE_ENTER();	_tlevel |= level;	for(i=0; i<THRDMAX; i++)		for(t=_thread[i]; _thread[i] && t!=NULL; t=t->next)			t->level |= level;	HASH_WRITE_EXIT();	return 0;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_remove_level(	// function name   tlevel_t tlevel)	// trace level(s)   desc: remove <level> in all added threads    --------------------------------------------------------------------*/int trc_remove_level(tlevel_t level){	uint_t i;	tthread_t *t = NULL;	if(!trc_valid_level(level)) return 1;	HASH_WRITE_ENTER();	_tlevel &= ~level;	for(i=0; i<THRDMAX; i++)		for(t=_thread[i]; _thread[i] && t!=NULL; t=t->next)			t->level &= ~level;	HASH_WRITE_EXIT();	return 0;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_set_thread_level(	// function name   tlevel_t tlevel	// trace level(s)   tid_t id)		// thread id   desc: set level=<level> in thread <id>   --------------------------------------------------------------------*/int trc_set_thread_level(tlevel_t level, tid_t id){	int ret = 1;	tthread_t *t = NULL;	if(id == 0)		id = pthread_self();	HASH_WRITE_ENTER();	if((t = trc_thread(id)) && trc_valid_level(level)){		t->level = level;		ret = 0;	}	HASH_WRITE_EXIT();	return ret;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_add_thread_level(	// function name   tlevel_t tlevel	// trace level(s)   tid_t id)		// thread id   desc: add <level> to thread <id>   --------------------------------------------------------------------*/int trc_add_thread_level(tlevel_t level, tid_t id){	int ret = 1;	tthread_t *t = NULL;	if(id == 0)		id = pthread_self();	HASH_WRITE_ENTER();	if((t = trc_thread(id)) && trc_valid_level(level)){		t->level |= level;		ret = 0;	}	HASH_WRITE_EXIT();	return ret;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_remove_thread_level(	// function name   tlevel_t tlevel	// trace level(s)   tid_t id)		// thread id   desc: remove <level> from thread <id>   --------------------------------------------------------------------*/int trc_remove_thread_level(tlevel_t level, tid_t id){	int ret = 1;	tthread_t *t = NULL;	if(id == 0)		id = pthread_self();	HASH_WRITE_ENTER();	if((t = trc_thread(id)) && trc_valid_level(level)){		t->level &= ~level;		ret = 0;	}	HASH_WRITE_EXIT();	return ret;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_set_unit_level(	// function name   tunit_t *tl		// trace level(s)   tlevel_t level)	// tlevel_t    desc: set level=<level> in tunit_t <tl>   --------------------------------------------------------------------*/int trc_set_unit_level(uint_t i, tlevel_t level){	int ret = 1;	if(_unitmax == 0 || i<0 || i>=_unitmax)		return ret;	/* this wont happen often so just reuse hash table locks */	HASH_WRITE_ENTER();	if(i < UNITMAX && trc_valid_level(level)){		_unit[i].level = level;		ret = 0;	}	HASH_WRITE_EXIT();	return ret;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_add_unit_level(	// function name   tunit_t *tl		// trace level(s)   tlevel_t level)	// tlevel_t    desc: add level=<level> in tunit_t <tl>   --------------------------------------------------------------------*/int trc_add_unit_level(uint_t i, tlevel_t level){	int ret = 1;	if(_unitmax == 0 || i<0 || i>=_unitmax)		return ret;	/* this wont happen often so just reuse hash table locks */	HASH_WRITE_ENTER();	if(i < UNITMAX  && trc_valid_level(level)){		_unit[i].level |= level;		ret = 0;	}	HASH_WRITE_EXIT();	return ret;}/* ----------------------------------------------------------------------   int			// 0=success, 1=failure   trc_remove_unit_level(// function name   tunit_t *tl		// trace level(s)   tlevel_t level)	// tlevel_t    desc: remove level=<level> from tunit_t <tl>   --------------------------------------------------------------------*/int trc_remove_unit_level(uint_t i, tlevel_t level){	int ret = 1;	if(_unitmax == 0 || i<0 || i>=_unitmax)		return ret;	/* this wont happen often so just reuse hash table locks */	HASH_WRITE_ENTER();	if(i < UNITMAX && trc_valid_level(level)){		_unit[i].level &= ~level;		ret = 0;	}	HASH_WRITE_EXIT();	return ret;}/* ----------------------------------------------------------------------   void			// procedure    trc_state()		// procedure name   desc: print trace state info for debugging purposes.   --------------------------------------------------------------------*/void trc_state(){	printf("_trc: %d\t_level: %d\t_t: %d\t", _trc, _tlevel, _server);	if(_fp == _STDOUT)		printf("_fp: _STDOUT");	else if(_fp)		printf("_fp: user file");	else		printf("_fp: NULL");	printf("\n");}/* ----------------------------------------------------------------------   char *		// string output of fmt/argslist combination    trc_varargs(		// function name   const char *fmt,	// format   ...)			// arguments embedded in <format>   desc: convert fmt/arglist combination into string    --------------------------------------------------------------------*/char *trc_varargs(const char *fmt, ...){	va_list args;	tthread_t *t = NULL;	HASH_READ_ENTER();	if(t = trc_thread(pthread_self())){		if(fmt){			va_start(args, fmt);			vsprintf(t->fmt, fmt, args);			va_end(args);		}		else			t->fmt[0] = NULL;	}	HASH_READ_EXIT();	return t? t->fmt: NULL;}/* ----------------------------------------------------------------------   void			// procedure    trc_trace(		// procedure name   taction_t a,		// action   tlevel_t level,	// trace level   cchar_t *file, 	// source file    uint_t line,		// source file line number    cchar_t *kword,	// keyword for trace info   cchar_t *s)		// trace info   desc: write trace line    --------------------------------------------------------------------*/void trc_trace(taction_t a, uint_t i, tlevel_t level, cchar_t *file, uint_t line, cchar_t *fn, cchar_t *kword, cchar_t *s){	int n;			/* length of non-indented fields */	tthread_t *t;	int num, bytesWritten;	int unit, thread;	time_t tim;	struct tm *timeptr;	char buf[64];	HASH_READ_ENTER();		/* check for valid output stream and this thread is registered */	if(!_fp || !(t = trc_thread(pthread_self()))){		HASH_READ_EXIT();		return;	}	/* if unit or thread is on and has level set, do trace */	unit = _unitmax>0 && i>=0 && i<_unitmax && _unit[i].on && ((_unit[i].level & level)!=0); 	thread = t->on && ((t->level & level)!=0);	if(!unit && !thread){		HASH_READ_EXIT();		return;	}	time(&tim);	timeptr = localtime(&tim);	strftime(buf, 64, "%D-%T", timeptr);	/* generate trace output */	sprintf(t->trace, "%s:%s:%d:%s:%n", buf, file, line, t->name, &n);	t->wspace[WSPACELEN(n)] = '\0';		switch(a){	case(TRCA_ENTER):		sprintf(t->trace+n, "%senter %s(%s)\n", t->wspace, fn, s);		break;	case(TRCA_RETURN):		sprintf(t->trace+n, "%sreturn %s(%s)\n", t->wspace, fn, s);			break;	case(TRCA_VOID_RETURN):		sprintf(t->trace+n, "%s%s: return\n", t->wspace, fn);			break;	case(TRCA_PRINT):		sprintf(t->trace+n, "%s%s\n", t->wspace, s);			break;	case(TRCA_ERROR):		sprintf(t->trace+n, "%sERROR in fn %s: %s\n", t->wspace, fn, s);			break;	}		t->wspace[WSPACELEN(n)] = ' ';		/* write trace output to _fd */	if(_server){			num = 0;		for(bytesWritten=0; bytesWritten<TRACELEN; bytesWritten+=num)			num = write(_serv_sockfd, 				(void*)((char *)t->trace + bytesWritten),				 TRACELEN - bytesWritten);		if(bytesWritten == TRACELEN)			_msgs ++;	}	else{		fprintf(_fp, "%s", t->trace);	}	HASH_READ_EXIT();}/* ----------------------------------------------------------------------   void			// procedure    trc_start_client()	// procedure name   --------------------------------------------------------------------*/int trc_start_client(){	int nread;	struct sockaddr_in serv_addr = {0};	char name[1024];	struct hostent *hostptr = NULL;	sem_wait(&_startclient);	/* create endpoint */	if((_serv_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){		perror(NULL);		return 1;	}	gethostname(name, 1024);	hostptr = gethostbyname(name);	(void) memset(&serv_addr, 0, sizeof(serv_addr));	(void) memcpy(&serv_addr.sin_addr, hostptr->h_addr, hostptr->h_length);	/* connect to trace server */	serv_addr.sin_family = AF_INET;	serv_addr.sin_port = htons(TRC_PORT);	if(connect(_serv_sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){		printf("connect error\n");		perror(NULL);		return 1;	}		return 0;}int trc_stop_client(){	close(_serv_sockfd);}/* ----------------------------------------------------------------------   void			// procedure    trc_start_server()	// procedure name   --------------------------------------------------------------------*/void *trc_start_server(void){	char buf[TRACELEN];	int sockfd, client_sockfd;	int status = 0, on =1;	int nread, len;	struct sockaddr_in serv_addr, client_addr;	/* create endpoint */	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){		perror(NULL);		return NULL;	}	/* turn off bind address checking */	status = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,		(const char *)&on, sizeof(on));	if(status == -1){		perror("setsockopt(..., SO_REUSEADDR,...)");		return NULL;	}	/* bind adress */	serv_addr.sin_family = AF_INET;	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);	serv_addr.sin_port = htons(TRC_PORT);	if(bind(sockfd, &serv_addr, sizeof(serv_addr)) < 0){		perror(NULL);		return NULL;	}	/* specify queue */	listen(sockfd, 1);	/* server ready, initialise client */	sem_post(&_startclient);		len = sizeof(client_addr);	client_sockfd = accept(sockfd, &client_addr, &len);	while((_server && (client_sockfd != -1))|| _msgs){		nread = 0;		while((nread += read(client_sockfd, buf, TRACELEN)) < TRACELEN)			;		_msgs--;//		printf("%s", buf);		fprintf(_fp, "%s", buf);	}	close(client_sockfd);	return NULL;}int trc_stop_server(){	return (_server = 0);}

⌨️ 快捷键说明

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