기존 .so 파일이 존재하더라도 로드할 수 없는 현상, Docker 호스트 OS에 종속적인 것으로 보입니다.

기존 .so 파일이 존재하더라도 로드할 수 없는 현상, Docker 호스트 OS에 종속적인 것으로 보입니다.

Alma8 기반 Docker 컨테이너에 Qt6을 구축했으며 Docker 호스트는 Fedora 35입니다.

어떤 경우에는(아래 설명) 모든 Qt 라이브러리가 로드되지 않습니다 libQt6Core.so[.6[.2.4]]. 그러나 파일이 존재하고 올바른 디렉토리에서 검색됩니다. libQt6Dbus.so예를 들어 다른 Qt 라이브러리를 찾아 로드합니다.

광범위한 디버깅, 재구축, 웹 검색을 통해 근본 원인이 무엇인지, 어떻게 해결할 수 있는지에 대한 단서를 얻지 못했습니다.

포지셔닝 문제

문제의 범위를 다음 시나리오로 좁혔습니다.

  • 나는 두 개의 최소 가상 머신을 만들었습니다. 하나는 centos7을 사용하고 다른 하나는 alma8을 사용했습니다.
  • 공식 저장소에서 Docker를 설치했습니다.
  • 두 가상 머신 모두에서 동일한 Docker 이미지를 실행하고 동일한 qt6 패키지를 설치하고 있습니다.
  • Docker 호스트가 centos7일 때 충돌이 발생했습니다.
  • Docker 호스트가 alma8일 때 작동합니다.

이론과 이슈

  • Qt6은 Alma8을 기반으로 구축되었으며 Centos7에서 제공하는 것보다 일부 최신 시스템 라이브러리에 연결되므로 Qt6은 Centos7에서 실행되지 않습니다(완전히 예상된 것이며 괜찮습니다). 하지만 그것은~해야 한다Alma8 Docker 컨테이너 내 어디에서나 실행하세요.
  • 컨테이너 이미지는 어디에서나 실행될 수 있어야 하지만 이 경우 호스트 OS의 "무언가"가 컨테이너에 몰래 들어가서 문제를 일으킬 수 있습니다. 두 컨테이너가 정확히 동일한 이미지를 사용하더라도 마찬가지입니다.

문제는 이 "사물"이 무엇이며 어떻게/왜 빌드를 중단시키는가입니다.

내가 시도한 것

libQt6Gui.so다음을 사용하여 로드할 수 있는지 libQt6Core.so, libQt6Core.so가짜로 보이는지 확인했습니다 .

  • ldd약간의 차이점이 있습니다 LD_DEBUG=libs ldd(아래 참조).
  • 자유의 나무아무런 차이도 보이지 않습니다(그러나 멋진 나무입니다 :))
  • pyldd(conda-build에서)
  • readelf -d

나는 또한 다음을 시도했습니다.

  • 설정 LD_LIBRARY_PATH(아무것도 변경하지 않았습니다. 올바른 경로가 항상 검색된다는 것을 알고 있으므로 놀라운 일이 아닙니다)
  • centos7 호스트가 있는 alma8 컨테이너에 Qt6 빌드(": 파일을 열 수 없습니다"로 빌드 실패 libQt6Core.so.6, 빌드된 라이브러리와 동일한 오류)
  • centos7 컨테이너에 Qt6 빌드(아직 수정할 수 없는 다른 문제로 인해 빌드가 실패함)

차이점은 다음과 같습니다.ldd

아래 스크린샷에서는 Centos7 호스트의 Alma8-Docker-Container를 볼 수 있습니다.왼쪽그리고 오른쪽 Alma8 호스트의 *Alma8-Docker-Container.

처음 두 이미지는 결과를 보여줍니다 ldd /opt/emsconda/lib/libQt6Gui.so. libQt6Core왼쪽에서는 찾을 수 없지만 오른쪽에서는 찾을 수 있습니다.

여기에 이미지 설명을 입력하세요.

두 번째 스크린샷은 다른 Qt 라이브러리를 보여줍니다.찾아서 로드하세요. 왼쪽의 ICU 라이브러리도 없습니다. 아마도 libQt6Core도 로드될 때만 로드되는 것일까요?

여기에 이미지 설명을 입력하세요.

이 스크린샷은 결과를 보여줍니다 LD_DEBUG=libs ldd .... 두 경우 모두 libQt6Core검색이 올바른 위치( /opt/emsconda/lib)에 있음을 알 수 있습니다. 하지만 올바른 컨테이너에만 로드할 수 있습니다. 또한 왼쪽의 `/opt/emsconda/lib/./를 확인하고(하하)) 조용히 다음 lib로 이동합니다...

오류 메시지를 찾을 수 없습니다. 파일이 열리지 않거나 로드되지 않습니다.

여기에 이미지 설명을 입력하세요.

이것 libQt6Core.so자체를 조사해 보면 단서를 얻을 수 있습니다. 이는 linux-vdso.so.1.

~에 따르면이 문제, 이 파일은 운영 체제 커널에 의해 사용자 공간에 주입된 가상 라이브러리입니다.

Docker 컨테이너는 자체 커널을 실행하지 않기 때문에 이 파일이 호스트 운영 체제에서 온 것으로 의심됩니다. 어쩌면 centos7 커널이 제공할 수 없는 일부 기능 libQt6Core에 의존할까요 ? linux-vdso.so.1나는 전혀 모른다 ... 여기에 이미지 설명을 입력하세요.


지금까지 시도한 어떤 것도 오류 메시지를 생성하지 않았기 때문에 실제 문제가 무엇인지, 디버깅 방법을 전혀 모릅니다. 귀하가 제공할 수 있는 팁, 요령 또는 도움을 주시면 감사하겠습니다.

답변1

질문에 답변되었습니다Qt 포럼에서.

요약:

  • .so필요한 최소 커널 버전을 나타내는 ABI 태그가 포함되어 있습니다 . 를 통해 이를 확인할 수 있습니다 objdump -s -j .note.ABI-tag libQt6Core.so.6.2.4. 결과는 마지막 세 블록( 내 경우에는 0x03 0x11 0x00-> 3.17.0)에 있습니다.
  • QT는 최신 커널에서만 작동하는 일부 시스템 호출을 사용하기 때문에 이 정보는 의도적으로 여기에 배치됩니다.
  • Glibc는 공유 객체를 로드할 때 이 정보를 읽고 이를 현재 커널 버전과 비교합니다. 일치하지 않는 경우 파일이 로드되지 않습니다.
  • Docker에는 자체 커널이 없으므로 Docker 호스트의 커널 버전이 비교에 사용됩니다. 따라서 Docker 이미지가 Alma8이더라도 제 경우 커널은 여전히 ​​Centos7 호스트의 이전 v3.10.0입니다.
  • 당신은 그것을 사용할 수 있습니다 strip --remove-section=.note.ABI-tag libQt6Core.so.6.2.4. Qt에는 대체 코드가 있는 것 같으므로 문제가 없어야 합니다.

원천:https://github.com/Microsoft/WSL/issues/3023

관련 정보