使用gdb在多个屏幕窗口中调试MPI

使用gdb在多个屏幕窗口中调试MPI,gdb,mpi,gnu-screen,Gdb,Mpi,Gnu Screen,如果我有一个MPI程序,我想用gdb进行调试,同时能够看到所有单独进程的输出,我可以使用: mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...] mpirun-nxterm-hold-egdb-exrun--args./program[arg1][arg2][…] 当我有一个GUI可以玩的时候,这是很好的。但情况并非总是如此 我是否可以使用类似的设置,使每个进程都有自己的窗口?

如果我有一个MPI程序,我想用gdb进行调试,同时能够看到所有单独进程的输出,我可以使用:

mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...]
mpirun-nxterm-hold-egdb-exrun--args./program[arg1][arg2][…]
当我有一个GUI可以玩的时候,这是很好的。但情况并非总是如此

我是否可以使用类似的设置,使每个进程都有自己的窗口?这对于在远程环境中进行调试非常有用,因为它允许我使用
Ctrl+a n
在输出之间切换,我认为“如何调试MPI程序?”线程中的答案符合您的要求


编辑:

作为对评论的回应,你可以更容易地做到这一点,尽管简洁并不是我会使用的术语:

通过mpirun启动分离屏幕-运行调试器和进程。我已经调用了会话mpi,我正在通过我的库路径,因为它被屏幕剥离,我的演示需要它(我也在mac上,因此使用lldb和DYLD):

然后启动一个单独的屏幕会话,我称之为“调试”:

screen -AdmS debug
使用
screen-ls
列出正在运行的会话:

screen -S debug -X screen -t tab0 screen -r 19871.mpi
screen -S debug -X screen -t tab1 screen -r 19872.mpi
screen -S debug -X screen -t tab2 screen -r 19875.mpi
screen -S debug -X screen -t tab3 screen -r 19876.mpi
mpirun -np 4 screen -AdmS mpi gdb ./parallel_pit_fill.exe one retain ./beauford.tif 500 500
>>屏幕-ls

以下屏幕显示:

19871.mpi(分离式)

19872.mpi(分离式)

19875.mpi(分离式)

19876.mpi(分离式)

20105.1调试(分离)

现在在调试会话中启动4个新选项卡,将每个选项卡连接到一个mpi会话:

screen -S debug -X screen -t tab0 screen -r 19871.mpi
screen -S debug -X screen -t tab1 screen -r 19872.mpi
screen -S debug -X screen -t tab2 screen -r 19875.mpi
screen -S debug -X screen -t tab3 screen -r 19876.mpi
mpirun -np 4 screen -AdmS mpi gdb ./parallel_pit_fill.exe one retain ./beauford.tif 500 500
然后只需使用
screen-r debug
连接到调试会话。现在有4个选项卡,每个选项卡运行一个附加到mpi进程的调试器的串行实例,类似于前面描述的xterm方法。这并不是最快的命令集,但至少你不需要修改代码或chase-PIDs等


我尝试了另一种方法,但似乎不起作用:

启动分离屏幕

screen -AdmS ashell
启动两个mpi进程,在分离的会话中启动新的屏幕选项卡,使用我的演示mpi应用程序启动lldb:

mpirun -np 1 screen -S ashell -X screen -t tab1 env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out : -np 1 screen -S ashell -X screen -t tab2 env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out
或者干脆

mpirun -np 2 screen -S ashell -X screen env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out
然后将其连接到屏幕上

screen -r ashell 

您将有3个选项卡,其中2个与您的程序一起运行lldb,另一个与标准shell一起运行。不幸的是,当您尝试运行这些程序时,每个进程都认为它是通信世界中唯一的进程,我不知道该怎么办…

如何调试C/C++MPI程序?

一种方法是为每一个终端启动一个单独的终端和gdb会话 过程:

mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...]
启动新的屏幕会话以访问调试器:

screen -AdmS debug
将调试器的屏幕会话加载到新的屏幕会话中

screen -list |                   #Get list of screen sessions
   grep -E "[0-9]+.mpi"  |       #Extract the relevant ones
   awk '{print NR-1,$1}' |       #Generate tab #s and session ids, drop rest of the string
   xargs -n 2 sh -c '
     screen -S debug -X screen -t tab$0 screen -r $1
   '
跳转到新屏幕会话:

screen -r debug
我已将上述内容封装在一个方便的脚本中:

#!/bin/bash
if [ $# -lt 2 ]
then
  echo "Parallel Debugger Syntax: $0 <NP> <PROGRAM> [arg1] [arg2] [...]"
  exit 1
fi

the_time=`date +%s` #Use this so we can run multiple debugging sessions at once
                    #(assumes we are only starting one per second)

#The first argument is the number of processes. Everything else is what we want
#to run. Make a new mpi screen for each process.
mpirun -np $1 screen -AdmS ${the_time}.mpi gdb "${@:2}"

#Create a new screen for debugging from
screen -AdmS ${the_time}.debug

#The following are used for loading the debuggers into the debugging screen
firstpart="screen -S ${the_time}.debug"
secondpart=' -X screen -t tab$0 screen -r $1'

screen -list |                         #Get list of mpi screens
   grep -E "[0-9]+.${the_time}.mpi"  | #Extract the relevant ones
   awk '{print NR-1,$1}' |             #Generate tab #s and session ids, drop rest of the string
   xargs -n 2 sh -c "$firstpart$secondpart"

screen -r ${the_time}.debug            #Enter debugging screen
#/bin/bash
如果[$#-lt 2]
然后
echo“并行调试器语法:$0[arg1][arg2][…]”
出口1
fi
_time=`date+%s`#使用它,我们可以一次运行多个调试会话
#(假设我们每秒只启动一个)
#第一个参数是进程数。其他一切都是我们想要的
#跑。为每个进程创建一个新的mpi屏幕。
mpirun-np$1屏幕-AdmS${the_time}.mpi gdb“${@:2}”
#创建用于调试的新屏幕
screen-AdmS${the_time}.debug
#以下内容用于将调试器加载到调试屏幕
firstpart=“screen-S${the_time}.debug”
第二部分='-X屏幕-t选项卡$0屏幕-r$1'
屏幕-列表|#获取mpi屏幕列表
grep-E“[0-9]+.${the_time}.mpi”|#提取相关的
awk'{print NR-1,$1}'|#Generate tab#和session id,删除字符串的其余部分
xargs-n 2 sh-c“$firstpart$secondpart”
screen-r${the_time}.debug#进入调试屏幕

与您启动xterm的方式相比,它似乎非常复杂。还有什么更简洁的方法吗?我不确定-我用我期望的方式编辑了答案,但它不起作用。不过,这可能会让你开始。@Richard-我用我能想出的最简单的方法,补充了一个更详细的答案,来做你想做的事。它比链接帖子中的方法要简单一些,尽管仍然不如xterm方法简单。谢谢,@timofind。我能够使用xargs修改您的答案(请参阅),以自动生成
调试
屏幕会话。这使我能够构建一个方便的脚本来运行所有的东西。实际上,我们的两个cod似乎都没有捕捉到命令的参数。而且,当我使用
-ex run--args
时,程序永远不会启动,就好像每个进程都在等待通信,并且通信失败一样。警告:这似乎无法获取程序的参数!使用
-ex run--args
会导致程序挂起在
MPI_INIT
上,就好像它无法联系其他进程一样。我不知道这是为什么。