嵌入式Linux 执行程序时提示:-sh: No such file or directory

嵌入式Linux 执行程序时提示:-sh: No such file or directory

进行嵌入式Linux开发时,经常会遇到编译好的可执行程序在目标板无法运行的情况,在这里整理一下问题产生的几种原因:

  • 文件不存在
  • 程序无法执行

文件不存在

有时候可能真的是文件名或者路径名写错了,所以先使用ls命令确认一下文件是否存在。

程序不可执行

嵌入式的编译环境一般都不在目标板中进行,多是在PC主机上进行的,如果编译环境与运行环境存在差异,那么必然会导致编译出的程序无法在目标板运行。
我的做法是,先编译一个helloworld,再从目标板上取一个可以执行的程序,使用filereadelf命令分别查看,编译出的可执行程序与目标平台上的程序信息。

file命令重点确认程序是32位还是64位、指令集是什么:

$ file helloworld
ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, not stripped

readelf命令也可以查看程序位数:

$ readelf -h helloworld
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2’s complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x8414
Start of program headers: 52 (bytes into file)
Start of section headers: 2320 (bytes into file)
Flags: 0x5000002, has entry point, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 26

readelf也可以查看程序所使用的动态库有哪些(这里的helloworld只使用了c库):

$ readelf -d helloworld
Dynamic section at offset 0x660 contains 24 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x8370
0x0000000d (FINI) 0x8610
0x00000019 (INIT_ARRAY) 0x10654
0x0000001b (INIT_ARRAYSZ) 4 (bytes)
0x0000001a (FINI_ARRAY) 0x10658
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x00000004 (HASH) 0x8168
0x00000005 (STRTAB) 0x826c
0x00000006 (SYMTAB) 0x81ac
0x0000000a (STRSZ) 107 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x10748
0x00000002 (PLTRELSZ) 88 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x8318
0x00000011 (REL) 0x8310
0x00000012 (RELSZ) 8 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x82f0
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0x82d8
0x00000000 (NULL) 0x0

还要使用readelf重点确认程序使用的装载器(dynamic linker/loader、interpreter,man ld.so查看详细说明)是什么:

$ readelf -l helloworld | grep interpreter
[Requesting program interpreter: /lib/ld-linux.so.3]

如果在目标板上相应的目录下,没有这个库文件,那么也会出现程序无法运行,提示:“No such file or directory”。
出现这种情况,说明使用的交叉编译工具不正确,或者版本不匹配,最好的解决办法是更换交叉编译环境到正确的版本。

这里也有两个临时的办法,可以尝试一下是否可行:

在目标板上做一个链接,指向目标板的装载器/lib/ld-x.xx.so

$ ln -s /lib/ld-x.xx.so /lib/ld-linux.so.3

编译程序时,加入-static选项静态链接程序,即不使用动态库。

你可能感兴趣的:(程序编译及运行)