Changeset 51 in libcf for trunk/src/cf_debug.c


Ignore:
Timestamp:
04/02/13 10:23:52 (11 years ago)
Author:
cheese
Message:

#1 change the debugging utiltity to support single context with mutex

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/cf_debug.c

    r50 r51  
    77#include "cf_local.h"
    88#include "cf_error.h"
     9#include "cf_thread.h"
    910
    1011#include <stdlib.h>
     
    3031     : ((CF_DEBUG_CTX *)__ctx)->fp)
    3132
     33/**
     34 * 디버그 컨텍스트
     35 *
     36 * @remark change from public to private
     37 */
     38typedef void *  CF_Debug_Ctx;
     39
     40/**
     41 * 콜스택 데이터
     42 *
     43 * @remark change from public to private
     44 */
     45typedef struct cf_debug_callStack {
     46    char    file[NAME_LENGTH + 1];      /**< 파일 이름 */
     47    char    function[NAME_LENGTH + 1];  /**< 함수 이름 */
     48    int     line;                       /**< 라인 넘버 */
     49} CF_Debug_CallStack;
     50
    3251typedef struct __cf_debug_callstack__
    3352{
     
    3655    int     line;
    3756
     57    int     frameIndex;
     58
    3859    struct __cf_debug_callstack__   * caller;
    3960} S_CF_DEBUG_CALLSTACK, CF_DEBUG_CALLSTACK;
     
    4162typedef struct __cf_debug_ctx__
    4263{
    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;
    4870
    4971    CF_DEBUG_CALLSTACK  callstack;
    5072} S_CF_DEBUG_CTX, CF_DEBUG_CTX;
     73
     74CF_Debug_Ctx    gDebugSingleCtx = NULL;
    5175
    5276static int
     
    117141
    118142/**
    119  * 디버그 컨텍스트를 생성
    120  *
    121  * @return 성공 시, CF_Debug_Ctx 형태의 컨텍스트; 실패 시, NULL
    122  * @see CF_DEBUG_CREATE_CTX
    123  */
    124 CF_Debug_Ctx
    125 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 /**
    135143 * 디버그 컨텍스트를 해제
    136144 *
     
    141149 * @see CF_DEBUG_DESTROY_CTX
    142150 */
    143 int
     151static int
    144152CF_Debug_DestroyCtx (CF_Debug_Ctx ctx)
    145153{
     
    159167    }
    160168
     169    if (context->mutex)
     170        CF_Mutex_Destory (&context->mutex);
     171
    161172    free (context);
    162173
     
    165176
    166177/**
    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 */
     183static int
     184CF_Debug_CreateCtx (CF_Debug_Ctx * ctx)
     185{
     186    int             result = 0;
     187    CF_DEBUG_CTX    * context = NULL;
    187188
    188189    TRY
    189190    {
    190         dupfd = dup (fd);
    191         if (dupfd < 0)
     191        context = (CF_DEBUG_CTX *) calloc (sizeof (CF_DEBUG_CTX), 1);
     192        if (context == NULL)
    192193        {
    193             result = -1;
     194            result = CF_ERROR_DEBUG_ALLOCATE_CTX;
    194195            TRY_BREAK;
    195196        }
    196197
    197         fp = fdopen (dupfd, "a");
    198         if (fp == NULL)
     198        result = CF_Mutex_Create (&context->mutex);
     199        if (result < 0)
    199200        {
    200             close (dupfd);
    201             result = -2;
    202201            TRY_BREAK;
    203202        }
    204203
    205         context->fp = fp;
     204        *ctx = (CF_Debug_Ctx) context;
    206205    }
    207206    CATCH_IF (result < 0)
    208207    {
    209         return CF_ERROR_DEBUG_SET_OUTPUT_FD;
     208        CF_Debug_DestroyCtx (context);
    210209    }
    211210
     
    280279
    281280/**
    282  * 컨텍스트를 업데이트하고 디버그 메시지를 출력
    283  *
    284  * @return CF_OK 반환
     281 * 컨텍스트에 콜스택 푸시
     282 *
     283 * @return 성공 시, CF_OK; 실패 시, 오류 코드
    285284 *
    286285 * @param ctx   디버그 컨텍스트
     
    288287 * @param func  함수 이름
    289288 * @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 */
     290static int
    382291CF_Debug_CallStackPush (CF_Debug_Ctx    ctx,
    383292                        const char      * file,
     
    399308    push->line = line;
    400309    push->caller = context->callstack.caller;
     310    push->frameIndex = context->callstack.frameIndex + 1;
    401311    context->callstack.caller = push;
    402312
     
    407317
    408318/**
    409  * 컨텍스트에서 콜스택 팝
     319 * 컨텍스트에서 콜스택에서 TOP을 제거하지 않고 가져옴
    410320 *
    411321 * @return 성공 시, CF_OK; 실패 시, 오류 코드
     
    414324 * @param callstack 콜스택 정보를 가져올 콜스택 데이터 구조체 포인터
    415325 *
    416  * @see CF_Debug_CallStackPop, CF_Debug_CallStack
    417  */
    418 int
     326 * @see CF_Debug_CallStack
     327 */
     328static int
     329CF_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 */
     359static int
    419360CF_Debug_CallStackPop (CF_Debug_Ctx         ctx,
    420361                       CF_Debug_CallStack   * callstack)
     
    429370        return CF_ERROR_DEBUG_POP_CALLSTACK;
    430371
    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;
    437374
    438375    memset (context->file, 0x00, sizeof (context->file));
     
    454391    return CF_OK;
    455392}
     393
     394/**
     395 * 현재 콜스택을 출력
     396 *
     397 * @return 성공 시, CF_OK; 실패 시, 오류 코드
     398 *
     399 * @param fp 출력 할 파일 포인터
     400 */
     401int
     402CF_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 */
     442int
     443CF_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 */
     472int
     473CF_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.