3 Jan
2013
Posted in: 코드
By    1 Comment

포맷스트링이 부릅니다. 헬게이트2…


포맷스트링이 부릅니다. 헬게이트2…
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaru, http://www.jiniya.net

최근에 포맷 스트링과 관련된 문제를 한 번 더 겪어서 여기다 기록을 남겨본다. 문제는 다음과 같은 부분에서 출발했다. 크래시가 났는데 log_writer의 Write 함수를 호출하는 부분에서 났다. 그간 문제없이 잘 사용했던 함수라 증말 증상이 이해가 되질 않았다. 뭔가 buffer 값이 잘못됐는지만 계속 추적했는데 buffer 같은 이상이 없었다.

char buffer[80];
// 버퍼 계산하는 부분
log_writer->Write(L"buffer = '%hs'", buffer);

그렇게 한참을 시도를 하다 놀라운 사실을 발견했다.
클래스가 다음과 같이 선언돼 있었던 것이다. 문제를 눈치 챘는가?

class LogWriter : public ILogWriter
{
public:
    virtual void XCALL Write(xcwstr fmt, ...);
    virtual void XCALL Write(xcstr fmt, ...);
    virtual void XCALL Write(xcwstr fmt, va_arg ap);
    virtual void XCALL Write(xcstr fmt, va_arg ap);
};

맞다. 인자가 두개인 함수가 같이 선언된 것이 문제였다. 내가 원했던 링크 경로는 Write(xcwstr fmt, …)이었는데, Write(xcwstr fmt, va_arg ap)로 연결이 됐던 것이다. 흙~ 그래서 클래스를 다음과 같이 바꿨다.

class LogWriter : public ILogWriter
{
public:
    virtual void XCALL Write(xcwstr fmt, ...);
    virtual void XCALL Write(xcstr fmt, ...);
    virtual void XCALL WriteV(xcwstr fmt, va_arg ap);
    virtual void XCALL WriteV(xcstr fmt, va_arg ap);
};

가변 인자 함수를 정의할 때에는 각별히 주의해야겠다.

Browser does not supports flash movie

  • 트랙백 주소: http://www.jiniya.net/wp/archives/9392/trackback

관련 글

  • http://icary.tistory.com

    그럼 저런 경우는 가변인자가 아니라 정확하게 Argument 정의된 녀석이 runtime에서는 우선적으로 호출된다고 보면 되는건가??
    Rare 케이스 득했네.. ㅋㅋ