Changeset 51 in libcf for trunk/src/cf_debug.c
- Timestamp:
- 04/02/13 10:23:52 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/cf_debug.c
r50 r51 7 7 #include "cf_local.h" 8 8 #include "cf_error.h" 9 #include "cf_thread.h" 9 10 10 11 #include <stdlib.h> … … 30 31 : ((CF_DEBUG_CTX *)__ctx)->fp) 31 32 33 /** 34 * 디버그 컨텍스트 35 * 36 * @remark change from public to private 37 */ 38 typedef void * CF_Debug_Ctx; 39 40 /** 41 * 콜스택 데이터 42 * 43 * @remark change from public to private 44 */ 45 typedef struct cf_debug_callStack { 46 char file[NAME_LENGTH + 1]; /**< 파일 이름 */ 47 char function[NAME_LENGTH + 1]; /**< 함수 이름 */ 48 int line; /**< 라인 넘버 */ 49 } CF_Debug_CallStack; 50 32 51 typedef struct __cf_debug_callstack__ 33 52 { … … 36 55 int line; 37 56 57 int frameIndex; 58 38 59 struct __cf_debug_callstack__ * caller; 39 60 } S_CF_DEBUG_CALLSTACK, CF_DEBUG_CALLSTACK; … … 41 62 typedef struct __cf_debug_ctx__ 42 63 { 43 char file[NAME_LENGTH + 1]; 44 char func[NAME_LENGTH + 1]; 45 int line; 46 47 FILE * fp; 64 char file[NAME_LENGTH + 1]; 65 char func[NAME_LENGTH + 1]; 66 int line; 67 68 FILE * fp; 69 CF_Mutex mutex; 48 70 49 71 CF_DEBUG_CALLSTACK callstack; 50 72 } S_CF_DEBUG_CTX, CF_DEBUG_CTX; 73 74 CF_Debug_Ctx gDebugSingleCtx = NULL; 51 75 52 76 static int … … 117 141 118 142 /** 119 * 디버그 컨텍스트를 생성120 *121 * @return 성공 시, CF_Debug_Ctx 형태의 컨텍스트; 실패 시, NULL122 * @see CF_DEBUG_CREATE_CTX123 */124 CF_Debug_Ctx125 CF_Debug_CreateCtx (void)126 {127 CF_DEBUG_CTX * ctx = NULL;128 129 ctx = (CF_DEBUG_CTX *) calloc (sizeof (CF_DEBUG_CTX), 1);130 131 return (CF_Debug_Ctx) ctx;132 }133 134 /**135 143 * 디버그 컨텍스트를 해제 136 144 * … … 141 149 * @see CF_DEBUG_DESTROY_CTX 142 150 */ 143 int151 static int 144 152 CF_Debug_DestroyCtx (CF_Debug_Ctx ctx) 145 153 { … … 159 167 } 160 168 169 if (context->mutex) 170 CF_Mutex_Destory (&context->mutex); 171 161 172 free (context); 162 173 … … 165 176 166 177 /** 167 * 디버그 컨텍스트에 출력할 파일 디스크립터를 설정 168 * 169 * @return 성공 시, CF_OK; 실패 시, 오류 코드 170 * 171 * @param ctx 디버그 컨텍스트 172 * @param fd 파일 디스크립터 173 * 174 * @see CF_File_Open, CF_File_Create 175 */ 176 int 177 CF_Debug_SetOutputFD (CF_Debug_Ctx ctx, 178 int fd) 179 { 180 int result = 0; 181 int dupfd = 0; 182 183 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx; 184 FILE * fp = NULL; 185 186 CHECK_INVALID_CTX (ctx); 178 * 디버그 컨텍스트를 생성 179 * 180 * @return 성공 시, CF_Debug_Ctx 형태의 컨텍스트; 실패 시, NULL 181 * @see CF_DEBUG_CREATE_CTX 182 */ 183 static int 184 CF_Debug_CreateCtx (CF_Debug_Ctx * ctx) 185 { 186 int result = 0; 187 CF_DEBUG_CTX * context = NULL; 187 188 188 189 TRY 189 190 { 190 dupfd = dup (fd);191 if ( dupfd < 0)191 context = (CF_DEBUG_CTX *) calloc (sizeof (CF_DEBUG_CTX), 1); 192 if (context == NULL) 192 193 { 193 result = -1;194 result = CF_ERROR_DEBUG_ALLOCATE_CTX; 194 195 TRY_BREAK; 195 196 } 196 197 197 fp = fdopen (dupfd, "a");198 if ( fp == NULL)198 result = CF_Mutex_Create (&context->mutex); 199 if (result < 0) 199 200 { 200 close (dupfd);201 result = -2;202 201 TRY_BREAK; 203 202 } 204 203 205 context->fp = fp;204 *ctx = (CF_Debug_Ctx) context; 206 205 } 207 206 CATCH_IF (result < 0) 208 207 { 209 return CF_ERROR_DEBUG_SET_OUTPUT_FD;208 CF_Debug_DestroyCtx (context); 210 209 } 211 210 … … 280 279 281 280 /** 282 * 컨텍스트 를 업데이트하고 디버그 메시지를 출력283 * 284 * @return CF_OK 반환281 * 컨텍스트에 콜스택 푸시 282 * 283 * @return 성공 시, CF_OK; 실패 시, 오류 코드 285 284 * 286 285 * @param ctx 디버그 컨텍스트 … … 288 287 * @param func 함수 이름 289 288 * @param line 라인 넘버 290 * @param fmt 포맷 스트링 291 * @param ... 가변 인자 292 * 293 * @see CF_Debug_Trace 294 */ 295 int 296 CF_Debug_Trace (CF_Debug_Ctx ctx, 297 const char * file, 298 const char * func, 299 const int line, 300 const char * fmt, ...) 301 { 302 va_list valist; 303 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx; 304 305 CHECK_INVALID_CTX (ctx); 306 307 CF_Debug_Local_UpdateCtx (ctx, file, func, line); 308 309 va_start (valist, fmt); 310 CF_Debug_Local_Print (GET_CTX_OSTREAM (context), 311 context->file, 312 context->func, 313 context->line, 314 fmt, valist); 315 va_end (valist); 316 317 return CF_OK; 318 } 319 320 /** 321 * 컨텍스트를 업데이트하고 바이너리 데이터를 디버그 메시지와 함께 출력 322 * 323 * @return 성공 시, CF_OK; 실패 시, 오류 코드 324 * 325 * @param ctx 디버그 컨텍스트 326 * @param file 파일 경로 327 * @param func 함수 이름 328 * @param line 라인 넘버 329 * @param bin 바이너리 데이터 330 * @param len 바이너리 길이 331 * @param fmt 포맷 스트링 332 * @param ... 가변 인자 333 * 334 * @see CF_DEBUG_TRACE_BIN 335 */ 336 int 337 CF_Debug_TraceBin (CF_Debug_Ctx ctx, 338 const char * file, 339 const char * func, 340 const int line, 341 const unsigned char * bin, 342 const int len, 343 const char * fmt, ...) 344 { 345 va_list valist; 346 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx; 347 348 CHECK_INVALID_CTX (ctx); 349 350 CF_Debug_Local_UpdateCtx (ctx, file, func, line); 351 352 va_start (valist, fmt); 353 CF_Debug_Local_Print (GET_CTX_OSTREAM (context), 354 context->file, 355 context->func, 356 context->line, 357 fmt, valist); 358 va_end (valist); 359 360 CF_Debug_Local_PrintBin (GET_CTX_OSTREAM (context), 361 context->file, 362 context->func, 363 context->line, 364 bin, len); 365 366 return CF_OK; 367 } 368 369 /** 370 * 컨텍스트에 콜스택 푸시 371 * 372 * @return 성공 시, CF_OK; 실패 시, 오류 코드 373 * 374 * @param ctx 디버그 컨텍스트 375 * @param file 파일 경로 376 * @param func 함수 이름 377 * @param line 라인 넘버 378 * 379 * @see CF_DEBUG_CALLSTACK_PUSH 380 */ 381 int 289 */ 290 static int 382 291 CF_Debug_CallStackPush (CF_Debug_Ctx ctx, 383 292 const char * file, … … 399 308 push->line = line; 400 309 push->caller = context->callstack.caller; 310 push->frameIndex = context->callstack.frameIndex + 1; 401 311 context->callstack.caller = push; 402 312 … … 407 317 408 318 /** 409 * 컨텍스트에서 콜스택 팝319 * 컨텍스트에서 콜스택에서 TOP을 제거하지 않고 가져옴 410 320 * 411 321 * @return 성공 시, CF_OK; 실패 시, 오류 코드 … … 414 324 * @param callstack 콜스택 정보를 가져올 콜스택 데이터 구조체 포인터 415 325 * 416 * @see CF_Debug_CallStackPop, CF_Debug_CallStack 417 */ 418 int 326 * @see CF_Debug_CallStack 327 */ 328 static int 329 CF_Debug_CallStackPeek (CF_Debug_Ctx ctx, 330 CF_Debug_CallStack * callstack) 331 { 332 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx; 333 CF_DEBUG_CALLSTACK * pop = NULL; 334 335 pop = context->callstack.caller; 336 if (pop == NULL) 337 return CF_ERROR_DEBUG_PEEK_CALLSTACK; 338 339 if (callstack != NULL) 340 { 341 sprintf (callstack->file , "%s", pop->file); 342 sprintf (callstack->function, "%s", pop->func); 343 callstack->line = pop->line; 344 } 345 346 return CF_OK; 347 } 348 349 /** 350 * 컨텍스트에서 콜스택 팝 351 * 352 * @return 성공 시, CF_OK; 실패 시, 오류 코드 353 * 354 * @param ctx 디버그 컨텍스트 355 * @param callstack 콜스택 정보를 가져올 콜스택 데이터 구조체 포인터 356 * 357 * @see CF_Debug_CallStack 358 */ 359 static int 419 360 CF_Debug_CallStackPop (CF_Debug_Ctx ctx, 420 361 CF_Debug_CallStack * callstack) … … 429 370 return CF_ERROR_DEBUG_POP_CALLSTACK; 430 371 431 if (callstack != NULL) 432 { 433 sprintf (callstack->file , "%s", pop->file); 434 sprintf (callstack->function, "%s", pop->func); 435 callstack->line = pop->line; 436 } 372 if (CF_Debug_CallStackPeek (ctx, callstack) < 0) 373 return CF_ERROR_DEBUG_PEEK_CALLSTACK; 437 374 438 375 memset (context->file, 0x00, sizeof (context->file)); … … 454 391 return CF_OK; 455 392 } 393 394 /** 395 * 현재 콜스택을 출력 396 * 397 * @return 성공 시, CF_OK; 실패 시, 오류 코드 398 * 399 * @param fp 출력 할 파일 포인터 400 */ 401 int 402 CF_Debug_PrintCallStack (FILE * fp) 403 { 404 int iter = 0; 405 406 CF_DEBUG_CTX * ctx = gDebugSingleCtx; 407 CF_DEBUG_CALLSTACK * callstack = NULL; 408 409 if (ctx == NULL) 410 return CF_ERROR_DEBUG_INVALID_CTX; 411 412 callstack = &ctx->callstack; 413 414 do 415 { 416 if (callstack == NULL) 417 break; 418 419 fprintf (fp, "#%04d %s (%s:%d)\n", 420 iter, 421 callstack->func, 422 callstack->file, 423 callstack->line); 424 425 callstack = callstack->caller; 426 } while (iter++ < ctx->callstack.frameIndex); 427 428 return CF_OK; 429 } 430 431 /** 432 * 함수 진입을 명시 433 * 434 * @return 성공 시, CF_OK; 실패 시, 오류 코드 435 * 436 * @param file 파일 경로 437 * @param func 함수 이름 438 * @param line 라인 넘버 439 * 440 * @see CF_Debug_LeaveFunction 441 */ 442 int 443 CF_Debug_EnterFunction (const char * file, 444 const char * func, 445 const int line) 446 { 447 int result = 0; 448 CF_DEBUG_CTX * ctx = NULL; 449 450 if (gDebugSingleCtx == NULL) 451 { 452 result = CF_Debug_CreateCtx (&gDebugSingleCtx); 453 if (result != CF_OK) 454 return result; 455 } 456 ctx = (CF_DEBUG_CTX *)gDebugSingleCtx; 457 458 CF_Mutex_Lock (&ctx->mutex); 459 CF_Debug_CallStackPush (gDebugSingleCtx, file, func, line); 460 CF_Mutex_Unlock (&ctx->mutex); 461 462 return CF_OK; 463 } 464 465 /** 466 * 함수 종료를 명시 467 * 468 * @return 성공 시, CF_OK; 실패 시, 오류 코드 469 * 470 * @see CF_Debug_EnterFunction 471 */ 472 int 473 CF_Debug_LeaveFunction (void) 474 { 475 CF_DEBUG_CTX * ctx = (CF_DEBUG_CTX *)gDebugSingleCtx; 476 477 if (ctx == NULL) 478 return CF_ERROR_DEBUG_INVALID_CTX; 479 480 CF_Mutex_Lock (&ctx->mutex); 481 CF_Debug_CallStackPop (gDebugSingleCtx, NULL); 482 CF_Mutex_Unlock (&ctx->mutex); 483 484 return CF_OK; 485 }
Note:
See TracChangeset
for help on using the changeset viewer.