ldd cho tôi biết ứng dụng của tôi là không phải là một chương trình thực thi động


17

Tôi có một ứng dụng 32 bit (được gọi là uclsyn) tôi nhận được từ một giáo sư thiên văn học. Tôi đã quản lý để nó chạy trên CentOS một năm trước, nhưng bây giờ khi tôi thiết lập một máy ảo CentOS mới, nó sẽ không chạy và tôi không thể hiểu tại sao. Nó tiếp tục trở lại với "Bị giết".

Đây là trao đổi trên dòng lệnh:

$ ./uclsyn_linux
Killed

$ ldd ./uclsyn_linux
not a dynamic executable

$ file ./uclsyn_linux
uclsyn_linux: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

Trên máy không chạy, "ldd ./uclsyn_linux" trả về toàn bộ danh sách các phụ thuộc. Tôi đã tìm thấy các gói cung cấp các thư viện dùng chung này và tất cả chúng dường như được cài đặt.

Gói yêu cầu

  • libSM-1.1.0-7.1.el6.i686
  • libX11-1.3-2.el6.i686
  • libgcc-4.4.6-3.el6.i386
  • glibc-2.12-1.47.el6_2.9.i686
  • libuuid-2.17.2-12.4.el6.i686
  • libXau-1.0.5-1.el6.i686
  • Ngoài ra còn có một đống thư viện cục bộ cho ứng dụng mà tôi đã kiểm tra và đã được cài đặt.

Môi trường của tôi

CentOS chạy dưới VirtualBox

uname -a: Linux localhost.localdomain 2.6.32-358.el6.i686 # 1 SMP Thu 21 tháng 2 12:50:49 UTC 2013 i686 i686 i386 GNU / Linux


1
đoán mò: bạn đang cố chạy nhị phân 32 bit trên HĐH 64 bit mà không cài đặt thư viện 32 bit.
michas

Nó là tệp nhị phân 32 bit, nhưng HĐH tôi cài đặt là phiên bản 32 bit của CentOS. Ít nhất đó là những gì uname-một lệnh cho tôi biết có?
Carl

3
@Carl Vì tò mò, strace ./uclsynđầu ra làm gì? Điều đó có thể cho chúng ta một gợi ý về những gì còn thiếu đầu tiên.
lgeorget

@lgeorget, Nó trả về: execve ("./ uclsyn_linux", ["./uclsyn_linux"], [/ * 56 vars * /] <chưa hoàn thành ...> +++ bị giết bởi SIGKILL +++
Carl

@Carl Ok, vì vậy nó thậm chí không đi đến điểm mà nó cố tải một số thư viện. Tôi chưa bao giờ thử trước stracemột chương trình không được liên kết chính xác.
lgeorget

Câu trả lời:


13

Tôi chỉ gặp vấn đề với nhị phân 32 bit, giải pháp là:

apt-get install gcc-multilib

$ uname -a
Linux bla 2.6.32-028stab094.3 #1 SMP Thu Sep 22 12:47:37 MSD 2011 x86_64 GNU/Linux

3
Làm thế nào bạn tìm thấy lib đó bị mất?
yehudahs

1
Giải pháp này đã làm việc cho tôi. +1
FractalSpace

@yehudahs Tôi đã chạy rất nhiều ứng dụng 32 bit được biên dịch sẵn trên Linux trong một thời gian cộng với Reverse Engineering chúng, vì vậy tôi đã thu thập được một số kinh nghiệm chụp ảnh rắc rối. : D
lama12345

1
thật tuyệt vì điều này đã làm việc cho tôi cũng như tôi đã gãi đầu về những gì tôi đã làm sai
Marvin Effing

1
Cũng hoạt động với tôi: ldd đã không tìm thấy thứ gì trong khi nó hoạt động ^^
jy95

8

Lỗi ở đây là do không có đủ RAM trên VirtualMachine. Chạy strace ./programnamechỉ ra rằng chương trình đã bị giết ngay khi nó bắt đầu chạy, trước khi tải bất kỳ thư viện nào. Việc tăng dung lượng RAM có sẵn đảm bảo chương trình có thể hoạt động.

Phản hồi hữu ích

Có một số phản hồi hữu ích từ những người khác là @slm, người đã cung cấp các lệnh hữu ích để kiểm tra xem mỗi thư viện có tồn tại không và @lgeorget, người đề xuất thử stracelệnh.


5

Bạn có thể đăng một số thư viện mà nó liên kết đến (từ hệ thống ban đầu) không? Bạn có thể chỉ cần cài đặt một số thư viện bị thiếu.

Thông thường trên hệ thống CentOS, vấn đề chỉ là chạy lệnh yum như vậy:

yum install <package name>

Bạn có thể làm việc ngược từ hệ thống ban đầu như vậy:

$ ldd /bin/ls
    linux-vdso.so.1 =>  (0x00007fff519ff000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00000034e8e00000)
    librt.so.1 => /lib64/librt.so.1 (0x00000034e8a00000)
    libcap.so.2 => /lib64/libcap.so.2 (0x0000003d6fe00000)
    libacl.so.1 => /lib64/libacl.so.1 (0x00000034fae00000)
    libc.so.6 => /lib64/libc.so.6 (0x00000034e7200000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00000034e7a00000)
    /lib64/ld-linux-x86-64.so.2 (0x00000034e6e00000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00000034e7e00000)
    libattr.so.1 => /lib64/libattr.so.1 (0x00000034f7600000)

Trong đầu ra đó, bạn có thể thấy nơi bản sao của tôi /bin/lsđang chọn các thư viện .so được chia sẻ để lấy ví dụ librt.so.1, điều này xảy ra ở đây : /lib64/librt.so.1.

Biết điều này, trên hệ thống ban đầu, bạn có thể chạy lệnh này để tìm ra gói nào cung cấp thư viện này:

$ rpm -qf /lib64/librt.so.1
glibc-2.13-2.x86_64

Vì vậy, gói được gọi glibc-2.13-2.x86_64. Vì vậy, để cài đặt nó, bạn sẽ làm điều này:

$ sudo yum install glibc-2.13-2.x86_64

Cảm ơn rất nhiều vì sự giúp đỡ. Tôi đang tiến xa hơn. Đã cập nhật câu hỏi của tôi với một số thông tin thêm bây giờ, nếu bạn muốn cập nhật câu trả lời của mình với điều tương tự, nó sẽ được đánh giá cao. :)
Carl

Bạn đã có yum install <package>những gói mà bạn tham chiếu trong câu hỏi của bạn?
slm

Có tôi đã làm. Tất cả chúng đều được cài đặt ngoại trừ libuuid.i686, nhưng tôi vẫn gặp vấn đề tương tự.
Carl

2

Câu trả lời nằm trong câu hỏi của bạn: bạn thử chạy một ứng dụng được biên dịch cho GNU / Linux một năm trước và bạn thử chạy nó với các thư viện mới, có thể không tương thích hoặc có sẵn nữa.

Tại thời điểm này, bạn có hai lựa chọn. Nếu bạn có thể biên dịch lại nó (điều mà tôi nghi ngờ, nếu tôi hiểu rõ trường hợp của bạn), nó sẽ chạy vì nó sẽ được gửi lại với các thư viện tương thích. Mặt khác, bạn có thể thử xây dựng một loại hộp cát, một VM chạy với phiên bản cũ của các thư viện GNU, để chạy ứng dụng.


1
Điều này LAF không đúng. Chương trình được liên kết tĩnh, không có thư viện nào trên hệ thống máy chủ sẽ được tham chiếu. Mặc dù ABI vẫn có thể gây ra sự không tương thích, nhưng không thể xảy ra giữa các vòng quay nhỏ của hạt nhân linux (giả sử có cùng kiến ​​trúc).
ckhan

1
Nó không được liên kết tĩnh, xem đầu ra từ file. Và các thông báo như No package xyz foundgợi ý rằng các thư viện cần thiết không còn nữa (ít nhất, không phải như vậy, trong cùng một gói). Đó là lý do tại sao tôi khuyên bạn nên xây dựng lại chương trình, nếu có thể hoặc chạy nó trong một hệ thống mà nó được biết là hoạt động với các thư viện cũ.
lgeorget

Thật không may, biên dịch lại không phải là một lựa chọn ở đây. Tôi đã nhận được nó chạy trên một hệ thống khác giống như cách tôi đang thử ở đây, nhưng vì một số lý do, lần này nó không thích nó.
Carl

Cái này sai. Thay đổi địa chỉ hoàn toàn không thành vấn đề. Các chức năng bị loại bỏ hoặc các ngắt ABI khác xảy ra tại các phiên bản chính của thư viện (rất hiếm), trong trường hợp đó, bạn sẽ gặp lỗi khi tải libfoo2 nếu bạn chưa cài đặt libfoo2, cho dù bạn có cài đặt libfoo3 hay không.
psusi

OK biết được là tốt rồi. Tôi nghĩ rằng bất kỳ thay đổi trong một thư viện có thể phá vỡ liên kết. Tôi hiện đang điều hành một gentoo và tôi thường phải biên dịch lại các phụ thuộc ngược khi tôi nâng cấp thư viện, vì vậy tôi không nghĩ rằng liên kết có khả năng chống lại sự thay đổi của thư viện.
lgeorget

0

thử readelf -l uclsyn_linux Yêu cầu thông dịch viên chương trình sẽ cho bạn biết những gì bạn thiếu.


1
Tôi đã chạy đua readelf -l <file>với một tệp có cùng lddhành vi ( not a dynamic executable), nhưng tôi không thấy bất cứ điều gì ngay lập tức chỉ ra một thư viện bị thiếu. Tôi thấy Elf file type is EXEC (Executable file), Entry point, Program HeadersSection to Segment mapping. Chính xác những gì tôi nên tìm kiếm trong đầu ra?
StockB

0

Trong Arch Linux , nếu tệp là elf 32 bit, bạn có thể cài đặt lib32-gcc-libs (từ kho lưu trữ multilib) để giải quyết vấn đề.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.