MPI_Bcast发送MPI_PACKED消息时解包出现段错误问题排查
排查MPI_Unpack后段错误的可能原因
下面是几个需要逐一排查的点:
- 确认
header->position初始值为0。MPI_Unpack是从这个偏移位置开始读取数据,如果初始值不是0,会直接跳过前面的字节,读到buffer的非法区域,或者把数据写到dict->codes[0].code的错误位置,触发段错误。 - 核对打包和解包的长度是否完全一致。打包时你是否用了和
(dict->codes[0].length+1)完全相同的长度值?如果打包时的长度和这个值不匹配,比如打包时少传了字节,或者解包时多要了字节,都会导致内存越界。 - 检查
dict->codes[0].code的内存分配是否真的有效。比如你是不是用malloc((dict->codes[0].length + 1) * sizeof(char))分配的?有没有在分配后被意外free,或者指针被其他代码修改成了野指针?可以在Unpack前打印这个指针的地址和分配的大小,确认内存块是合法的。 - 验证MPI数据类型匹配。打包时你是不是用的
MPI_CHAR?如果打包时用了其他类型(比如MPI_BYTE或者自定义类型),解包用MPI_CHAR会导致数据解析错误,甚至访问非法内存。 - 检查
header->size是否正确。这个值必须是MPI_Pack实际输出的总字节数,如果你手动赋值或者计算错误,Unpack时会读取超出buffer范围的数据,破坏内存。 - 多进程环境下,根进程的解包操作也要注意。别以为根进程打包了就不用正确初始化
dict->codes[0].code,根进程同样需要分配好内存再执行Unpack,否则一样会出问题。 - 用调试工具定位具体错误。比如用
valgrind运行程序,它会告诉你具体是哪一行代码访问了非法内存;或者在Unpack前后打印header->position,看看偏移量是否符合预期(比如解包后position应该等于之前打包的总字节数)。
内容的提问来源于stack exchange,提问作者Scotty
相关产品推荐
相关产品推荐

