Index: /trunk/include/cf_debug.h
===================================================================
--- /trunk/include/cf_debug.h	(revision 50)
+++ /trunk/include/cf_debug.h	(revision 51)
@@ -27,26 +27,8 @@
 
 #ifdef _DEBUG
-/**
- * 디버그 컨텍스트 생성
- *
- * @see CF_Debug_CreateCtx
- */
-# define CF_DEBUG_CREATE_CTX()										\
-	CF_Debug_CreateCtx ()
-
-/**
- * 디버그 컨텍스트 해제
- *
- * @param __ctx 디버그 컨텍스트
- *
- * @see CF_Debug_DestroyCtx
- */
-# define CF_DEBUG_DESTROY_CTX(__ctx)								\
-	CF_Debug_DestroyCtx (__ctx)
 
 /**
  * 디버그 메시지를 지정된 파일 포인터로 출력
  *
- * @param __fp	파일 포인터. 표준출력(stdout) 및 표준오류(stderr) 사용 가능
  * @param __fmt	포맷 스트링
  * @param ...	가변 인자
@@ -60,5 +42,4 @@
  * 바이너리 데이터를 디버그 메시지와 함께 지정된 파일 포인터로 출력
  *
- * @param __fp	파일 포인터. 표준출력(stdout) 및 표준오류(stderr) 사용 가능
  * @param __bin	바이너리 데이터
  * @param __len	바이너리 길이
@@ -72,83 +53,29 @@
 
 /**
- * 컨텍스트를 업데이트하고 디버그 메시지를 출력
+ * 함수에 진입
  *
- * @param __ctx	디버그 컨텍스트
- * @param __fmt	포맷 스트링
- * @param ...	가변 인자
- *
- * @see CF_Debug_Trace
+ * @see CF_Debug_EnterFunction
  */
-# define CF_DEBUG_TRACE(__ctx,__fmt,...)							\
-	CF_Debug_Trace (__ctx,__FILE__,__func__,__LINE__,__fmt,##__VA_ARGS__)
+# define CF_DEBUG_BEGIN_FUNCTION								\
+	CF_Debug_EnterFunction (__FILE__,__func__,__LINE__)
 
 /**
- * 컨텍스트를 업데이트하고 바이너리 데이터를 디버그 메시지와 함께 출력
+ * 함수에서 종료
  *
- * @param __ctx	디버그 컨텍스트
- * @param __bin	바이너리 데이터
- * @param __len	바이너리 길이
- * @param __fmt	포맷 스트링
- * @param ...	가변 인자
- *
- * @see CF_Debug_TraceBin
+ * @see CF_Debug_LeaveFunction
  */
-# define CF_DEBUG_TRACE_BIN(__ctx,__bin,__len,__fmt,...)			\
-	CF_Debug_TraceBin (__ctx,__FILE__,__func__,__LINE__,__bin,__len,__fmt,##__VA_ARGS__)
+# define CF_DEBUG_END_FUNCTION					\
+	CF_Debug_LeaveFunction ()
 
-/**
- * 컨텍스트에 콜스택 푸시
- *
- * @param __ctx 디버그 컨텍스트
- *
- * @see CF_Debug_CallStackPush
- */
-# define CF_DEBUG_CALLSTACK_PUSH(__ctx)								\
-	CF_Debug_CallStackPush (__ctx,__FILE__,__func__,__LINE__)
-
-/**
- * 컨텍스트에서 콜스택 팝
- *
- * @param __ctx			디버그 컨텍스트
- * @param __callstack	콜스택 정보를 가져올 콜스택 데이터 구조체 포인터
- *
- * @see CF_Debug_CallStackPop, CF_Debug_CallStack
- */
-# define CF_DEBUG_CALLSTACK_POP(__ctx,__callstack)					\
-	CF_Debug_CallStackPop (__ctx,__callstack)
 #else // #ifdef _DEBUG
-# define CF_DEBUG_CREATE_CTX()							NULL
-# define CF_DEBUG_DESTROY_CTX(__ctx)
 # define CF_DEBUG_PRINT(__fp,__fmt,...)
 # define CF_DEBUG_PRINT_BIN(__fp,__bin,__len,__fmt,...)
-# define CF_DEBUG_TRACE(__ctx,__fmt,...)
-# define CF_DEBUG_TRACE_BIN(__ctx,__bin,__len,__fmt,...)
-# define CF_DEBUG_CALLSTACK_PUSH(__ctx)
-# define CF_DEBUG_CALLSTACK_POP(__ctx,__callstack)		1
+# define CF_DEBUG_BEGIN_FUNCTION
+# define CF_DEBUG_END_FUNCTION
 #endif // #ifdef _DEBUG
-
-/** 디버그 컨텍스트 */
-typedef void *	CF_Debug_Ctx;
-
-/** 콜스택 데이터 */
-typedef struct cf_debug_callStack {
-	char	file[NAME_LENGTH + 1];		/**< 파일 이름 */
-	char	function[NAME_LENGTH + 1];	/**< 함수 이름 */
-	int		line;						/**< 라인 넘버 */
-} CF_Debug_CallStack;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
-
-CF_EXPORT CF_Debug_Ctx
-CF_Debug_CreateCtx		(void);
-
-CF_EXPORT int
-CF_Debug_DestroyCtx		(CF_Debug_Ctx ctx);
-
-CF_EXPORT int
-CF_Debug_SetOutputFD	(CF_Debug_Ctx	ctx,
-						 int			fd);
 
 CF_EXPORT int
@@ -169,28 +96,13 @@
 
 CF_EXPORT int
-CF_Debug_Trace			(CF_Debug_Ctx	ctx,
-						 const char		* file,
-						 const char		* func,
-						 const int		line,
-						 const char		* fmt, ...);
+CF_Debug_PrintCallStack	(FILE * fp);
 
 CF_EXPORT int
-CF_Debug_TraceBin		(CF_Debug_Ctx			ctx,
-						 const char				* file,
-						 const char				* func,
-						 const int				line,
-						 const unsigned char	* bin,
-						 const int				len,
-						 const char				* fmt, ...);
+CF_Debug_EnterFunction	(const char	* file,
+						 const char	* func,
+						 const int	line);
 
 CF_EXPORT int
-CF_Debug_CallStackPush	(CF_Debug_Ctx	ctx,
-						 const char		* file,
-						 const char		* func,
-						 const int		line);
-
-CF_EXPORT int
-CF_Debug_CallStackPop	(CF_Debug_Ctx		ctx,
-						 CF_Debug_CallStack	* callstack);
+CF_Debug_LeaveFunction	(void);
 
 #ifdef __cplusplus
Index: /trunk/include/cf_error.h
===================================================================
--- /trunk/include/cf_error.h	(revision 50)
+++ /trunk/include/cf_error.h	(revision 51)
@@ -62,7 +62,8 @@
 /*------------------------------------------------------------*/
 #define CF_ERROR_DEBUG_INVALID_CTX			CF_ERROR_DEBUG - 1
-#define CF_ERROR_DEBUG_SET_OUTPUT_FD		CF_ERROR_DEBUG - 2
-#define CF_ERROR_DEBUG_PUSH_CALLSTACK		CF_ERROR_DEBUG - 3
-#define CF_ERROR_DEBUG_POP_CALLSTACK		CF_ERROR_DEBUG - 4
+#define CF_ERROR_DEBUG_PUSH_CALLSTACK		CF_ERROR_DEBUG - 2
+#define CF_ERROR_DEBUG_POP_CALLSTACK		CF_ERROR_DEBUG - 3
+#define CF_ERROR_DEBUG_PEEK_CALLSTACK		CF_ERROR_DEBUG - 4
+#define CF_ERROR_DEBUG_ALLOCATE_CTX			CF_ERROR_DEBUG - 5
 /* }}} debug */
 
Index: /trunk/src/cf_debug.c
===================================================================
--- /trunk/src/cf_debug.c	(revision 50)
+++ /trunk/src/cf_debug.c	(revision 51)
@@ -7,4 +7,5 @@
 #include "cf_local.h"
 #include "cf_error.h"
+#include "cf_thread.h"
 
 #include <stdlib.h>
@@ -30,4 +31,22 @@
 	 : ((CF_DEBUG_CTX *)__ctx)->fp)
 
+/**
+ * 디버그 컨텍스트
+ * 
+ * @remark change from public to private
+ */
+typedef void *	CF_Debug_Ctx;
+
+/**
+ * 콜스택 데이터
+ * 
+ * @remark change from public to private
+ */
+typedef struct cf_debug_callStack {
+	char	file[NAME_LENGTH + 1];		/**< 파일 이름 */
+	char	function[NAME_LENGTH + 1];	/**< 함수 이름 */
+	int		line;						/**< 라인 넘버 */
+} CF_Debug_CallStack;
+
 typedef struct __cf_debug_callstack__
 {
@@ -36,4 +55,6 @@
 	int		line;
 
+	int		frameIndex;
+
 	struct __cf_debug_callstack__	* caller;
 } S_CF_DEBUG_CALLSTACK, CF_DEBUG_CALLSTACK;
@@ -41,12 +62,15 @@
 typedef struct __cf_debug_ctx__
 {
-	char	file[NAME_LENGTH + 1];
-	char	func[NAME_LENGTH + 1];
-	int		line;
-
-	FILE	* fp;
+	char		file[NAME_LENGTH + 1];
+	char		func[NAME_LENGTH + 1];
+	int			line;
+
+	FILE		* fp;
+	CF_Mutex	mutex;
 
 	CF_DEBUG_CALLSTACK	callstack;
 } S_CF_DEBUG_CTX, CF_DEBUG_CTX;
+
+CF_Debug_Ctx	gDebugSingleCtx = NULL;
 
 static int
@@ -117,20 +141,4 @@
 
 /**
- * 디버그 컨텍스트를 생성
- *
- * @return 성공 시, CF_Debug_Ctx 형태의 컨텍스트; 실패 시, NULL
- * @see CF_DEBUG_CREATE_CTX
- */
-CF_Debug_Ctx
-CF_Debug_CreateCtx (void)
-{
-	CF_DEBUG_CTX * ctx = NULL;
-
-	ctx = (CF_DEBUG_CTX *) calloc (sizeof (CF_DEBUG_CTX), 1);
-
-	return (CF_Debug_Ctx) ctx;
-}
-
-/**
  * 디버그 컨텍스트를 해제
  *
@@ -141,5 +149,5 @@
  * @see CF_DEBUG_DESTROY_CTX
  */
-int
+static int
 CF_Debug_DestroyCtx (CF_Debug_Ctx ctx)
 {
@@ -159,4 +167,7 @@
 	}
 
+	if (context->mutex)
+		CF_Mutex_Destory (&context->mutex);
+
 	free (context);
 
@@ -165,47 +176,35 @@
 
 /**
- * 디버그 컨텍스트에 출력할 파일 디스크립터를 설정
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * @param ctx	디버그 컨텍스트
- * @param fd	파일 디스크립터
- *
- * @see CF_File_Open, CF_File_Create
- */
-int
-CF_Debug_SetOutputFD (CF_Debug_Ctx	ctx,
-					  int			fd)
-{
-	int result = 0;
-	int dupfd = 0;
-
-	CF_DEBUG_CTX	* context = (CF_DEBUG_CTX *) ctx;
-	FILE			* fp = NULL;
-
-	CHECK_INVALID_CTX (ctx);
+ * 디버그 컨텍스트를 생성
+ *
+ * @return 성공 시, CF_Debug_Ctx 형태의 컨텍스트; 실패 시, NULL
+ * @see CF_DEBUG_CREATE_CTX
+ */
+static int
+CF_Debug_CreateCtx (CF_Debug_Ctx * ctx)
+{
+	int				result = 0;
+	CF_DEBUG_CTX	* context = NULL;
 
 	TRY
 	{
-		dupfd = dup (fd);
-		if (dupfd < 0)
+		context = (CF_DEBUG_CTX *) calloc (sizeof (CF_DEBUG_CTX), 1);
+		if (context == NULL)
 		{
-			result = -1;
+			result = CF_ERROR_DEBUG_ALLOCATE_CTX;
 			TRY_BREAK;
 		}
 
-		fp = fdopen (dupfd, "a");
-		if (fp == NULL)
+		result = CF_Mutex_Create (&context->mutex);
+		if (result < 0)
 		{
-			close (dupfd);
-			result = -2;
 			TRY_BREAK;
 		}
 
-		context->fp = fp;
+		*ctx = (CF_Debug_Ctx) context;
 	}
 	CATCH_IF (result < 0)
 	{
-		return CF_ERROR_DEBUG_SET_OUTPUT_FD;
+		CF_Debug_DestroyCtx (context);
 	}
 
@@ -280,7 +279,7 @@
 
 /**
- * 컨텍스트를 업데이트하고 디버그 메시지를 출력
- *
- * @return CF_OK 반환
+ * 컨텍스트에 콜스택 푸시
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
  *
  * @param ctx	디버그 컨텍스트
@@ -288,96 +287,6 @@
  * @param func	함수 이름
  * @param line	라인 넘버
- * @param fmt	포맷 스트링
- * @param ...	가변 인자
- *
- * @see CF_Debug_Trace
- */
-int
-CF_Debug_Trace (CF_Debug_Ctx	ctx,
-				const char		* file,
-				const char		* func,
-				const int		line,
-				const char		* fmt, ...)
-{
-	va_list			valist;
-	CF_DEBUG_CTX	* context = (CF_DEBUG_CTX *) ctx;
-
-	CHECK_INVALID_CTX (ctx);
-
-	CF_Debug_Local_UpdateCtx (ctx, file, func, line);
-
-	va_start (valist, fmt);
-	CF_Debug_Local_Print (GET_CTX_OSTREAM (context),
-						  context->file,
-						  context->func,
-						  context->line,
-						  fmt, valist);
-	va_end (valist);
-
-	return CF_OK;
-}
-
-/**
- * 컨텍스트를 업데이트하고 바이너리 데이터를 디버그 메시지와 함께 출력
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * @param ctx	디버그 컨텍스트
- * @param file	파일 경로
- * @param func	함수 이름
- * @param line	라인 넘버
- * @param bin	바이너리 데이터
- * @param len	바이너리 길이
- * @param fmt	포맷 스트링
- * @param ...	가변 인자
- *
- * @see CF_DEBUG_TRACE_BIN
- */
-int
-CF_Debug_TraceBin (CF_Debug_Ctx			ctx,
-				   const char			* file,
-				   const char			* func,
-				   const int			line,
-				   const unsigned char	* bin,
-				   const int			len,
-				   const char			* fmt, ...)
-{
-	va_list			valist;
-	CF_DEBUG_CTX	* context = (CF_DEBUG_CTX *) ctx;
- 
-	CHECK_INVALID_CTX (ctx);
-
-	CF_Debug_Local_UpdateCtx (ctx, file, func, line);
-
-	va_start (valist, fmt);
-	CF_Debug_Local_Print (GET_CTX_OSTREAM (context),
-						  context->file,
-						  context->func,
-						  context->line,
-						  fmt, valist);
-	va_end (valist);
-
-	CF_Debug_Local_PrintBin (GET_CTX_OSTREAM (context),
-							 context->file,
-							 context->func,
-							 context->line,
-							 bin, len);
-
-	return CF_OK;
-}
-
-/**
- * 컨텍스트에 콜스택 푸시
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * @param ctx	디버그 컨텍스트
- * @param file	파일 경로
- * @param func	함수 이름
- * @param line	라인 넘버
- *
- * @see CF_DEBUG_CALLSTACK_PUSH
- */
-int
+ */
+static int
 CF_Debug_CallStackPush (CF_Debug_Ctx	ctx,
 						const char		* file,
@@ -399,4 +308,5 @@
 	push->line = line;
 	push->caller = context->callstack.caller;
+	push->frameIndex = context->callstack.frameIndex + 1;
 	context->callstack.caller = push;
 
@@ -407,5 +317,5 @@
 
 /**
- * 컨텍스트에서 콜스택 팝
+ * 컨텍스트에서 콜스택에서 TOP을 제거하지 않고 가져옴
  *
  * @return 성공 시, CF_OK; 실패 시, 오류 코드
@@ -414,7 +324,38 @@
  * @param callstack	콜스택 정보를 가져올 콜스택 데이터 구조체 포인터
  *
- * @see CF_Debug_CallStackPop, CF_Debug_CallStack
- */
-int
+ * @see CF_Debug_CallStack
+ */
+static int
+CF_Debug_CallStackPeek (CF_Debug_Ctx		ctx,
+						CF_Debug_CallStack	* callstack)
+{
+	CF_DEBUG_CTX		* context = (CF_DEBUG_CTX *) ctx;
+	CF_DEBUG_CALLSTACK	* pop = NULL;
+
+	pop = context->callstack.caller;
+	if (pop == NULL)
+		return CF_ERROR_DEBUG_PEEK_CALLSTACK;
+
+	if (callstack != NULL)
+	{
+		sprintf (callstack->file    , "%s", pop->file);
+		sprintf (callstack->function, "%s", pop->func);
+		callstack->line = pop->line;
+	}
+
+	return CF_OK;
+}
+
+/**
+ * 컨텍스트에서 콜스택 팝
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param ctx		디버그 컨텍스트
+ * @param callstack	콜스택 정보를 가져올 콜스택 데이터 구조체 포인터
+ *
+ * @see CF_Debug_CallStack
+ */
+static int
 CF_Debug_CallStackPop (CF_Debug_Ctx			ctx,
 					   CF_Debug_CallStack	* callstack)
@@ -429,10 +370,6 @@
 		return CF_ERROR_DEBUG_POP_CALLSTACK;
 
-	if (callstack != NULL)
-	{
-		sprintf (callstack->file    , "%s", pop->file);
-		sprintf (callstack->function, "%s", pop->func);
-		callstack->line = pop->line;
-	}
+	if (CF_Debug_CallStackPeek (ctx, callstack) < 0)
+		return CF_ERROR_DEBUG_PEEK_CALLSTACK;
 
 	memset (context->file, 0x00, sizeof (context->file));
@@ -454,2 +391,95 @@
 	return CF_OK;
 }
+
+/**
+ * 현재 콜스택을 출력
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param fp 출력 할 파일 포인터
+ */
+int
+CF_Debug_PrintCallStack (FILE * fp)
+{
+	int iter = 0;
+
+	CF_DEBUG_CTX		* ctx = gDebugSingleCtx;
+	CF_DEBUG_CALLSTACK	* callstack = NULL;
+
+	if (ctx == NULL)
+		return CF_ERROR_DEBUG_INVALID_CTX;
+
+	callstack = &ctx->callstack;
+
+	do
+	{
+		if (callstack == NULL)
+			break;
+
+		fprintf (fp, "#%04d %s (%s:%d)\n",
+					 iter,
+					 callstack->func,
+					 callstack->file,
+					 callstack->line);
+
+		callstack = callstack->caller;
+	} while (iter++ < ctx->callstack.frameIndex);
+
+	return CF_OK;
+}
+
+/**
+ * 함수 진입을 명시
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param file	파일 경로
+ * @param func	함수 이름
+ * @param line	라인 넘버
+ *
+ * @see CF_Debug_LeaveFunction
+ */
+int
+CF_Debug_EnterFunction (const char	* file,
+						const char	* func,
+						const int	line)
+{
+	int				result = 0;
+	CF_DEBUG_CTX	* ctx = NULL;
+
+	if (gDebugSingleCtx == NULL)
+	{
+		result = CF_Debug_CreateCtx (&gDebugSingleCtx);
+		if (result != CF_OK)
+			return result;
+	}
+	ctx = (CF_DEBUG_CTX *)gDebugSingleCtx;
+
+	CF_Mutex_Lock (&ctx->mutex);
+	CF_Debug_CallStackPush (gDebugSingleCtx, file, func, line);
+	CF_Mutex_Unlock (&ctx->mutex);
+
+	return CF_OK;
+}
+
+/**
+ * 함수 종료를 명시
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @see CF_Debug_EnterFunction
+ */
+int
+CF_Debug_LeaveFunction (void)
+{
+	CF_DEBUG_CTX * ctx = (CF_DEBUG_CTX *)gDebugSingleCtx;
+
+	if (ctx == NULL)
+		return CF_ERROR_DEBUG_INVALID_CTX;
+
+	CF_Mutex_Lock (&ctx->mutex);
+	CF_Debug_CallStackPop (gDebugSingleCtx, NULL);
+	CF_Mutex_Unlock (&ctx->mutex);
+
+	return CF_OK;
+}
Index: /trunk/src/cf_log.c
===================================================================
--- /trunk/src/cf_log.c	(revision 50)
+++ /trunk/src/cf_log.c	(revision 51)
@@ -30,13 +30,12 @@
 #define LOCK_LOG_CTX(__ctx)				CF_Mutex_Lock (&__ctx->mutex)
 #define UNLOCK_LOG_CTX(__ctx)			CF_Mutex_Unlock (&__ctx->mutex)
-#define CHECK_INITIALIZED()				(gLogEnvironment.ctxPool == NULL||	\
-										 gLogEnvironment.ctxSize <= 0	)
-#define CHECK_INVALID_MAPID(__mapid)	(gLogEnvironment.ctxSize <= __mapid)
-#define CHECK_MAPPED_ID(__mapid)		(gLogEnvironment.ctxPool[__mapid] != NULL)	\
-
+#define CHECK_INITIALIZED()				(gLogArray.ctxPool == NULL||	\
+										 gLogArray.ctxSize <= 0	)
+#define CHECK_INVALID_MAPID(__mapid)	(gLogArray.ctxSize <= __mapid)
+#define CHECK_MAPPED_ID(__mapid)		(gLogArray.ctxPool[__mapid] != NULL)
 
 #define LOG_BUFFER_DEFAULT_SIZE			128 * 1024
 
-#define LOG_DATETIME_LENGTH			sizeof ("0000-00-00 00:00:00.000") - 1
+#define LOG_DATETIME_LENGTH				sizeof ("0000-00-00 00:00:00.000") - 1
 
 /**
@@ -69,10 +68,10 @@
 } S_CF_LOG_CTX, CF_LOG_CTX;
 
-typedef struct __cf_log_environment__ {
+typedef struct __cf_log_array__ {
 	CF_Log_Ctx	* ctxPool;
 	int			ctxSize;
-} S_CF_LOG_ENVIRONMENT, CF_LOG_ENVIRONMENT;
-
-static CF_LOG_ENVIRONMENT	gLogEnvironment;
+} S_CF_LOG_ARRAY, CF_LOG_ARRAY;
+
+static CF_LOG_ARRAY	gLogArray;
 
 #if defined(_WIN32) || defined(_WIN64)
@@ -475,5 +474,5 @@
 	}
 
-	gLogEnvironment.ctxPool[mapid] = ctx;
+	gLogArray.ctxPool[mapid] = ctx;
 
 	return CF_OK;
@@ -501,8 +500,8 @@
 		return CF_ERROR_LOG_NOT_MAPPED_ID;
 
-	CF_Log_DestroyCtx (gLogEnvironment.ctxPool[mapid]);
-
-	free (gLogEnvironment.ctxPool[mapid]);
-	gLogEnvironment.ctxPool[mapid] = NULL;
+	CF_Log_DestroyCtx (gLogArray.ctxPool[mapid]);
+
+	free (gLogArray.ctxPool[mapid]);
+	gLogArray.ctxPool[mapid] = NULL;
 
 	return CF_OK;
@@ -528,5 +527,5 @@
 		return CF_ERROR_LOG_NOT_MAPPED_ID;
 
-	*ctx = gLogEnvironment.ctxPool[mapid];
+	*ctx = gLogArray.ctxPool[mapid];
 
 	return CF_OK;
@@ -543,13 +542,13 @@
 CF_Log_Initialize (const int logPool)
 {
-	memset (&gLogEnvironment, 0x00, sizeof (CF_LOG_ENVIRONMENT));
+	memset (&gLogArray, 0x00, sizeof (CF_LOG_ARRAY));
 
 	if (logPool > 0)
 	{
-		gLogEnvironment.ctxPool =
+		gLogArray.ctxPool =
 			(CF_Log_Ctx *) calloc ((size_t) logPool, sizeof (CF_Log_Ctx));
-		if (gLogEnvironment.ctxPool == NULL)
+		if (gLogArray.ctxPool == NULL)
 			return CF_ERROR_LOG_INITIALIZE;
-		gLogEnvironment.ctxSize = logPool;
+		gLogArray.ctxSize = logPool;
 	}
 
@@ -567,13 +566,13 @@
 	int mapid = 0;
 
-	for (mapid = 0 ; mapid < gLogEnvironment.ctxSize ; mapid++)
+	for (mapid = 0 ; mapid < gLogArray.ctxSize ; mapid++)
 	{
 		CF_Log_UnmapCtxID (mapid);
 	}
 
-	if (gLogEnvironment.ctxPool != NULL)
-		free (gLogEnvironment.ctxPool);
-
-	memset (&gLogEnvironment, 0x00, sizeof (CF_LOG_ENVIRONMENT));
+	if (gLogArray.ctxPool != NULL)
+		free (gLogArray.ctxPool);
+
+	memset (&gLogArray, 0x00, sizeof (CF_LOG_ARRAY));
 
 	return CF_OK;
Index: /trunk/test/debug.c
===================================================================
--- /trunk/test/debug.c	(revision 50)
+++ /trunk/test/debug.c	(revision 51)
@@ -7,33 +7,29 @@
 #include "cf_debug.h"
 
-CF_Debug_Ctx gDebugCtx;
+#include <string.h>
 
 void callee (void) {
-	CF_Debug_CallStack callstack;
-	
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
-	CF_DEBUG_CALLSTACK_POP (gDebugCtx, &callstack);
+	CF_DEBUG_BEGIN_FUNCTION;
+
+	CF_Debug_PrintCallStack (stdout);
+
+	CF_DEBUG_END_FUNCTION;
 }
 
 int main (void) {
-	int fd = 0;
-	gDebugCtx = CF_Debug_CreateCtx ();
+	char data[] =
+		"【 曲名 : 사랑하고 있는데 】\n"
+		"《 歌 : Kylee 》\n"
+		"『 절원의 템페스트 OP2 Theme 』\n";
 
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
+	CF_DEBUG_BEGIN_FUNCTION;
 
-	CF_DEBUG_TRACE (gDebugCtx, "print trace message with context to stderr\n");
+	CF_DEBUG_PRINT (stderr, "print message with context to stderr\n");
 
-	fd = CF_File_Create ("debug.txt");
-	if (fd < 0) {
-		CF_DEBUG_PRINT (stderr, "error ...\n");
-		// error
-	}
-	CF_Debug_SetOutputFD (gDebugCtx, fd);
+	CF_DEBUG_PRINT_BIN (stdout, (unsigned char *) data, (int) sizeof (data), "hehehehe\n");
 
-	CF_DEBUG_TRACE (gDebugCtx, "print trace message with context to debug.txt\n");
+	callee ();
 
-	CF_DEBUG_CALLSTACK_POP (gDebugCtx, NULL);
-
-	CF_Debug_DestroyCtx (gDebugCtx);
+	CF_DEBUG_END_FUNCTION;
 
 	return 0;
Index: /trunk/test/test.c
===================================================================
--- /trunk/test/test.c	(revision 50)
+++ /trunk/test/test.c	(revision 51)
@@ -22,6 +22,4 @@
 #define PORT		1234
 
-CF_Debug_Ctx		gDebugCtx;
-CF_Debug_CallStack	gDebugCallstack;
 CF_Mutex			globalMutex;
 
@@ -63,5 +61,5 @@
 	CF_Thread	tid[10];
 
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
+	CF_DEBUG_BEGIN_FUNCTION;
 
 	/* initialize */
@@ -125,4 +123,6 @@
 	/* finalize */
 	CF_Log_Finalize ();
+
+	CF_DEBUG_END_FUNCTION;
 }
 
@@ -132,47 +132,41 @@
 	char	buffer[128] = {0x00,};
 
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
+	CF_DEBUG_BEGIN_FUNCTION;
 
 	fd = CF_File_Open (file, CF_FILE_RO);
 	if (fd < 0)
-		CF_DEBUG_TRACE (gDebugCtx, "what the ... file open ?\n");
+		CF_DEBUG_PRINT (stderr, "what the ... file open ?\n");
 
 	if (CF_File_Read (fd, buffer, sizeof (buffer)) < 0)
-		CF_DEBUG_TRACE (gDebugCtx, "what the ... file read ?\n");
+		CF_DEBUG_PRINT (stderr, "what the ... file read ?\n");
 	else
-		CF_DEBUG_TRACE_BIN (gDebugCtx, (unsigned char *)buffer,
-										sizeof (buffer),
-										"-- %d bytes of %d bytes\n",
-										sizeof (buffer),
-										CF_File_GetSize (fd));
+		CF_DEBUG_PRINT_BIN (stdout, (unsigned char *)buffer,
+									sizeof (buffer),
+									"-- %d bytes of %d bytes\n",
+									sizeof (buffer),
+									CF_File_GetSize (fd));
 
 	CF_File_Close (fd);
 
-	CF_DEBUG_CALLSTACK_POP (gDebugCtx, NULL);
+	CF_DEBUG_END_FUNCTION;
 }
 
 void test_callstack3 (void)
 {
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
-	while (CF_DEBUG_CALLSTACK_POP (gDebugCtx, &gDebugCallstack) == CF_OK)
-	{
-		CF_DEBUG_TRACE (gDebugCtx, "print callstack [file:%s line:%d func:%s]\n",
-									gDebugCallstack.file,
-									gDebugCallstack.line,
-									gDebugCallstack.function);
-	}
-	CF_DEBUG_CALLSTACK_POP (gDebugCtx, NULL);
+	CF_DEBUG_BEGIN_FUNCTION;
+	CF_Debug_PrintCallStack (stdout);
+	CF_DEBUG_END_FUNCTION;
 }
 void test_callstack2 (void)
 {
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
+	CF_DEBUG_BEGIN_FUNCTION;
 	test_callstack3 ();
-	CF_DEBUG_CALLSTACK_POP (gDebugCtx, NULL);
+	CF_DEBUG_END_FUNCTION;
 }
 void test_callstack1 (void)
 {
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
+	CF_DEBUG_BEGIN_FUNCTION;
 	test_callstack2 ();
-	CF_DEBUG_CALLSTACK_POP (gDebugCtx, NULL);
+	CF_DEBUG_END_FUNCTION;
 }
 
@@ -333,7 +327,5 @@
 int main (int argc, char ** argv)
 {
-	gDebugCtx = CF_Debug_CreateCtx ();
-
-	CF_DEBUG_CALLSTACK_PUSH (gDebugCtx);
+	CF_DEBUG_BEGIN_FUNCTION;
 
 	// 1
@@ -353,13 +345,7 @@
 	test_socket ();
 
-	CF_DEBUG_CALLSTACK_POP (gDebugCtx, &gDebugCallstack);
-
 	CF_DEBUG_PRINT (stderr, " == END OF TEST ==\n");
-	CF_DEBUG_TRACE (gDebugCtx, "here is the end of function [file:%s line:%d func:%s]\n",
-								gDebugCallstack.file,
-								gDebugCallstack.line,
-								gDebugCallstack.function);
-
-	CF_Debug_DestroyCtx (gDebugCtx);
+
+	CF_DEBUG_END_FUNCTION;
 
 	return 0;
