Linux API/linux2020. 9. 28. 17:43

빌드하다 보니 이상한 에러 발생

 

error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments

 

원인은 open() 의 인자가 2개에서 3개로 늘어서 그렇다는데

vscode 에서 따라가서 봐도 인자는 2개 이상이면 문제가 없어야 하는데... 머지?

__fortify_function int

open (const char *__path, int __oflag, ...)

{

if (__va_arg_pack_len () > 1 __open_too_many_args ();

 

if (__builtin_constant_p (__oflag))

{

        if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)

        {

                __open_missing_mode ();

                return __open_2 (__path, __oflag);

        }

        return __open_alias (__path, __oflag, __va_arg_pack ());

}

 

if (__va_arg_pack_len () < 1) return __open_2 (__path, __oflag);

 

return __open_alias (__path, __oflag, __va_arg_pack ());

}

 

일단은 추적을 해보니 O_CREAT가 0이 아니거나 O_TMP_FILE이 설정되어 있을 경우

/* Detect if open needs mode as a third argument (or for openat as a fourth

argument). */

#ifdef __O_TMPFILE

# define __OPEN_NEEDS_MODE(oflag) \

(((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE)

#else

# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0)

#endif

 

그리고 인자가 1보다 작을 경우(즉, 퍼미션 이 없으면)

/* GCC 4.3 and above allow passing all anonymous arguments of an

__extern_always_inline function to some other vararg function. */

#if __GNUC_PREREQ (4,3)

# define __va_arg_pack() __builtin_va_arg_pack ()

# define __va_arg_pack_len() __builtin_va_arg_pack_len ()

#endif

 

아래를 수행해야 하는데 __open_missing_mode()는 따라가지지 않고

원래대로라면 __open_2(__path, __oflag) 으로 연결되어야 하는데 왜 에러가 난 걸까?

                __open_missing_mode ();

                return __open_2 (__path, __oflag);

[링크 : https://damduc.tistory.com/316]

 

+

/usr/include$ grep -rni "__errordecl" ./
./x86_64-linux-gnu/sys/cdefs.h:125:# define __errordecl(name, msg) \

별거 아닌.. 에러문 출력하는 선언문 인듯 한데..

# define __errordecl(name, msg) \
  extern void name (void) __attribute__((__error__ (msg)))
#else
# define __warndecl(name, msg) extern void name (void)
# define __warnattr(msg)
# define __errordecl(name, msg) extern void name (void)
#endif

 

정리를 하자면 O_CREAT, O_TMPFILE이 존재할 경우

컴파일 단계에서 __open_missing_mode (); 에 도달시 에러를 내고

그 다음 return으로 도달하지 못한다. 그리고 해당 항목은 GCC 4.3 이후 버전에서

인자를 확인하도록 추가되면서 영향을 받았다. 라고 해석을 해야 할 듯?

 

4.3 이후에 추가된 버그라고 봐야 하나?

 

if (__builtin_constant_p (__oflag))

{

        if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)

        {

                __open_missing_mode ();

                return __open_2 (__path, __oflag);

        }

        return __open_alias (__path, __oflag, __va_arg_pack ());

}

'Linux API > linux' 카테고리의 다른 글

linux USB bulk 통신  (0) 2020.10.21
linux open() 과 8진법  (0) 2020.09.28
open() read() write() close()를 이용한 cp 예제  (0) 2020.09.28
fopen64  (0) 2019.06.24
ubuntu iio rotate key 찾기 또 실패  (0) 2019.05.27
Posted by 구차니