Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在condor上运行时解决神秘故障的方法/工具_C_Memory Corruption_Condor - Fatal编程技术网

在condor上运行时解决神秘故障的方法/工具

在condor上运行时解决神秘故障的方法/工具,c,memory-corruption,condor,C,Memory Corruption,Condor,我正在编写一个跨计算集群运行的C应用程序(使用condor)。我已经尝试了很多方法来揭示有问题的代码,但都没有用 线索: 平均来说,当我在15台机器上运行代码2天时,会出现两到三个SEGFULTS(信号11) 当我在本地运行代码时,不会出现segfault。我在家里的机器上运行了将近3周 尝试: 我在valGrind本地运行了四天的代码,没有内存错误 我通过定义自己的信号处理程序捕获了segfault信号,以便输出一些程序状态 现在,当发生segfault时,我可以使用backtrace打

我正在编写一个跨计算集群运行的C应用程序(使用condor)。我已经尝试了很多方法来揭示有问题的代码,但都没有用

线索:

  • 平均来说,当我在15台机器上运行代码2天时,会出现两到三个SEGFULTS(信号11)
  • 当我在本地运行代码时,不会出现segfault。我在家里的机器上运行了将近3周
尝试:

  • 我在valGrind本地运行了四天的代码,没有内存错误
  • 我通过定义自己的信号处理程序捕获了segfault信号,以便输出一些程序状态
  • 现在,当发生segfault时,我可以使用backtrace打印当前堆栈
  • 我可以打印出变量值
  • 我创建了一个设置为当前行号的变量
  • 我也试着注释代码块,希望如果问题消失,我会发现错误
遗憾的是,输出的行号是相当随机的。我不完全确定我能用stacktrace做什么。假设它只记录发生SEGFULT的函数的地址,对吗

怀疑:

  • 我怀疑condor用来在机器之间移动作业的检查点系统对内存损坏更敏感,这就是为什么我在本地看不到它的原因
  • 索引被错误破坏,这些索引导致了错误。这可以解释这样一个事实,即分段故障发生在相当随机的线号上
更新

通过进一步研究,我发现了以下链接:

  • -用于自动捕获和打印有关SEGFULTS的状态数据的库

  • 关于捕捉SEGFULTS和获取违规指令行号的教程

更新2

Greg建议查看condor日志并“将SEGFULTS与condor从检查点重新启动可执行文件的时间关联起来”。查看日志,所有故障都会在重启后立即发生。当作业从一种类型的机器切换到另一种类型时,所有故障似乎都会发生

更新3

SEGFULT是由主机之间的差异引起的,在condor提交文件中将“requirements”字段设置为问题完全消失

可以设置单个机器:

requirements = machine == "hostname1" || machine == "hostname2"
requirements = classOfMachinesName
或一整类机器:

requirements = machine == "hostname1" || machine == "hostname2"
requirements = classOfMachinesName

请参见需求示例

我认为您已经尝试了大部分。我唯一建议的另一件事是开始添加大量日志代码,并希望您能够缩小错误发生的范围。

如果可以,请使用调试进行编译,并在gdb下运行。 或者,转储内核并将其加载到调试器中

mpich具有内置调试器,或者您可以购买商用并行调试器

然后,您可以逐步浏览代码,查看调试器中发生了什么


发生SEGFULT时,是否可以创建堆芯转储?然后,您可以调试此转储,以尝试找出代码崩溃时的状态


看看是什么指令导致了故障。它是一条有效的指令还是您正在尝试执行数据?如果有效,它试图访问什么内存?这个指针是从哪里来的。您需要缩小故障位置(堆栈损坏、堆损坏、未初始化指针、访问无效内存)。如果是损坏,请查看损坏区域中是否有任何指示数据(指向符号的指针、结构中类似的数据等)。内存分配器可能已经内置了调试某些损坏的功能(请参阅Linux上的
MALLOC\u CHECK\u
或Mac OS上的
mallocguardeges
)。这种情况的一个常见情况是使用空闲的内存()'d,因此记录malloc()/free()对可能会有所帮助。

有一件事你没有说,那就是解决问题需要多大的灵活性。 例如,您能让系统停止运行应用程序吗? 解决这些崩溃又有多重要

我想大部分情况下你是这样做的。这可能需要大量资源

短期步骤是对每个变量输入成吨的“断言”(半手写) 当你不想改变时,确保它没有改变。这可以在你经历长期过程时继续发挥作用

长期--尝试在两个集群上运行它(可能是您的家庭计算机和虚拟机)。 你还看到断层吗。如果没有,请增加群集大小,直到您开始看到故障

在最低配置下运行它(以获得SEGFULTS),并记录所有输入,直到崩溃。使用您记录的输入自动运行系统,调整它们,直到您能够以最少的输入获得一致的崩溃


在这一点上,环顾四周。如果您仍然找不到bug,那么您将不得不再次询问,并提供运行过程中收集的一些额外数据

如果您已经使用condor_编译工具将代码与condor检查点代码重新链接,那么它会做一些与普通链接不同的事情。最重要的是,它静态链接您的代码,并使用自己的malloc。另一个很大的区别是condor将在一台外国机器上运行它,那里的环境可能与您预期的导致问题的环境有很大的不同

condor_compile生成的可执行文件可以作为condor系统之外的独立二进制文件运行。如果您在本地运行condor_compile发出的二进制文件,在condor之外,您还看到segfaults吗


如果没有,您能否将SEGFULTS与condor从检查点重新启动可执行文件的时间相关联(用户日志将告诉您何时会发生这种情况)。

最近的gcc有挡泥板选项来执行一些运行时检查。这更像是