📄 ctrace.c
字号:
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 + -