1. 程式人生 > >關於linux裝載器(如何解決應用程式跑不起來not found等問題)

關於linux裝載器(如何解決應用程式跑不起來not found等問題)

關於linux動態連結共享庫(如何解決應用程式跑不起來not found等問題)

所謂linux中的Share Libraries和Dynamic linking扮演的角色類似Windows 中的dll檔案一樣。現在的OS作業系統中,大部分的程式都是動態連結的,就是說,很多程式在編譯成可執行程式時,會共享一些庫。這樣會帶來至少一個好處:應用程式可以減小自己的體積,對於各種各樣的應用程式中的OS來說,可以大大減少很多儲存空間了。

        Linux中存在兩種庫型別。 
1.一種稱之為靜態庫。以.a 字尾。這種庫本身在編譯成目標檔案的時候是和應用程式連結在一起的,所以編譯出來的應用程式相對較大。

2.第二種稱之為動態連結共享庫。 以.so為字尾。雖然這種庫形式只有一種,但是在使用中可以有兩種形式:
a.執行(runtime)時動態連結,共享庫在編譯器編譯時被連結,但並沒有包括在應用程式中(目標程式中),只在執行時連結。而且是必要的,如果沒有共享庫,程式將跑不起來。
b.執行中使用動態連結裝載器中的函式來進行動態的載入、解除安裝或者連結。如瀏覽器使用中裝載的各種外掛。


        我們知道Linux中的執行檔案使用的一種叫做ELF格式來表示。這是一種特殊的二進位制格式式。 ELF = Executable and Linkable Format,可執行連結格式,是UNIX系統實驗室(USL)作為應用程式二進位制介面(Application Binary Interface,ABI)而開發和釋出的。副檔名為elf。工具介面標準委員會(TIS)選擇了正在發展中的ELF標準作為工作在32位INTEL體系上不同作業系統之間可移植的二進位制檔案格式。

在移植的linux中經常碰到自己移植的檔案系統上經常會碰到,應用程式跑不起來,通常出現類似這樣的錯誤:
-/bin/sh: xxx not found. 
或者
xxx: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
如果檔案系統已經移植好,能正常使用其他應用程式。那顯然是應用程式缺少了相關的庫了。一句話就是共享庫或動態連結出現了問題。


        我們知道一個程式要想在記憶體中執行,除了編譯之外還要經過連結和裝入這兩個步驟。當然linux中動態連結也是經過這三個過程。Linux 使用這個ld-linux.so*(我的平臺是使用ld-linux.so6)中的來裝載(其實這只是一個連結)其他庫。所以這個庫必須放在linux中/lib下。對於其他,通常我們共享庫放在/lib這個路徑下,而且也是系統預設的搜尋路徑。

Linux共享庫的搜尋路徑先後順序:
1、編譯目的碼時指定的動態庫搜尋路徑:在編譯的時候指定-Wl,-rpath=路徑
2、環境變數LD_LIBRARY_PATH指定的動態庫搜尋路徑
3、配置檔案/etc/ld.so.conf中指定的動態庫搜尋路徑
4、預設的動態庫搜尋路徑/lib
5、預設的動態庫搜尋路徑 /usr/lib

解決思路:

#readelf -a <檔案>

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00008034 0x00008034 0x000c0 0x000c0 R E 0x4
  INTERP         0x0000f4 0x000080f4 0x000080f4 0x00013 0x00013 R   0x1
     
[Requesting program interpreter: /lib/ld-linux.so.3]
  LOAD           0x000000 0x00008000 0x00008000 0x0049c 0x0049c R E 0x8000
  LOAD           0x00049c 0x0001049c 0x0001049c 0x000ec 0x00108 RW  0x8000
  DYNAMIC        0x0004a8 0x000104a8 0x000104a8 0x000c0 0x000c0 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4

發現程式預設使用[Requesting program interpreter: /lib/ld-linux.so.3]作為聯結器,但是發現/lib目錄下面並沒有相關檔案,所以無法裝在執行檔案

#man gcc

-muclibc
           Use uClibc instead of the GNU C library.  This is the default on *-*-linux-*uclibc* targets.

發現如果不加-muclibc這條命令的話,編譯器預設是尋找GUN 的c library

於是在編譯是加上了-muclibc

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00008034 0x00008034 0x000c0 0x000c0 R E 0x4
  INTERP         0x0000f4 0x000080f4 0x000080f4 0x00013 0x00013 R   0x1
[Requesting program interpreter: /lib/ld-uClibc.so.0]
  LOAD           0x000000 0x00008000 0x00008000 0x0049c 0x0049c R E 0x8000
  LOAD           0x00049c 0x0001049c 0x0001049c 0x000ec 0x00108 RW  0x8000
  DYNAMIC        0x0004a8 0x000104a8 0x000104a8 0x000c0 0x000c0 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4

發現裝載器終於變成了[Requesting program interpreter: /lib/ld-uClibc.so.0]

執行編譯檔案,成功!!!!

那麼為什麼當前gcc預設會指向/lib/ld-linux.so.3檔案呢?

#arm-linux-gcc -dumpspecs >`arm-linux-gcc -print-libgcc-file-name `/specs

#vi specs

發現link中

*link:
%{!static:--eh-frame-hdr} %{h*} %{version:-v}    %{b}    %{static:-Bstatic}    %{shared:-shared}    %{symbolic:-Bsymbolic}    %{rdynamic:-export-dynamic}    %{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc and -muclibc used together}/lib/ld-uClibc.so.0;:/lib/ld-linux.so.3}}    -X    %{mbig-endian:-EB} %{mlittle-endian:-EL} -m armelf_linux_eabi

包含/lib/ld-linux.so.3資訊,好的,我們幹掉他,替換成自己喜歡的吧,神馬?不會修改?請參閱:http://blog.csdn.net/dragon101788/article/details/17509987

參考解決的思路,首先要卻定自己編譯的程式是否編譯於目標平臺的以及相關的資訊然後設定好動連結共享庫環境。結合例子helloarm程式。

[email protected]:~/mylinux$ file helloarm
helloarm: ELF 32-bit LSB>
Data>Description
  GNU0x00000010NT_GNU_ABI_TAG (ABI version tag)
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "4T"
  Tag_CPU_arch: v4T
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_enum_size: int
        從以上可以看出helloarm程式的目標平臺是ARMv4T,而且已經使用動態連結共享庫。
檢視應用程式所需要的庫:
[email protected]:~/mylinux$ readelf -d helloarm |grep NEEDED


Dynamic section at offset 0x5a8 contains 25 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
  …

        所需要的庫檔案分別是: libgcc_s.so.1和libc.so.6
        所以,最後我們將ld-linux-so6、libgcc_s.so.1、libc.so.6直接放到預設中/lib下面即可。當然也可以可以在/etc下新建ld.so.conf類似這樣:
#/etc/ld.so.conf
/usr/X11R6/lib
/usr/lib
...
..
/usr/lib/sane
/usr/lib/mysql
/opt/lib



        或者通過export LD_LIBRARY_PATH=路徑:$LD_LIBRARY_PATHLl來自定義。
設定好之後,你的應用程式就可以跑起來了。He~
[[email protected] /]# ls
bin         helloarm    linuxrc     proc        sys         var
dev         home        lost+found  root        tmp
etc         lib         mnt         sbin        usr
[[email protected] /]# ./helloarm
Hello arm !
I am running on GNU/linux !
Bye-Bye!
[[email protected] /]#

相關推薦

關於linux裝載(如何解決應用程式起來not found問題)

關於linux動態連結共享庫(如何解決應用程式跑不起來not found等問題) 所謂linux中的Share Libraries和Dynamic linking扮演的角色類似Windows 中的dll檔案一樣。現在的OS作業系統中,大部分的程式都是動態連結的,就是說,很

解決"應用程式配置正確,程式無法啟動"

“D:\Program Files\Tencent\QQ\Bin\QQ.exe”的啟用上下文生成失敗。 找不到從屬程式集 Microsoft.VC80.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18

Linux應用程式到存在的庫(.so/.a)的解決方法

各種各樣的環境變數控制著一些關鍵的過程。例如你可以臨時為你特定的程式的一次執行指定一個不同的函式庫。Linux系統中,通常變數LD_LIBRARY_PATH就是可以用來指定函式庫查詢路徑的,而且這個路徑通常是在查詢標準的路徑之前查詢。這個是很有用的,特別是在除錯一個新的函式庫

解決應用程式錯誤,記憶體能為“read”或“written”

記憶體不能為“read”或“written”的解決方案  有些人執行飈車程式的時候會彈出該記憶體不能為“read”的錯誤提示。希望以下文章能對大家有所幫助。  使用Windows作業系統的人有時會遇到這樣的錯誤資訊,執行某些程式的時候,有時會出現記憶體錯誤的提示,然後該程式會自動

“由於應用程式配置正確,應用程式未啟動。重新安裝應用程式可能會糾正這個問題。”解決思路

     上位機除錯時,解決方案配置可選Debug或者Release模式,在Debug模式下生成的exe檔案放在其它電腦上執行會報錯,在XP系統下執行提示“由於應用程式配置不正確,應用程式未啟動。重新安裝應用程式可能會糾正這個問題。”如果在該電腦上安裝VS2008後

Linux定時在驅動程式中的應用

        核心提供了一組與定時器相關的介面用來簡化管理定時器的操作。所有這些介面都宣告在<linux/Timer.h>中,大多數介面在<kernel/timer.c>中的到實現。   建立定時器首先要先定義它,然後通過一個輔助函式

U 盤全新安裝 Mac OS X 提示【這個“安裝 OS X ……”應用程式副本能驗證】的解決方法

如果網路好,也嫌如下安裝是 10.10 系統,可以使用 option + R 進行網路恢復。不過好像大部分人都會死於半路…… 如果 OS X 系統廢了,需要重新安裝,則在另一臺 Windows 系統上用 TransMac 製作啟動盤 在製作好了以後,按住

一種解決執行程式報“應用程式配置正確”的問題

      在我們開發工程中,可能有些情況下,不能在本機進行除錯。這個時候我們一般會使用VM(vmware)建立一個虛擬機器環境,然後把編譯過的程式放在該虛擬機器環境下執行除錯。可是在某些情況下,不管我們編譯的是debug還是release版本,在虛擬機器環境中都會報“由

解決"應用程式無法啟動,因為應用程式的並行配置正確"問題

解決"應用程式無法啟動,因為應用程式的並行配置不正確"問題 在使用中科院中文分詞ICTCLAS50_Windows_32_C時,執行其中的Demo,出現錯誤,顯示如下: 這是因為要開啟的程式是在Windows32下開發的,而我的系統是Win7(64位),由於使用的平臺不一

VS2008釋出程式_應用程式配置正確的解決

下列附有VS2008釋出程式介紹: vc2008程式釋出指南2008-05-03 17:46vc2008開發的程式的釋出方式可以有5種方式: 1. 採用靜態連結到crt和MFC. 只要你擁有組成程式的所有原始碼,你就可以採用這種方式, 這種方式除了程式變大一點,好處多多: 1) 不必重新發布vc2008基

應用程式配置正確,應用程式未能啟動” 錯誤的解決

一、問題描述 今天在虛擬機器上裝了XP系統,但執行一個win32 Console程式時彈出對話方塊: “由於應用程式配置不正確,應用程式未能啟動。重新安裝應用程式可能會糾正這個問題” 在英文os上: This application has failed to star

如何解決"應用程式無法啟動,因為應用程式的並行配置正確"問題

文章1,轉載自:http://jingyan.baidu.com/article/cdddd41c620e3d53cb00e11c.html 文章2,轉載自:http://blog.sina.com.cn/s/blog_705b14b30100p4la.html 前言:

解決VB可執行程式啟動錯誤: "應用程式配置正確,應用程式未能啟動"

最近VB編譯後的exe程式執行時候會報告錯誤:"由於應用程式配置不正確,應用程式未能啟動。重新安裝應用程式可能會糾正這個問題。"  之後便結束了. 我在檢視系統日誌後發現下圖資訊:   日誌資訊1: "Generate Activation Context 為 C:/spp工

如何解決應用程式無法啟動,因為應用程式的並行配置正確?

當遇到應用程式打不開時,提示報錯“應用程式無法啟動,因為應用程式的並行配置不正確”,該類問題大部分原因為缺少c++執行庫。 解決方法: 利用sxstrace跟蹤除錯應用程式執行時需要的動態庫的版本和路徑。 步驟: 1.利用管理員身份執行命令提示視窗 2.輸入sx

linux系統下解決getch()輸入數值回顯示

continue pan not while image png bsp log main 在linux系統下開發C 程序卻會遇到系統不支持conio.h頭文件,無法使用getch()不回顯函數。下面就演示如何構建函數實現數值輸入不回顯。 1 #includ

Linux下,為應用程式新增桌面圖示(ubuntu18.4)

一、桌面圖示位置 Lniux下桌面圖示儲存路徑為:/usr/share/applications   二、桌面圖示格式 所有桌面圖示格式均為desktop,即名為XXX.desktop   三、編輯內容(常用) // 檔案頭(必須) [Desktop Entry] /

如何安裝和使用Wine,以便在Linux上執行Windows應用程式

如何安裝和使用Wine,以便在Linux上執行Windows應用程式  我來答 分享 舉報 瀏覽 2150 次 1個回答 #不想上班# 今天上班,你最想說點啥? 最佳答案 cincoutvc 來自電腦網路類芝麻團 2017-10-19 在Linux上執行Windows程式需要安裝Wine,

解決Mybatis @Mapper 介面名字衝突導致springboot程式啟動起來的問題

有兩個同名的Mapper: package com.clear.ims4.business.material.program.layout; @Mapper public interface LayoutRepository { }   package com.clear

執行VS編譯的程式提示“由於應用程式配置正確,應用程式未能啟動”的問題

造成這個問題的原因是,執行這個程式的電腦並沒有安裝vs,從而缺少了一些dll檔案。 以vs2008為例,將下面這幾個檔案拷貝到工程生成的輸出目錄中即可 我的這些檔案的路徑是C:\Program Files (x86)\Microsoft Visual Stud

linux I2C讀寫應用程式

本文程式碼參考ZFZF294990051 童鞋的程式碼,非常感謝ZFZF294990051童鞋。 參考地址:http://blog.csdn.net/zfzf294990051/article/details/17322621 #include <stdio.h>