【问题标题】:Cannot execute binary file on CentOS amd64无法在 CentOS amd64 上执行二进制文件
【发布时间】:2019-07-25 16:36:29
【问题描述】:

我正在尝试在 CentOS 上运行一个简单的程序。

程序:

using System;
namespace helloworld
{
    class Program
    {
         static void Main(string[] args)
         {
            Console.WriteLine("Hello World!");
            returnHello();
         }
         static string returnHello()
         {
            return "hwdy ha";
         }
     }
}

我的发布设置是:

  1. 配置: Release|Any CPU
  2. 目标框架: netcoreapp2.1
  3. 部署模式:自包含
  4. 目标运行时: linux-x64
  5. 目标位置: bin\Release\netcoreapp2.1\publish\

在我运行的终端中

dotnet publish --self-contained -r linux-x64 -c release

然后将文件夹 \publish 复制到我的 CentOS 机器上。

使用文件 helloworld,我看到了文件详细信息:

ELF 64 位 LSB 可执行文件,x86-64,版本 1(SYSV),动态链接 (使用共享库),对于 GNU/linux.2.6.32, BuildID[sha1]=0x22d087f79061d441f9f6d007bf336f380c1214db,剥离

使用 uname -r:

3.2.0-3-amd64

在 CentOS 中,我进入发布文件夹并运行:bash helloworld。作为回应,我得到 ​​p>

helloworld: 无法执行二进制文件

.

我不确定我在这里缺少什么,对我来说,该文件似乎针对正确的操作系统,但我无法在 CentOS 中执行该文件。任何帮助表示赞赏。谢谢

【问题讨论】:

  • 你试过 CPU ANY 了吗?
  • 是的,很抱歉我错过了写这篇文章。
  • 这是什么版本的 CentOS? 6?
  • @OmairMajid,当我运行“uname -or”时,我得到 3.2.0-3-amd64 GNU/Linux。我不完全确定它是否是 6。
  • 试试cat /etc/*-release

标签: c# linux bash .net-core x86-64


【解决方案1】:

TLDR:您需要为 .NET Core 切换到更新的操作系统,例如 CentOS 7 或 Debian 9。

首先,根据/etc/*release 输出,您使用的是Debian wheezy(又名Debian 7)。有几点需要注意:这是 2013 年发布的,2016 年停产。换句话说,您使用的操作系统不再被任何人支持。 .NET Core 不支持它。 Debian 本身不支持它。 (CentOS 肯定不支持)

其次,.NET Core 的每个版本都有一个它支持的平台(和特定版本的平台)列表。这些平台的旧版本缺乏功能、兼容性或其他使 .NET Core 不适合在那里运行的东西。

.NET Core 2.1 supports these operating systems。对于 Debian,它只支持 Debian 9 (我认为,它们发布后的更高版本)。

由于 .NET Core 支持 Debian 9,它利用了 C 库 (glibc) 中的许多功能,这些功能需要最新版本的 glibc。 Debian 7 没有最新版本的 glibc,因此无法运行 .NET Core 2.1 应用程序。

您应该尝试更新版本的 Debian、CentOS 或其他一些 Linux 发行版。我知道 .NET Core 2.1 在 RHEL(以及 CentOS 的扩展)上运行良好。它应该也适用于最新版本的 Debian 和 Ubuntu。

有几种方法可以修改 .NET Core 并解决此错误,但它相当先进,并且会导致您无法更新到 .NET Core 的新版本,所以我不推荐它:您可以引导 .NET Core 本身(如重新编译 .NET Core 本身)以支持 Debian 7,然后使用它来运行您的应用程序。

【讨论】:

  • 你好,我希望我可以更新那台机器,但不幸的是,这个建议对我来说是不可能的。不过我很欣赏这个建议。我工作的公司担心更新那台机器会导致遗留软件出现其他问题,并拒绝这样做。我发现我可以成功地为这台机器构建 Go 程序,所以我确实有一个解决方案。再次感谢您!
【解决方案2】:

不要在二进制可执行文件上运行 bash,直接使用 ./helloworld 运行即可

bash 是一个 shell 脚本解释器,拒绝读取非文本文件。例如

$ bash /bin/ls
/bin/ls: /bin/ls: cannot execute binary file

如果./helloworld 不起作用,还请尝试strace ./helloworldldd ./helloworld 检查可执行文件中嵌入的错误ELF 解释器(动态链接器)路径。

【讨论】:

  • 谢谢。我尝试了 ./helloworld 并获得了权限被拒绝,然后我尝试了“ldd ./helloworld”并得到了“/usr/lib/x86_64-linux-gnu/libstdc++.so.6:未找到版本‘GLIBCXX_3.4.18’(必需由./helloworld)”。对于“strace ./helloworld”,我得到了 strace: command not found。
  • 我看了上面的评论,然后运行“chmod +x helloworld”,我想我错过了可执行权限。现在当我运行 ./helloworld 时,我只得到“/usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by ./helloworld)”
  • 我在 go 中制作了相同的 hello world 程序(名称:helloworldgo)并为 linux amd64 构建了它。我想看看哪个更容易为 linux 构建。使用 ./helloworldgo 运行 go 版本运行得很好。 @Peter 感谢您指出这一点。
  • @Patrick:是的,“权限被拒绝”肯定是因为缺少+x 权限。 straceltrace 可以成为调试此类低级问题的有用工具(查看实际的系统调用进程正在做什么,例如他们正在查看哪些路径。strace -e file ./hello 通常很有用)。我建议安装strace;所有主流 Linux 发行版都将其打包。
  • 您的库版本错误显示构建主机和您尝试运行它的位置之间的 C++ 库 ABI 版本不匹配。与libc 不同,libstdc++ 确实以不兼容的方式进行了更改,而无需将.so.6 增加到不同的文件名,因此它们进行符号版本控制以提供动态链接器错误,而不是难以调试的神秘崩溃。跨度>
猜你喜欢
  • 2015-05-23
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多