免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1666 | 回复: 0
打印 上一主题 下一主题

并行调试器 PDB 使用及分析实例 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-01-17 17:02 |只看该作者 |倒序浏览
并行调试器 PDB(Parallel debugger) 简介
长期以来,高性能并行环境下的程序调试一直是一个热门话题。PDB 是 IBM 发布的一种强大的并行环境下的命令行调试工具。它能够在并行程序运行时观察程序的所有 tasks 的内部结构和内存的使用情况,方便用户对并行程序进行调试。与串行调试器相比,PDB V5.3 增加了以下功能(本文中均以 PDB V5.3 为例,进行介绍):
  • 支持单步调试并行程序的每一个 task
  • 支持同时对并行程序的多个 task 进行调试
  • 提供了一个控制中心,用来对并行程序的所有 tasks 进行集中管理
  • 支持同时对多达 1024k 的任务进行调试
  • 提供了一种机制,可以让用户自定义消息过滤准则。
  • 支持对数据进行分类显示
PDB 的架构(如图 1)的核心部分,是具有多层的树形结构的 SCI(Scalable Communication Infrastructure)—它可以启动及管理并行程序的所有分布式的 tasks,所有的通信及任务管理都由 SCI 完成。PDB 底层调用的是串行调试器 GDB,即 GNU Project Debugger(在 Linux 系统上),及 DBX(在 AIX 系统上)。使用 PDB 进行调试,类似于同时启动多个 GDB(DBX),对并行程序的多个任务同时进行调试。关于 PDB 的基本信息请参见“参考资源”中的 IBM Publication: 《 Parallel Environment for AIX and Linux V5.2.1 》的“Using the PDB debugger”章节。

图 1. PDB 的架构


PDB 的两种启动方式:Launch 模式和 Attach 模式
编译并行程序
使用 PDB 进行调试,必须使并行程序在编译时包含调试信息,即在编译时用“-g”选项打开调试选项。调试信息包含程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号。PDB 利用这些信息使源代码和机器码相关联。
下面是本文中要用 PDB 调试的并行程序。此程序调用 MPI(Message Passing Interface,消息传递接口)函数初始化并行环境,查询应用中进程的总数等,进行点对点通信,传输消息,以及结束该并行环境。

清单 1. 并行程序“mpihello.c”文件的代码:
                                 #include "mpi.h" void main(int argc, char **argv)  {     int numprocs,myrank,i,namelen;     MPI_Status status;     char msg[128];     char processor_name[MPI_MAX_PROCESSOR_NAME];     /* 调用 MPI_Init 函数,初始化并行环境 */  MPI_Init(&argc,&argv);  /* 调用 MPI_Comm_size 函数,查询进程总数 */  MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  /* 调用 MPI_Comm_rank 函数,查询当前进程的标识号 */  MPI_Comm_rank(MPI_COMM_WORLD,&myrank);  /* 调用 MPI_Get_processor_name 函数,查询当前进程运行的机器的名称 */     MPI_Get_processor_name(processor_name,&namelen);  /* 每一个进程都向进程 0 发送消息 */    strcpy(msg,"hello world!";    sprintf(msg,"hello world from %s",processor_name);     MPI_Send(msg,strlen(msg) + 1,MPI_CHAR,0,99,MPI_COMM_WORLD);  /* 进程 0 从所有进程接收消息,并将其打印 */     if(myrank ==0) {         for (i=0;i<numprocs;i++) {             MPI_Recv(msg,strlen(msg)+1,MPI_CHAR,i,99,MPI_COMM_WORLD,&status);             printf("Message from %d of %d:  %s\n",i,numprocs,msg);         }  }  /* 调用 MPI_Finalize 函数,结束并行环境 */     MPI_Finalize();  }

利用 IBM 并行编译器 mpcc 编译该并行程序(在编译时用“-g”选项打开调试选项):
$ mpcc -g -o mpihello mpihello.c

利用 IBM 并行环境运行该并行程序的结果为(其中:参数“-procs 2”指定了该并行程序以两个任务运行):
$ poe ./mpihello -procs 2  Message from 0 of 2:  hello world from node1  Message from 1 of 2:  hello world from node2

下面将介绍使用 PDB 的两种启动方式对该并行程序进行调试。
PDB 的两种启动方式
根据一个调试会话是如何启动的,PDB 分为两种启动方式:“Launch”模式和“Attach”模式。
“Launch”模式 :
“Launch”模式,即使用 PDB 启动一个新的调试进程。在 Launch mode 下,PDB 必须启动在该并行程序希望被执行(即 poe 希望被执行)的主机上。其启动方式如下:

清单 2. “Launch”模式启动方式:
                                 pdb executable_and_arguments     [--poe poe_options]     [--gdb gdb_options] (Linux only)  or  [--dbx dbx_options] (AIX only)  FLAGS  executable_and_arguments    Specifies to launch the target executable and start debugging from    the beginning of the program. The arguments are to the executable,    not to PDB.  --gdb gdb_options    Specifies the options to pass to GDB. Applies to Linux only.  --dbx dbx_options    Specifies the options to pass to dbx. Applies to AIX only.  --poe poe_options    Specifies the options to pass to POE.

例如以“Launch”模式启动 PDB,调试一个并行程序“mpihello”,如下所示(其中:参数“-procs 2”指定了该并行程序以两个任务运行,参数“-hostfile”指定了将要执行该并行程序的主机列表):
$ pdb ./mpihello --poe -procs 2 -hostfile ./host.list                       

“Attach”模式:
“Attach”模式,即使用 PDB 挂接一个正在运行的进程。在“Attach”模式下,PDB 必须启动在该并行程序已经被执行(即 poe 已经被启动)的主机上。其启动方式如下:

清单 3. “Attach”模式启动方式:
                                 pdb -a [poe_process_id]  [--gdb gdb_options] (Linux only)  or  [--dbx dbx_options] (AIX only)  FLAGS  executable_and_arguments    Specifies to launch the target executable and start debugging from    the beginning of the program. The arguments are to the executable,    not to PDB.  -a [poe_process_id]    Specifies to attach to a running POE job. pdb -a must be issued from    the node on which the POE job was initiated. If the POE process ID is    not specified, PDB tries to find one and reports an error if multiple    POE processes exist.  --gdb gdb_options    Specifies the options to pass to GDB. Applies to Linux only.  --dbx dbx_options    Specifies the options to pass to dbx. Applies to AIX only.

例如以“Attach”模式启动 PDB,挂接一个已经被执行的并行程序“mpihello”(进程号为 [poe_pid])进行调试,如下所示:
$ pdb – a [poe_id]                       

PDB 启动以后,可以利用 DBX/GDB 命令,以及 PDB 内部命令对并行程序进行调试。
控制中心
PDB 成功启动后,提供了一个控制中心 console,用来对被启动的并行程序的所有 tasks 进行集中管理。除了该控制中心外,PDB 还可以通过以下方式挂接新的控制中心到该调试会话上,对任务进行管理,即:
pdb -c [session_number]                       

PDB 通过控制中心可以利用 DBX/GDB 命令,以及 PDB 内部命令对并行程序的任务进行调试。

在 PDB 中使用 DBX/GDB 命令对并行程序进行调试
PDB 启动以后,可以使用 DBX(在 AIX 系统上)/GDB(在 Linux 系统上)命令对并行程序进行调试。下面通过在 IBM-Power 550, AIX61(AIX 系统)/ SLES11(Linux 系统)平台上的简单实例演示如何在 PDB 中进行设置断点,运行程序,以及打印变量等操作。

清单 4. 在 AIX 系统上,使用 DBX 进行调试:
                                 (IBM-Power 550, AIX61(AIX 系统 ))  $ pdb ./mpihello --poe -procs 2 -hostfile ./host.list  PDB -- Parallel Debugger for IBM Parallel Environment on AIX  Current PDB debug session number is 655534. Be aware, only one console  will connect to this session after startup, type 'pdb -c 655534' to  connect more consoles to this session.  At the prompt, enter any DBX command.  Enter 'help' for more usage.  (all) stop in main ( 设置断点在源程序的 main 函数 )  0:1 | [1] stop in main  (all) run ( 运行程序 )  0:1 | [1] stopped in main at line 10 in file "mpihello.c" ($t1)  0:1 |    10       MPI_Init(&argc,&argv);  (all) list ( 显示源代码 )  0:1 |    11       MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  0:1 |    12       MPI_Comm_rank(MPI_COMM_WORLD,&myrank);  0:1 |    13       MPI_Get_processor_name(processor_name,&namelen);  0:1 |    14  0:1 |    15   /* every process send msg to process 0 */  0:1 |    16      strcpy(msg,"hello world!";  0:1 |    17      sprintf(msg,"hello world from %s",processor_name);  0:1 |    18  0:1 |    19       MPI_Send(msg,strlen(msg) + 1,MPI_CHAR,0,99,MPI_COMM_WORLD);  0:1 |    20  (all) stop at 13 ( 设置断点在源程序的第 13 行 )  0:1 | [6] stop at "mpihello.c":13  (all) cont ( 继续运行程序 )  0:1 | [6] stopped in main at line 13 in file "mpihello.c" ($t1)  0:1 |    13       MPI_Get_processor_name(processor_name,&namelen);  (all) print numprocs ( 打印变量 numprocs 的值 )  0:1 | 2  (all) print myrank ( 打印变量 myrank 的值 )  0 | 0  1 | 1

在上例中,PDB 使用 DBX 命令设置了两个断点,运行了该并行程序,并打印了变量“numprocs”,及“myrank”的值。

清单 5. 在 Linux 系统上,使用 GDB 进行调试:
                                 (IBM-Power 550, SLES11(Linux 系统 ))  $ pdb ./mpihello --poe -procs 2 -hostfile ./host.list  PDB -- Parallel Debugger for IBM Parallel Environment on Linux  Current PDB debug session number is 2405. Be aware, only one console  will connect to this session after startup, type 'pdb -c 2405' to  connect more consoles to this session.  At the prompt, enter any GDB command.  Enter 'help' for more usage.  (all) break main ( 设置断点在源程序的 main 函数 )  0:1 | Breakpoint 1 at 0x100008a8: file mpihello.c, line 10.  (all) run ( 运行程序 )  0:1 | Starting program: /u/ronglli/tests_linux/mpihello  0:1 | [Thread debugging using libthread_db enabled]  0 | [New Thread 0x4045f4b0 (LWP 2455)]  1 | [New Thread 0x4045f4b0 (LWP 2457)]  0 | [New Thread 0x4085f4b0 (LWP 2456)]  1 | [New Thread 0x4085f4b0 (LWP 245]  0:1 |  0:1 | Breakpoint 1, main (argc=1, argv=0xfffeef94) at mpihello.c:10  0:1 | 10            MPI_Init(&argc,&argv);  (all) list ( 显示源代码 )  0:1 | 5     int numprocs,myrank,i,namelen;  0:1 | 6     MPI_Status status;  0:1 | 7     char msg[128];  0:1 | 8     char processor_name[MPI_MAX_PROCESSOR_NAME];  0:1 | 9  0:1 | 10            MPI_Init(&argc,&argv);  0:1 | 11            MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  0:1 | 12            MPI_Comm_rank(MPI_COMM_WORLD,&myrank);  0:1 | 13            MPI_Get_processor_name(processor_name,&namelen);  0:1 | 14  (all) break 13 ( 设置断点在源程序的第 13 行 )  0:1 | Breakpoint 2 at 0x100008cc: file mpihello.c, line 13.  (all) cont ( 继续运行程序 )  0:1 | Continuing.  0 | [New Thread 0x476ff4b0 (LWP 2557)]  1 | [New Thread 0x476ff4b0 (LWP 255]  0 | [New Thread 0x4843f4b0 (LWP 2559)]  1 | [New Thread 0x4843f4b0 (LWP 2560)]  0 | [New Thread 0x48a4f4b0 (LWP 2562)]  1 | [New Thread 0x48a4f4b0 (LWP 2561)]  0 | [New Thread 0x4906f4b0 (LWP 2563)]  1 | [New Thread 0x4906f4b0 (LWP 2564)]  1 |  0:1 | Breakpoint 2, main (argc=1, argv=0xfffeef94) at mpihello.c:13  0:1 | 13      MPI_Get_processor_name(processor_name,&namelen);  (all) print numprocs ( 打印变量 numprocs 的值 )  0:1 | $1 = 2  (all) print myrank ( 打印变量 myrank 的值 )  1 | $2 = 1  0 | $2 = 0

在上例中,PDB 使用 GDB 命令设置了两个断点,运行了该并行程序,并打印了变量“numprocs”,及“myrank”的值。

在 PDB 中使用 PDB 内部命令对并行程序进行调试
PDB 提供了内部命令便于对并行程序进行调试,例如“组操作”,“用户自定义消息过滤准则”,“消息聚合”,以及退出等。
组操作
PDB 支持对其并行程序的所有任务进行组操作,即提供“group”命令,显示组成员,创建一个包含一部分或全部任务的新组,删除组,对组进行赋值,加减操作等;并提供了“on”命令,来切换组名,选择已定义的组为当前组。在 PDB 一个调试会话启动后,PDB 就创建了预定义组“all”(包括了所有的任务);“FILTERED”(包括所以针对上一条命令有消息输出的任务);以及“0”,“1”…“<num clinets -1>”(仅包括一个任务)。“group”及“on”命令提供的操作如下所示:

清单 6. “group”命令提供的操作:
                                 (all) help group  Group clients  group -- show all groups.  group <name> -- show the group of <name>.  group <name> = <clients> -- set group <name> to have <clients>.  group <name> + <clients> -- add <clients> into group <name>.  group <name> - <clients> -- delete <clients> from group <name>.  <name>: the name of a group.  <clients>: list of clients separated by space. <client>:<client>            can be used for a range of clients. Group names can be            used in the list too.  Predefined groups are:            0, 1, 2, ..., <num clients - 1> representing individual clients,            'all' containing all clients, and  Examples:            group a = 0:2 4     -- Group a has clients 0,1,2,4            group b = 3 a       -- Group b has clients 0,1,2,3,4            group a + b 5:7     -- Group a has clients 0,1,2,3,4,5,6,7


清单 7. “on”命令提供的操作:
                                 (all) help on  Switch client group  on <group> -- Set current group to be <group>.               Client commands are broadcast to all members in               current group.

下面通过 IBM-Power 550, AIX61(AIX 系统)/ SLES11(Linux 系统)平台上的简单实例演示如何在 PDB 中进行组操作,例如创建新组,删除组,切换组等。

清单 8. 使用“group”及“on”命令进行组操作:
                                 (IBM-Power 550, AIX61(AIX 系统 )/ SLES11(Linux 系统 ))  (all) group ( 使用 group 命令显示组名 )  FILTERED: 0 1 2 3 4 5 6 7  all: 0 1 2 3 4 5 6 7  (all) group g1 = 0 1:4 ( 创建新组 )  (all) group g2 = 4 5  (all) group  FILTERED: 0 1 2 3 4 5 6 7  all: 0 1 2 3 4 5 6 7  g1: 0 1 2 3 4  g2: 4 5  (all) group g1 - g2  (all) group  FILTERED: 0 1 2 3 4 5 6 7  all: 0 1 2 3 4 5 6 7  g1: 0 1 2 3  g2: 4 5  (all) group g2 + g1 7  (all) group  FILTERED: 0 1 2 3 4 5 6 7  all: 0 1 2 3 4 5 6 7  g1: 0 1 2 3  g2: 0 1 2 3 4 5 7  (all) list  0:7 | 1 #include "mpi.h" 0:7 | 2  0:7 | 3 main(int argc, char **argv)  0:7 | 4 {  0:7 | 5     int numprocs,myrank,i,namelen;  0:7 | 6     MPI_Status status;  0:7 | 7     char msg[128];  0:7 | 8     char processor_name[MPI_MAX_PROCESSOR_NAME];  0:7 | 9  0:7 | 10            MPI_Init(&argc,&argv);  (all) on g1 ( 使用 on 命令切换当前组 )  (g1) list  0:3 | 11            MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  0:3 | 12            MPI_Comm_rank(MPI_COMM_WORLD,&myrank);  0:3 | 13            MPI_Get_processor_name(processor_name,&namelen);  0:3 | 14  0:3 | 15        /* every process send msg to process 0 */  0:3 | 16           strcpy(msg,"hello world!";  0:3 | 17           sprintf(msg,"hello world from %s",processor_name);  0:3 | 18  0:3 | 19            MPI_Send(msg,strlen(msg) + 1,MPI_CHAR,0,99,MPI_COMM_WORLD);  0:3 | 20

用户自定义消息过滤准则
PDB 提供了用户自定义消息过滤准则,即提供“match”命令,对消息进行过滤。

清单 9. “match”命令提供的操作:
                                 (all) help match  Filter client command outputs with regular expression  match -- show last client command outputs.  match <regexp> -- filter the last client command output with <regexp>.  match <regexp> | match <regexp> | ... -- cascade style.  Note: If you want to filter <command> output with <regexp>,  you can use the system command.  <command> | grep <regexp> -- filter <command> output with <regexp>.  <command> | grep <regexp> | grep <regexp> | ... -- cascade style.  <regexp>: regular expression surrounded by single(double) quotation marks  <command>: client command.  Examples:            match 'Hello'     -- Show lines that contain 'Hello' in last command                 outputs            match 'Hello' | match 'World'     -- Show lines that contain 'Hello'                and 'World' in last command outputs            match 'Hello|World'     -- Show lines that contain 'Hello' or 'World'                in last command outputs            list | grep 'Hello'     -- Show lines that contain 'Hello' in current                 command outputs            list | grep 'Hello' | grep 'World'     -- Show lines that contain                 'Hello' and 'World' in current command outputs            list | grep -E "Hello|World"     -- Show lines that contain 'Hello' or                 'World' in current command outputs          This is available only in normal state.

下面通过 IBM-Power 550, AIX61(AIX 系统)/ SLES11(Linux 系统)平台上的简单实例演示如何在 PDB 中使用“match”命令,对消息进行过滤。

清单 10. 使用“match”命令对消息进行过滤:
                                 (IBM-Power 550, AIX61(AIX 系统 )/ SLES11(Linux 系统 ))  (all) list  0:7 | 1 #include "mpi.h" 0:7 | 2  0:7 | 3 main(int argc, char **argv)  0:7 | 4 {  0:7 | 5     int numprocs,myrank,i,namelen;  0:7 | 6     MPI_Status status;  0:7 | 7     char msg[128];  0:7 | 8     char processor_name[MPI_MAX_PROCESSOR_NAME];  0:7 | 9  0:7 | 10            MPI_Init(&argc,&argv);  (all) match msg ( 使用 match 命令过滤与 msg 字符串匹配的消息 )  0:7 | 7     char msg[128];  (all) list | grep MPI |grep Comm  0:7 | 11            MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  0:7 | 12            MPI_Comm_rank(MPI_COMM_WORLD,&myrank);

消息聚合(Message Aggregation)
在 PDB 中,不同任务中的相同的消息会被聚合,从而大幅度地增加了 PDB 的输出消息的可读性,减少了消息的冗余度。如下例:
0 | this is a test  1 | this is a test … 99 | this is a test

以上输出消息,会被聚合成一条消息:
[0:99] | this is a test                       

综上所述,PDB 提供了多种内部命令,使得同时对多个任务进行管理变得更加简单、方便;其输出消息通过“用户自定义消息过滤”、“消息聚合”等方法,增加了 PDB 的可用性

结束语
本文主要介绍了 IBM 发布的一种并行环境下的命令行调试工具 PDB,并详细讲解了 PDB V5.3 的特点及使用方法。通过 PDB,技术人员可以在 AIX/Linux 系统上,更加方便、高效地完成对并行程序的调试。

关于作者
李荣,IBM 中国软件开发中心 HPC 部门的软件工程师,主要从事高性能计算相关的工作。



http://www.ibm.com/developerworks/cn/aix/library/1106_lirong_pdb/index.html

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP