MPICH 1.6中具有全局变量的分割故障

Segmentation Fault with Global Variable in MPICH 1.6

本文关键字:全局变量 分割 故障 MPICH      更新时间:2023-10-16

考虑以下简单程序:

#include <mpi.h>                                                                                                                                                                                                                                 
#include <iostream>                                                                                                                                                                                                                              
#include <stdlib.h>                                                                                                                                                                                                                              
#include <stdio.h>                                                                                                                                                                                                                               
#include <string>                                                                                                                                                                                                                                
#include <vector>                                                                                                                                                                                                                                
using std::cout;                                                                                                                                                                                                                                 
using std::string;                                                                                                                                                                                                                               
using std::vector;                                                                                                                                                                                                                               
vector<float> test;                                                                                                                                                                                                                              
#ifdef GLOBAL                                                                                                                                                                                                                                    
string hostname;                                                                                                                                                                                                                                 
#endif                                                                                                                                                                                                                                           
int main(int argc, char** argv) {                                                                                                                                                                                                                
  int rank;  // The node id of this processor.                                                                                                                                                                                                   
  int size;  // The total number of nodes.                                                                                                                                                                                                       
#ifndef GLOBAL                                                                                                                                                                                                                                   
  string hostname;                                                                                                                                                                                                                               
#endif                                                                                                                                                                                                                                           
  MPI_Init(&argc, &argv);                                                                                                                                                                                                                        
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);                                                                                                                                                                                                          
  MPI_Comm_size(MPI_COMM_WORLD, &size);                                                                                                                                                                                                          
  cout << "Joining the job as processor: " << rank << std::endl;                                                                                                                                                                                 
  {                                                                                                                                                                                                                                              
    char buf[2048] = "HELLO";                                                                                                                                                                                                                    
    hostname.assign(buf, 2048);                                                                                                                                                                                                                  
  }                                                                                                                                                                                                                                              
  test.push_back(1.0f);                                                                                                                                                                                                                          
  cout << "Hostname: " << hostname << "::" << test[0] << std::endl;                                                                                                                                                                              
  MPI_Finalize();                                                                                                                                                                                                                                
  return 0;                                                                                                                                                                                                                                      
} 

如果我编译/运行这个:

mpicxx -c test.cc && mpicxx -lstdc++ test.o -o test && ./test

没有分割错误,但如果我运行它:

mpicxx -DGLOBAL -c test.cc && mpicxx -lstdc++ test.o -o test && ./test

则在hostname.assign()行存在分段错误。此外,如果我删除这个赋值,一旦main方法返回,string析构函数中就会出现分段错误,因此assign方法并不是真正的罪魁祸首。

注意,唯一的区别是"global"变量hostname的声明位置。

我正在编译MPICH2版本1.6,并没有真正的选项来改变这一点,因为我是在超级计算机上运行这个。

如果我删除MPI_Init等错误消失导致我相信有意想不到的事情发生与MPI和这个全局变量。

我在网上发现了一些其他发生这种情况的例子,但他们都通过安装新版本的MPICH来解决问题,这对我来说也是不可能的。

此外,我想知道为什么会发生这种情况而不仅仅是一种绕过它的方法。

感谢您的宝贵时间。

好了,经过相当多的调试,我发现MVAPICH2-1.6库定义了一个名为hostname的变量:

mpid/ch3/channels/mrail/src/rdma/ch3_shmem_coll.c

这是第55行(在这个版本的文件中):

char hostname[SHMEM_COLL_HOSTNAME_LEN];

编译器没有抱怨这里的名称冲突,但这几乎肯定是罪魁祸首,因为在我的程序中更改变量名称消除了错误。我想这在MVAPICH2的后续版本中会有所改变,但如果没有,我将提交错误。