MPI和Valgrind未显示行号

3

我写了一个大型程序,但是我在追踪分段错误时遇到了很大的困难。我发布了一个问题,但是我没有足够的信息(请参见下面的链接 - 如果您有,请注意我花了将近一整天的时间尝试多次编译代码以找出能够重现错误的最小版本,但是一直没有成功)。

https://stackoverflow.com/questions/16025411/phantom-bug-involving-stdvectors-mpi-c

所以现在我第一次尝试使用valgrind。我刚刚安装了它(只需“sudo apt-get install valgrind”),没有特殊的安装来考虑MPI(如果有的话)。我希望得到具体的信息,包括文件名和行号(我知道valgrind无法提供变量名)。虽然我得到了有用的信息,包括
  • 大小为4的无效读取
  • 条件跳转或移动依赖于未初始化的值
  • 未初始化的值是由堆栈分配创建的
  • 1个块中的4个字节肯定丢失

除此之外还有这个神奇的东西

  • Syscall param sched_setaffinity(mask) points to unaddressable byte(s) at 0x433CE77: syscall (syscall.S:31) Address 0x0 is not stack'd, malloc'd or (recently) free'd

但我没有得到文件名和行号。相反,我得到了:

==15095==    by 0x406909A: ??? (in /usr/lib/openmpi/lib/libopen-rte.so.0.0.0)

这是我编译代码的方法:

mpic++ -Wall -Wextra -g -O0 -o Hybrid.out (…file names)

这里有两种我执行valgrind的方式:

valgrind --tool=memcheck --leak-check=full --track-origins=yes --log-file=log.txt mpirun -np 1 Hybrid.out

并且

mpirun -np 1 valgrind --tool=memcheck --leak-check=full --track-origins=yes --log-file=log4.txt -v ./Hybrid.out

基于使用Open MPI运行并行程序时出现分段错误中的说明的第二个版本。

如果我正确理解所选择的答案,那么这与{{link2:在Ubuntu发行版中使用MPI编译openmpi}矛盾。

我故意在一个处理器上运行valgrind,因为这是我的程序能够完成执行而不会出现分段错误的唯一方式。 我也使用两个处理器运行了它,我的程序出现了预期的分段错误,但是从valgrind返回给我的日志似乎包含基本相同的信息。 我希望通过解决valgrind在一个处理器上报告的问题,可以神奇地解决发生在多个处理器上的问题。

我尝试像{{link3:建议的那样在程序编译中包括“-static”}}

尽管在Ubuntu 11.10 / VirtualBox上使用-g标志,Valgrind仍未显示行号

但编译失败,并显示以下内容(除了几个警告)

dynamic STT_GNU_IFUNC symbol "strcmp" with pointer equality in '…' can not be used when making an executably; recompile with fPIE and relink with -pie

我还没有研究过"fPIE"和"-pie"的含义。此外,请注意,我没有使用makefile,也不知道如何编写makefile。
还有几点需要说明:我的代码不使用malloc、calloc或new命令,完全使用std::vector,没有使用C数组。我使用像.resize()、.insert()、.erase()和.pop_back()这样的命令。我的代码还通过引用和常量引用将向量传递给函数。至于并行命令,我只使用MPI_Barrier()、MPI_Bcast()和MPI_Allgatherv()。
如何让valgrind显示它报告的错误的文件名和行号呢?感谢大家的帮助!
编辑:
我继续工作,我的一个朋友指出,没有行号的报告都来自于MPI文件,我没有从源代码编译它们,因此不能使用-g选项,因此看不到行号。所以我根据这个命令再次尝试了valgrind。
mpirun -np 1 valgrind --tool=memcheck --leak-check=full --track-origins=yes --log-file=log4.txt -v ./Hybrid.out

但现在对于两个处理器,这是

mpirun -np 2 valgrind --tool=memcheck --leak-check=full --track-origins=yes --log-file=log4.txt -v ./Hybrid.out

该程序已经运行完成(我没有看到命令行报告的段错误),但是这次valgrind的执行给了我文件中的行号。Valgrind指向的行是我调用MPI_Bcast()的地方。可以说,仅当内存问题在多个处理器上显现时(因为我已经在np -1上成功运行它),这才出现了这个问题吗?
1个回答

0

听起来你在使用错误的工具。如果你想知道段错误发生的位置,请使用gdb。

这里有一个简单的例子。这个程序将在*b=5处发生段错误。

// main.c

int
main(int argc, char** argv)
{
   int* b = 0;
   *b = 5;
   return *b;
}

使用gdb查看发生了什么;(<----部分解释了输入行)

svengali ~ % g++ -g -c main.c -o main.o # include debugging symbols in .o file
svengali ~ % g++ main.o -o a.out        # executable is linked (no -g here)
svengali ~ % gdb a.out
GNU gdb (GDB) 7.4.1-debian
<SNIP>
Reading symbols from ~/a.out...done.
(gdb) run <--------------------------------------- RUNS THE PROGRAM
Starting program: ~/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00000000004005a3 in main (argc=1, argv=0x7fffffffe2d8) at main.c:5
5      *b = 5;
(gdb) bt  <--------------------------------------- PRINTS A BACKTRACE
#0  0x00000000004005a3 in main (argc=1, argv=0x7fffffffe2d8) at main.c:5
(gdb) print b <----------------------------------- EXAMINE THE CONTENTS OF 'b'
$2 = (int *) 0x0
(gdb) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接