it-swarm-vi.com

Nhận thông báo "Không tìm thấy" khi chạy nhị phân 32 bit trên hệ thống 64 bit

Tôi hiện đang có một vấn đề kỳ lạ trên debian (wheezy/AMD64).

Tôi đã tạo một chroot để cài đặt một máy chủ (tôi không thể cung cấp thêm chi tiết về nó, xin lỗi). Hãy gọi đường dẫn của nó /chr_path/. Để làm cho mọi thứ dễ dàng, tôi đã khởi tạo chroot này bằng một debootstrap (cũng là wheezy/AMD64).

Tất cả dường như hoạt động tốt bên trong chroot nhưng khi tôi khởi động tập lệnh cài đặt của máy chủ thì tôi nhận được: zsh: Not found /some_path/Perl (trình cài đặt bao gồm nhị phân Perl vì một số lý do)

Tự nhiên, tôi kiểm tra /some_path/ location và tôi tìm thấy nhị phân "Perl". file trong môi trường chroot trả về:

/some_path/Perl ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

Các tập tin tồn tại, có vẻ ok, có quyền chính xác. Tôi có thể sử dụng file, ls, vim trên đó nhưng ngay khi tôi cố gắng thực hiện nó - ./Perl chẳng hạn - Tôi nhận được: zsh: Not found ./Perl.

Tình huống này khá dễ hiểu đối với tôi. Hơn thế nữa :

  • Tôi có thể thực thi các nhị phân cơ bản khác (/ bin/ls, ...) trong chroot mà không gặp lỗi
  • Tôi có vấn đề tương tự cho các nhị phân khác đi kèm với dự án
  • Khi tôi cố gắng thực thi nhị phân từ gốc chính (/chr_path/some_path/Perl), nó hoạt động.
  • Tôi đã cố gắng đặt một trong các tệp nhị phân có bản sao ls của tôi. Tôi đã kiểm tra rằng các quyền truy cập là như nhau nhưng điều này không thay đổi bất cứ điều gì (một cái đang hoạt động và cái kia thì không)
72
Elenaher

Khi bạn không thực thi được một tệp phụ thuộc vào một trình tải của bộ dữ liệu, thì lỗi bạn gặp có thể liên quan đến trình tải hơn là tệp bạn đang thực thi.

  • Trình tải của tệp thực thi gốc được liên kết động là một phần của hệ thống chịu trách nhiệm tải các thư viện động. Nó giống như /lib/ld.so hoặc là /lib/ld-linux.so.2, và phải là một tập tin thực thi.
  • Trình tải của tập lệnh là chương trình được đề cập trên dòng Shebang, ví dụ: /bin/sh cho tập lệnh bắt đầu bằng #!/bin/sh. (Bash và zsh đưa ra một thông điệp, người phiên dịch xấu, người thay vì lệnh không tìm thấy trong trường hợp này.

Thông báo lỗi khá sai lệch khi không chỉ ra rằng trình tải là vấn đề. Thật không may, việc sửa lỗi này sẽ khó khăn vì giao diện kernel chỉ có chỗ để báo cáo mã lỗi số, không phải cũng chỉ ra rằng lỗi trong thực tế liên quan đến một tệp khác. Một số shell tự thực hiện công việc cho các tập lệnh (đọc #! dòng trên tập lệnh và xử lý lại tình trạng lỗi), nhưng không có cái nào tôi thấy cố gắng làm tương tự cho các nhị phân gốc.

ldd sẽ không hoạt động trên các nhị phân vì nó hoạt động bằng cách đặt một số biến môi trường đặc biệt và sau đó chạy chương trình, để trình tải thực hiện công việc. strace sẽ không cung cấp bất kỳ thông tin có ý nghĩa nào, vì nó sẽ không báo cáo nhiều hơn những gì kernel báo cáo, và như chúng ta đã thấy kernel không thể báo cáo mọi thứ mà nó biết.

Tình huống này thường phát sinh khi bạn cố chạy một hệ nhị phân cho đúng hệ thống (hoặc họ hệ thống) và siêu kiến ​​trúc nhưng kiến ​​trúc phụ sai. Ở đây bạn có các nhị phân ELF trên một hệ thống mong đợi các nhị phân ELF, vì vậy kernel tải chúng tốt. Chúng là các nhị phân i386 chạy trên bộ xử lý x86_64, vì vậy các hướng dẫn có ý nghĩa và đưa chương trình đến điểm mà nó có thể tìm kiếm trình tải của nó. Nhưng chương trình là chương trình 32 bit (như đầu ra file chỉ ra), tìm kiếm trình tải 32 bit /lib/ld-linux.so.2 và có lẽ bạn chỉ cài đặt trình tải 64 bit /lib64/ld-linux-x86-64.so.2 trong chroot.

Bạn cần cài đặt hệ thống thời gian chạy 32 bit trong chroot: trình tải và tất cả các thư viện mà các chương trình cần. Từ Debian wheezy trở đi, nếu bạn muốn hỗ trợ cả i386 và x86_64, hãy bắt đầu với cài đặt AMD64 và kích hoạt multiarch support: run dpkg --add-architecture i386 sau đó apt-get updateapt-get install libc6:i386 zlib1g:i386 … (nếu bạn muốn tạo danh sách các phụ thuộc của gói Perl của Debian, để xem thư viện nào có khả năng cần thiết, bạn có thể sử dụng aptitude search -F %p '~Rdepends:^Perl$ ~ri386'). Bạn có thể lấy một bộ sưu tập các thư viện phổ biến bằng cách cài đặt ia32-libs gói (trước tiên bạn cần bật hỗ trợ multiarch). Trên Debian AMD64 trở nên khò khè, trình tải 32 bit nằm trong libc6-i386 gói. Bạn có thể cài đặt một bộ thư viện 32 bit lớn hơn bằng cách cài đặt ia32-libs .

Chạy ldd(1) trên nhị phân Perl của bạn. Thường thì có vẻ khó hiểu Not found lỗi trên một tệp rõ ràng là do một trong những thư viện chia sẻ được sử dụng bởi chương trình không được tìm thấy.

Vì vậy, có thể là chroot của bạn không đầy đủ đối với các thư viện chia sẻ cần thiết bởi các nhị phân của bạn.

5
camh