IT Share you

GCC의 -Wpsabi 옵션은 정확히 무엇을합니까?

shareyou 2020. 12. 5. 10:58
반응형

GCC의 -Wpsabi 옵션은 정확히 무엇을합니까? 그것을 억 누르는 것의 의미는 무엇입니까?


배경

작년에 저는 nlohmann json 라이브러리 [1]를 사용 하고 있었고 arm-linux-gnueabi-*경고없이 GCC 5.x 사용하여 x86_64에서 크로스 컴파일했습니다 . GCC를 최신 버전으로 업데이트하면 GCC는 비밀 진단 메모 페이지를 생성합니다. 예를 들어 다음은 메모 중 하나입니다.

In file included from /usr/arm-linux-gnueabi/include/c++/7/vector:69:0,
             from include/json.hpp:58,
             from src/write_hsi.cpp:23:
/usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long long int, long long unsigned int, double, std::allocator, nlohmann::adl_serializer>}; _Tp = nlohmann::basic_json<>; _Alloc = std::allocator<nlohmann::basic_json<> >]’:
/usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc:394:7: note: parameter passing for argument of type ‘std::vector<nlohmann::basic_json<>, std::allocator<nlohmann::basic_json<> > >::iterator {aka __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<>, std::allocator<nlohmann::basic_json<> > > >}’ changed in GCC 7.1
   vector<_Tp, _Alloc>::
   ^~~~~~~~~~~~~~~~~~~
/usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc: In member function ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer> nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::parser::parse_internal(bool) [with ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]’:
/usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc:105:21: note: parameter passing for argument of type ‘__gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<>, std::allocator<nlohmann::basic_json<> > > >’ changed in GCC 7.1
_M_realloc_insert(end(), std::forward<_Args>(__args)...);
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-Wno-psabi, 컴파일러 옵션 에 추가 하여 솔루션을 찾기가 쉬웠습니다 . 사실 그것은 라이브러리에 구현 된 수정 사항이었습니다. [2]

ABI (Application Binary Interface) 및 PSABI (프로세서 별 ABI)의 기본 사항을 이해합니다. 참고로이 답변 [11] 은 ABI에 대한 간략한 개요를 제공합니다.

ABI ( Application Binary Interface )는 고수준 언어의 저수준 개념과 특정 하드웨어 / OS 플랫폼의 기계어 코드 기능 간의 매핑을 정의하는 표준입니다. 여기에는 다음이 포함됩니다.

  • C / C ++ / Fortran / ... 데이터 유형 이 메모리에 배치되는 방식 (데이터 크기 / 정렬)
  • 중첩 된 함수 호출의 작동 방식 (함수 호출자에게 반환하는 방법에 대한 정보가 저장되는 위치 및 방법, CPU 레지스터 및 / 또는 메모리 함수 인수가 전달되는 위치)
  • 어떻게 프로그램 시작 / 초기화 작업 (어떤 데이터 형식가 "실행 파일"어떻게 코드 / 데이터가 어떻게 DLL을 작업에서로드하고있다 ...)

이에 대한 답변은 다음과 같습니다.

  • 언어 별 (따라서 C ABI, C ++ ABI, Fortran ABI, Pascal ABI, ... 심지어 실제 하드웨어 대신 "가상"프로세서를 대상으로하는 Java 바이트 코드 사양도 ABI입니다.)
  • 운영 체제 별 (동일한 하드웨어의 MS Windows 및 Linux는 다른 ABI를 사용함)
  • 하드웨어 / CPU 특정 (ARM 및 x86 ABI는 다름).
  • (오랜) 시간에 걸쳐 진화 (기존 ABI는 종종 업데이트 / 개선되어 새로운 CPU 기능을 사용할 수 있습니다. 예를 들어 앱에서 x86 SSE 레지스터를 사용하는 방법을 지정하는 것은 물론 한 번만 가능했습니다.) CPU 에는 이러한 규정이 있으므로 기존 ABI를 명확히해야합니다.)

따라서 ABI는 가장 중요한 구성 요소이며 그 구성 요소 중 하나 ( "하드웨어 / CPU 별"세부 정보)는 psABI입니다.

내 문제

내가 가진 문제는

  1. 나는 의미를 이해하지 않고 보편적으로 경고를 비활성화하는 것을 좋아하지 않습니다.
  2. " -Wno-psabi노트를 없애기 위해 사용"하는 조언은 컴파일러 업그레이드 후에 "갑자기 나타나는"이러한 유형의 진단 노트에 대한 매우 일반적인 조언 인 것 같습니다. [2] [3] [4] GCC 개발자 중 한 사람도이 작업을 제안합니다. [5]
  3. GCC 매뉴얼 에도 문서화되어 있지 -Wpsabi않습니다 [6] . [7]-Wno-psabi

결과적으로 정확히 무엇이 -Wno-psabi영향을 미치고 그렇지 않을지 확신 하지 못합니다. 관련 옵션 -Wabi 문서화되어 있습니다. [8]

-Wabi (C, Objective-C, C++ and Objective-C++ only)

G ++가 공급 업체 중립적 C ++ ABI와 호환되지 않는 코드를 생성 할 때 경고합니다.

또한 psABI 관련 변경 사항에 대해서도 경고합니다. 이 시점에서 알려진 psABI 변경 사항은 다음과 같습니다.

  • SysV / x86-64의 경우 long double 멤버가있는 공용체는 psABI에 지정된대로 메모리에 전달됩니다. 예를 들면 :

union U { long double ld; int i; };

union U 항상 메모리에 전달됩니다.

이 모든 것에 대한 나의 이해는

  1. -Wabi psABI 변경이있을 때 경고를 생성합니다.
  2. GCC 7 은 ARM 타겟에 영향을 미치는 GCC 5에 도입 된 ABI 버그 [9]를 수정했습니다 .
    • 릴리스 노트에는 "이것은 ABI 변경"이라고 명시되어 있습니다. [10]
    • 어떤 이유로 릴리스 노트에는 문서화 된 -Wpsabi것이 아니라 문서화되지 않은 것을 사용할 때 관련 진단 노트가 생성된다고 명시 되어 있습니다 -Wabi.
    • 이 ABI 변경은 매뉴얼에 언급되어 있지 않습니다.
  3. Putting together "this is an ABI change" and "use -Wpsabi", it appears to me this is specifically a psABI change, not a different kind of ABI change. (In reality it is a change in GCC's implementation of the psABI, not the psABI itself)

I know that documentation isn't always up to date, especially for something that is a known undocumented option. But my concern is that "use -Wno-psabi" seems to be the standard response for several different kinds of these cryptic diagnostic notes. But, in my basic understanding of ABIs, isn't an ABI change a big deal? Shouldn't I be concerned about an ABI change, rather than just making the message go away? Between the undocumented stuff and some of the finer details of ABI vs psABI, I'm not really sure...

For example, if I add -Wno-psabi to my makefile to make those notes go away, what if there is another ABI change in the future that does affect my project? Have I effectively silenced future warnings or notes that may be important?

Also, even though we are told "if you recompile all the code, there is nothing to worry about,"[5] what exactly is "all the code"? Is that my source code? glibc? Any other system-wide shared library I might be using?

References

  1. https://github.com/nlohmann/json
  2. https://github.com/nlohmann/json/issues/658
  3. https://stackoverflow.com/a/48149400
  4. https://stackoverflow.com/a/13915796/10270632
  5. https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html
  6. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81831
  7. https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc
  8. https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/C_002b_002b-Dialect-Options.html
  9. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728
  10. https://gcc.gnu.org/gcc-7/changes.html
  11. https://stackoverflow.com/a/8063350

You only need to worry about ABIs when you are crossing library boundaries. Within your own applications/libraries the ABI doesn't really matter as presumably all your object files are compiled with the same compiler version and switches.

If you have a library compiled with ABI1 and an application compiled with ABI2 then the application will crash when it tries to call functions from the library as it wont pass the arguments correctly. To fix the crash you would need to recompile the library (and any other libraries it depends on) with ABI2.

In your specific case as long as you compile nlohmann with the same compiler version as your application (or are just using nlohmann as a header) then you don't need to worry about the ABI change.

Globally suppressing the warning seems to be a dangerous option as it will prevent you from seeing any future ABI issues. A better option would be to use #pragma to disable the warning just for the functions in question, e.g.:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wno-psabi"
void foo()
{
}
#pragma GCC diagnostic pop

참고URL : https://stackoverflow.com/questions/52020305/what-exactly-does-gccs-wpsabi-option-do-what-are-the-implications-of-supressi

반응형