'#define'에 해당하는 글 1건

출처 : http://blog.naver.com/PostView.nhn?blogId=dolicom&logNo=10096312448


보통 리눅스 커널을 디버깅 하려면 쉽게 log 메세지를 이용할 수 있다. 이럴 때는 printk 함수를 사용하면 되는데 디버깅이 끝나면 제거 하면 된다.


#ifdef DEBUG

#define DPRINTF(fmt,args,...) printk(##args)

#else

 #define DPRINTF

#endif


이렇게 하면

DPRINTF을 골라서 쉽게 제거할 수 있다.


예를 들어 특정 부분만을 디버깅 할 때만 printf 한다면


#include <stdio.h>


#define DEBUG

#ifdef DEBUG
#define DPRINTF(fmt,args,...) printf( "%s:%s:%d: " fmt, __FILE__,  __FUNCTION__, __LINE__, ##args)
#else
#define DPRINTF   - 코드내의 이 함수를 제거 하여 출력하지 않는다.
#endif


int main( int argc, char *argv[])
{
   int i = 0;

   if (argc < 2) {
      DPRINTF( "argc=%d\n", argc);
   } else {
      DPRINTF( "argc=%d,argv1=%s\n", argc, argv[1]);
   }

   printf("파일이름: %s\n", __FILE__);
   printf("현재 라인번호 : %d\n", __LINE__);
   printf("현재 출력되는 함수 : %s\n", __FUNCTION__);
   printf("컴파일 날짜 : %s\n", __DATE__);
   printf("컴파일 시간 : %s\n", __TIME__);

   return 0;
}


실행 :

C:\defexam\defexam\defexam.cpp:main:23: argc=1
파일이름: c:\defexam\defexam\defexam.cpp
현재 라인번호 : 29

현재 출력되는 함수 : main
컴파일 날짜 : Nov 14 2010
컴파일 시간 : 21:55:14




#와 ##


#   : 스트링화 한다.

## : 토큰을 연결하여 하나의 토큰으로 만든다.



Token


프로그램을 구성하고 있는 문법적으로 의미 있는 최소 단위

          

if (i<100) sum+=i;
===> if, (, i, <, 100, ), sum, +=, i, ;

10개의 토큰으로 이루어 진다.



토큰의 예

  • 키워드 : int, while, if, else, auto, char, for…
  • 식별자 : main, printf, scanf, i, j…
  • 연산자 : +, -, *, /, =, <. >=…
  • 수치상수 : 124, 12.35, 7E9 등과 같은 수
  • 문자상수 : 단일 인용 부호(' ')내의 단일 문자나 문자열
  • 특수문자 : (, ), ;와 같이 구분자로 사용되는 문자
  • 주해 : /*와 */사이에 있는 임의의 문자열, 컴파일러에 의해 번역되지 않는다.

#예 :

#define QUOTEME(x) #x
printf("%s\n", QUOTEME(1+2));
===>
printf("%s\n", "1+2");


Token concatenation


#define CATTOK(x,y)  x##y


  int manage;

   manage = 10;

   printf("%d\n", CATTOK(man,age));

===>

   printf("%d\n", manage );



 

 

예 1 :


#define FORMAT_(type) FORMAT_##type
#define FORMAT_int    "%d"
#define FORMAT_double "%g"


 

void print_star(const starStruct *const star) {
  /* FORMAT_(type) will be replaced with FORMAT_int or FORMAT_double */
  #define EXPAND_STAR_MEMBER(member, type) \
    printf("%s: " FORMAT_(type) "\n", #member, star->member);
  EXPAND_STAR
  #undef EXPAND_STAR_MEMBER
  }

 

예 2 :

 

#define MYCASE(item,id) \
case id: \
  item##_##id = id;\
break

switch(x) {
    MYCASE(widget,23);
}

===>

case 23:
  widget_23 = 23;
break;

 


예 3 :


#define     CONCAT(a, b)     a##b


// main 함수

int main(void)

{

          int arr〔2〕= { 100, 200 };


          printf("%d \n", CONCAT(2, 4));

          printf("%d %d \n", CONCAT(arr, 〔0〕), CONCAT(arr, 〔1〕));


          return 0;

}



printf 사용시 방법 몇가지


 

#define print_int(val)    printf("%d", val)
#define print_double(val) printf("%g", val




#define DPRINTF(a,args...) fprintf( stderr, "%s:%d:"#a"\n", __FUNCTION__, __LINE__, ##args)


예:


#define DPRINTF(fmt,args,...) printf( "%s:%d:" fmt, __FUNCTION__, __LINE__, ##args)


int main( int argc, char *argv[])
{
   int i = 0;


   if (argc < 2) {

      DPRINTF( "argc=%d", argc);

   }


   printf("End of program\n");
   return 0;
}


#define CHECK1(x,format,args) if(x) {printf(format,args);}


#define fcntl( fd, command, ... ) \
wpurple_fcntl( fd, command, ##__VA_ARGS__ )

#define gprintk(fmt, x... ) printk( "%s: " fmt, __FUNCTION__ , ## x)

 

다른 예


#define a /*
#<?php echo "\\010Hello, world!\\n"// 2> /dev/null > /dev/null \\
;
// 2> /dev/null; x=a;
$x=5 // 2> /dev/null \\
;
if (($x))
// 2> /dev/null; then
return 0;
// 2> /dev/null; fi
#define e ?>
#define b */
#include
#define main() int main()
#define printf printf(
#define true )
#define function
function main()
{
printf "Hello, world!\\n"true/* 2> /dev/null | grep -v true*/;
return 0;
}
#define c /*
main
#*/


예 :


#define printf(fmt, args...)    test_print(fmt, ##args)


int ttyS1_fd;


void test_print(char *fmt, ...)
{
   write(ttyS1_fd, fmt, strlen(fmt));
}

int main(void)
{
   if ( (ttyS1_fd = open("/dev/ttyS1", O_RDWR|O_NOCTTY)) < 0 ) {
       printf(" /dev/ttyS1" open failed\n");
       return 1;
   }

   while (1) {
      printf("abcde %d\n", 1);
      sleep(1)
   }

  return 0;
}

 

#define sum(x,y)  (x+y)


#define LEN 100

#define WIDTH 100

   char array[LEN][WIDTH];

#undef LEN

#undef WIDTH




printk 사용


참고로 printk 함수는

printk()는 카널의 메시지를 콘솔이나 dmesg, syslog 데몬에게 넘겨주는 일을 한다.



1. printk

 

 include/linux/kernel.h


일반적인 프로그램을 작성할때도 로그정책은 매우 중요하다. 보통 레벨 1은 가장 낮은 수준의 디버그 메시지 레벨 3은 모든 디버그 메시지를 모두 남기는 식으로 정하는데 priorities를 이용해서 발생되는 로그에 레벨을 부여해 줄 수 있다.

priority 는 다음과 같이 커널에 정의되어 있다.

#define KERN_EMERG    "<0>"  /* system is unusable               */ 
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */

2. printk 사용

 

KERN_INFO의 동일한 표현

printk(KERN_INFO "system ok\n");

printk("<6>" "system ok\n");

printk("<6>system ok\n");


기타 예 :

printk(KERN_INFO "i = %u\n", i);

printk("<0> %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);

레벨에 대한 표시를 하지 않는다면 default 레벨은 "KERN_WARNING" 이다.

 

3. 커널 메시지 관리 데몬

- klogd : 커널에서 발생하는 메시지를 기록하고 관리한다.

- syslogd : 커널에서 발생한느 메시지와 응용 프로그램에서 요청한 시스템 정보를 기록하고 관리한다.

- /var/log/messages 파일에 모든 커널메시지가 저장된다.

 

4. 로그 정보보기

- dmesg

- cat /proc/kmsg : 커널 메시지가 발생할 때 즉시 출력.



Windows CE에서 사용법


보통 디버깅 시 정의하는 것을 바꿀 필요가 생긴다. 지금 WindowsCE의 메세지를 PC WIN32 MFC로 바꾸려면 RETAILMSG과 TRACE의 정의가 틀리다. 따라서 이것을 조정하기 위한 정의 이다.


RETAILMSG 함수의 첫번째 인수 n을 제거하는 것이다.


#define RETAILMSG(n, args...) TRACE(##args)   ---> ##다음 부터는 그대로



RETAILMSG(1, (TEXT("Invalid parameter to ReadChunk()\r\n")));

===> TRACE( (TEXT("Invalid parameter to ReadChunk()\r\n")));


RETAILMSG(1, (TEXT("Error opening %s. Error code = 0x%08x\n"), pszFilename, GetLastError()));

===> TRACE( (TEXT("Error opening %s. Error code = 0x%08x\n"), pszFilename, GetLastError()));


'Linux' 카테고리의 다른 글

LIDS 내부구조(리눅스 파일 보안)  (0) 2011.02.16
__attribute__ __context__ sparse  (0) 2011.02.15
linux directory dirent.h  (0) 2010.12.05
insmod,rmmod,lsmod,modprobe,depmod,modinfo  (0) 2010.12.05
[MTD] NAND: nandsim page-wise allocation  (0) 2010.12.05

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,