2009년 04월 29일
재미있는 C언어5. printf 에서 생긴일

[NSD][CRT][Tim:0][Err:00000][FileSetAttributes(#1286)@ns_file.c]: Native set attr (0) (0) fails. ERR[0]

SQA  도중에 위와 같은 메시지가 출력되었다는 것이었습니다.

[CRT] 레벨의 에러는 절대 발생해서는 안되는 에러이기 때문에 사뭇 심각했습니다. 물론 나중에 별 문제가 아니라고 밝혀 졌지만,

 

진짜 문제는 ERR[0]이었습니다.

 

문제의 코드를 보면

  1. err = pVnode->pVnodeOps->pfnSetAttributes(pVnode, (dwAttribute & FILE_ATTR_MASK));
    if (FERROR_NO_ERROR != err)
    {

    NSD_EMZ((_T("Native set attr (%u) (%d) fails. ERR[%d]"), NsVnodeGetIndex(pVnode), dwAttribute, err));    break;
    }

위 코드를 보면 err이 FERROR_NO_ERROR이 아닐 때 즉, err이 0이 아니어야만 if안으로 진입하여 메시지를 찍을 수 있는 것이었습니다.

 

"에러가 0인데 메시지가 출력되었다!"

어떻게 이런일이 발생 할 수 있을까요??? 

err가 0이 아니었기 때문에 if안으로 진입한 것인데 정작 err은 0이었다니... 송선임님이 안가르쳐 주셨다면 한참 고민했을 겁니다.

 

범인은 %u였습니다. NsVnodeGetIndex()의 리턴값은 unsigned long long형 이었습니다. 크기가 8byte라는 것이지요.

8byte의 변수를 4byte unsigned int 구분자인 %u를 사용하여 4byte만큼 찍고 나머지 4byte는 그대로 뒤로 밀려 버렸습니다.

그결과 (%u)와 (%d)에 NsVnodeGetIndex()의 리턴값 8byte가 4byte씩 나누어 찍히고, ERR[%d]는 뒤 따라오는 dwAttribute가 찍힌 것이었습니다. (우연히도 NsVnodeGetIndex()와 dwAttribute의 값이 모두 0이었습니다.)

정작 err은 출력 구분자(%)가 없어 출력되지 못했습니다.

위 코드를 아래와 같이 고쳐 해결 하였습니다.

  1. NSD_EMZ((_T("Native set attr (%llu) (%d) fails. ERR[%d]"), NsVnodeGetIndex(pVnode), dwAttribute, err));

printf의 출력 구분자와 변수의 type이 맞지 않아도 컴파일러는 경고나, 에러를 발생하지 않습니다.

 

ps 오늘의 교훈 : 에러 메시지 출력을 잘못해도 SQA를 통과 못할 수도 있습니다. 

by buzzan | 2009/04/29 10:55 | 재미있는 C언어 | 트랙백 | 덧글(1)
트랙백 주소 : http://buzzan.egloos.com/tb/4330352
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by ZZang at 2009/06/02 21:39
에러코드 0...

환장하게 하는 에러...

하지만 그 이유를 알면 더 환장하는... --+

:         :

:

비공개 덧글



<< 이전 페이지 | 다음 페이지 >>