gpt4 book ai didi

c++ runtime_error捕获在集群节点之间不一致

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:06:52 25 4
gpt4 key购买 nike

问题

我正在尝试设置一个 c++ 程序以在 Redhat scientific linux (v5.11) 集群上运行。我已经能够编译该软件并且它在头节点上完美运行,但是在任何工作节点上运行时它会崩溃。

我已将问题追溯到部分代码,如果某些条件返回 false,则会抛出 std::runtime_error。这是故意的,因为当软件正常运行时,它会被捕获并继续迭代。在工作节点上,软件会在第一次抛出错误时中止。 abort 代码和 backtrace 如下所示。

因为它在一个节点上工作而不在其他节点上工作,我猜测这是 gcc 版本的问题。要编译,我必须 yum install devtoolset-2 并使用 gcc 4.8.2 (Red Hat 4.8.2-15) 作为系统构建软件 gcc 4.1 .2 (Red Hat 4.1.2-55) 太旧,无法正确编译。当我在两个节点上启动应用程序时,我有以下信息:

which gcc > /opt/rh/devtoolset-2/root/usr/bin/gcc
which c++ > /opt/rh/devtoolset-2/root/usr/bin/c++
which g++ > /opt/rh/devtoolset-2/root/usr/bin/g++
which gfortran > /opt/rh/devtoolset-2/root/usr/bin/gfortran
$LD_LIBRARY_PATH > /opt/rh/devtoolset-2/root/usr/lib64:/opt/rh/devtoolset-2/root/usr/lib

就头节点和工作节点之间的区别而言,它们除了内核版本外完全相同:

  • 头:Linux address.com 2.6.18-419.el5 #1 SMP x86_64 x86_64 x86_64 GNU/Linux
  • 工作人员:Linux address.com 2.6.18-164.11.1.el5 #1 SMP x86_64 x86_64 x86_64 GNU/Linux

我累的事情:

  • 使用 SGE 队列提交在工作节点上运行(使用 -V 传递环境)
  • 通过 ssh worker 直接在工作节点上运行,并导出与头节点上相同的所有环境变量
  • 在worker节点上编译运行

任何帮助将不胜感激!以下是我认为获得答案有助于我缩小原因范围的几个问题:

  1. 追求内核版本差异是否有效?
  2. 这看起来像是库和路径的问题而不是代码的问题吗?
  3. 库版本之间的 C++ 错误处理方式有变化吗?
  4. 是否有更多的调试方法可以尝试找出问题的原因?

额外信息

abort如下:

terminate called after throwing an instance of 'std::runtime_error'
what(): 'custom error message'

Program received signal SIGABRT, Aborted.
0x00000038b6830265 in raise () from /lib64/libc.so.6

回溯如下:

#0  0x00000038b6830265 in raise () from /lib64/libc.so.6
#1 0x00000038b6831d10 in abort () from /lib64/libc.so.6
#2 0x00000038bb0bec44 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6
#3 0x00000038bb0bcdb6 in ?? () from /usr/lib64/libstdc++.so.6
#4 0x00000038bb0bcde3 in std::terminate() () from /usr/lib64/libstdc++.so.6
#5 0x00000038bb0bceca in __cxa_throw () from /usr/lib64/libstdc++.so.6
#6 0x00002aaaab074bdc in Some::Function::Name() () from path/to/file.so

我必须承认我对 C++ 的了解非常有限,尽管我在过去的两天里一直在努力改进我一直在与这个问题作斗争。下面是抛出和捕获错误的代码的简化示例(这显然是重复调用 Func1 的更大过程的一部分):

double Func1(int a, double b, int c)
{

for (bool OK = true ; OK && d > e && f < a ; f++)
{
try
{
for (d = 0, g = 1 ; g < 10 ; g *= 2)
{
Func2() ;
}
}
catch (runtime_error problem)
{
*log << problem.what() ;
OK = false ;
}
if (c > 1)
{
*log << f << d;
}
}

void Func2()
{
for (int j = 0 ; j < ny && (x & 5) > 0 ; j++)
{
if (Func3(j) <= 0.0)
{
throw runtime_error("custom error message") ;
}
Func4[j] = j ;
}
}

在编译后的程序上运行 ldd(在头节点上运行,工作节点上缺少第 1 行):

linux-vdso.so.1 =>  (0x00007fff2b6e7000)
/users/username/software/version/Part1/Part1Extra.so (0x00002b3543587000)
libgfortran.so.3 => /usr/lib64/libgfortran.so.3 (0x00002b354385b000)
libm.so.6 => /lib64/libm.so.6 (0x0000003cc2000000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000315f800000)
libc.so.6 => /lib64/libc.so.6 (0x0000003cc1c00000)
/users/username/software/version/Part2/Part2.so (0x00002b3543b4f000)
/users/username/software/version/Part3/Part3.so (0x00002b3543d9b000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003160000000)
/lib64/ld-linux-x86-64.so.2 (0x0000003cc1800000)
/users/username/software/version/Part3/Part3Extra.so (0x00002b3543fb2000)

最佳答案

终于弄清楚发生了什么......

对于那些发现与 c++ 代码相关的意外错误的人来说,这些代码在多节点系统的一部分上正常运行但在其他部分上却不能正常运行,即使系统共享一个公共(public)文件结构,最后一点可能会产生误导,尽管我对于那些更熟悉系统管理的人来说,这肯定是显而易见的。

最初我的印象是头节点和工作节点/计算节点共享整个文件结构。这只是部分正确,因为工作节点可以访问文件系统的某些部分,但重要的是不能访问核心文件,例如 /lib/lib64。通过 yum 安装的包独立于每个计算节点。将头节点更新为正确的 gcc 版本(在本例中为 devtoolset-2)后,我的印象是每个工作节点也已更新。此情况并非如此。

潜在问题

使用 gcc 4.8.2 (Red Hat 4.8.2-15) 编译的 c++ 代码在具有 libstdc++.x86_64 (v4.1.2-55.el5) 的头节点上运行 捕获抛出的 std::runtime_error 错误。在工作节点上运行时未正确捕获此错误。

问题是工作节点系统 libstdc++.x86_64 版本太旧(不幸的是我不记得确切的版本)这意味着错误没有被捕获。似乎某个版本的 libstdc++ 无法从使用 gcc 4.8.2 编译的代码中捕获错误。

解决方案

必须使用 yum 手动更新每个工作节点,以便其 libstdc++ 版本足够高以解决此问题 (v4.1.2-55.el5 在我们的例子中)。更新 libstdc++ 解决了这个问题。

额外信息

在我们的例子中,工作节点无法直接连接到互联网,因此 yum 必须通过代理来完成。我们的 yum 版本也太旧,无法使用 socks5h 自动 ssh 隧道代理方法。因此,我们必须在头节点上使用 squid 包来允许连接。

最后,这花了一些时间才弄清楚,因为文件结构差异非常具有误导性。虽然节点之间不共享关键文件夹,但内容看起来与旧/新版本的包完全相同,具有完全相同的文件结构,只是内容有所修改。

再一次强调,这对系统管理员来说可能是显而易见的,但就是这样。

关于c++ runtime_error捕获在集群节点之间不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45061354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com