【问题标题】:MPI Debugging, Segmentation fault?MPI调试,分段错误?
【发布时间】:2012-05-11 13:47:20
【问题描述】:

编辑:我的问题与C, Open MPI: segmentation fault from call to MPI_Finalize(). Segfault does not always happen, especially with low numbers of processes 类似,因此无论哪种方式,您都可以回答那个问题。 . .

我希望在调试以下代码时获得一些帮助:

int main(){
        long* my_local;
        long n, s, f;
        MPI_Init(NULL, NULL);
        MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    if(my_rank == 0){
        /*  Get size n from user                            */
        printf("Total processes: %d\n", comm_sz);
        printf("Number of keys to be sorted?  ");
        fflush(stdout);
        scanf("%ld", &n);

        /*  Broadcast size n to other processes             */
        MPI_Bcast(&n, 1, MPI_LONG, 0, MPI_COMM_WORLD);

        /*  Create n/comm_sz keys                           
             NOTE! some processes will have 1 extra key if
              n%comm_sz != 0                                */
        create_Keys(&my_local, my_rank, comm_sz, n, &s, &f);
    }

    if(my_rank != 0){
        /* Receive n from process 0                         */
        MPI_Bcast(&n, 1, MPI_LONG, 0, MPI_COMM_WORLD);

        /*  Create n/comm_sz keys                           */
        create_Keys(&my_local, my_rank, comm_sz, n, &s, &f);
    }

        /* The offending function, f is a long set to num elements of my_local*/
        Odd_Even_Tsort(&my_local, my_rank, f, comm_sz);

        printf("Process %d completed the function", my_rank);
        MPI_Finalize();
        return 0;
}

void Odd_Even_Tsort(long** my_local, int my_rank, long my_size, int comm_sz)
{
    long nochange = 1;
    long phase = 0;
    long complete = 1;
    MPI_Status Stat;
    long your_size = 1;

    long* recv_buf = malloc(sizeof(long)*(my_size+1));
    printf("rank %d has size %ld\n", my_rank, my_size);

    while (complete!=0){
        if((phase%2)==0){
            if( ((my_rank%2)==0) && my_rank < comm_sz-1){
            /*  Send right                          */
                MPI_Send(&my_size, 1, MPI_LONG, my_rank+1, 0, MPI_COMM_WORLD);
                MPI_Send(*my_local, my_size, MPI_LONG, my_rank+1, 0, MPI_COMM_WORLD);
                MPI_Recv(&your_size, 1, MPI_LONG, my_rank+1, 0,  MPI_COMM_WORLD, &Stat);
                MPI_Recv(&recv_buf, your_size, MPI_LONG, my_rank+1, 0,  MPI_COMM_WORLD, &Stat);
            }
            if( ((my_rank%2)==1) && my_rank < comm_sz){
            /*  Send left                          */
                MPI_Recv(&your_size, 1, MPI_LONG, my_rank-1, 0,  MPI_COMM_WORLD, &Stat);
                MPI_Recv(&recv_buf, your_size, MPI_LONG, my_rank-1, 0,  MPI_COMM_WORLD, &Stat);
                MPI_Send(&my_size, 1, MPI_LONG, my_rank-1, 0, MPI_COMM_WORLD);
                MPI_Send(*my_local, my_size, MPI_LONG, my_rank-1, 0, MPI_COMM_WORLD);
            }
        }
        phase ++;
        complete = 0;
    }

    printf("Done!\n");
    fflush(stdout);
}

我得到的错误是:

[ubuntu:04968] *** Process received signal ***
[ubuntu:04968] Signal: Segmentation fault (11)
[ubuntu:04968] Signal code: Address not mapped (1)
[ubuntu:04968] Failing at address: 0xb
--------------------------------------------------------------------------
mpiexec noticed that process rank 1 with PID 4968 on node ubuntu exited on signal 11 (Segmentation fault).

我很困惑的原因是函数后面的打印语句仍然显示,但是如果我注释掉函数,没有错误。那么,我在哪里得到分段错误? mpiexec -n 2 ./a.out 和大于 9 的“n”大小出现错误。

如果您真的想要整个可运行代码,请告诉我。真的,我希望的不是精确答案,而是更多如何使用 gdb/valgrind 工具来调试这个问题和其他类似问题(以及如何读取他们的输出)。

(是的,我意识到“排序”功能还没有排序)。

【问题讨论】:

  • "函数后面的打印语句仍然显示,但如果我注释掉函数,没有错误"。这表明你的函数做错了什么,这在以后变成了一个错误。尝试在代码的重要阶段放置障碍和打印,看看执行能走多远。

标签: c debugging mpi


【解决方案1】:

这里的问题很简单,但除非您使用调试器或打印出详尽的调试信息,否则很难看到:

查看调用MPI_Recv 的代码。 recv_buf 变量应作为参数提供,而不是 &amp;recv_buf

  MPI_Recv(   recv_buf  , your_size, MPI_LONG, my_rank-1, 0,  MPI_COMM_WORLD, &Stat);

其余的似乎还可以。

【讨论】:

  • 啊哈,谢谢!这是否意味着问题的根源是recv_buf 是数组本身的地址,而&recv_buf 是指针recv_buf 的地址?我的 C 经验有些有限,所以我倾向于混合经常使用的东西。
  • @NickO 是的,正是这种关系。
  • @NickO 在调试时,可以在每次 MPI 调用后添加一个 printf。这很简单,但会有所帮助
猜你喜欢
  • 2015-02-18
  • 2014-05-07
  • 2017-06-25
  • 2019-06-26
  • 2012-01-24
  • 1970-01-01
  • 2011-12-24
  • 2016-03-22
  • 2017-11-10
相关资源
最近更新 更多