使用XGDB调试
XGDB 是基于GDB扩展的工具,它可以用于调试多tile的Xcore应用,即 .xe 格式的应用。因此,XGDB在设计时,尽可能与GDB保持一致,因此关于本工具的大部分信息可以在第三方网站和资源中找到(即GDB) 。
它用于调试多tile应用的方式比较特殊;下面的例子旨在展示如何使用XGDB来跟踪一个Xcore应用,应用的功能是将一个int值从一个核心传递到另一个核心,或者从一个tile传递到另一个tile,并在传递时打印当前的tile_core名称。
创建示例
为了演示使用XGDB进行调试,我们创建了一个跨两个tile,共4个core运行的传递token的有向环:
建立文件multitile.xc,为main.c提供多tile的入口点:
#include <platform.h>
typedef chanend chanend_t;
extern "C" {
void main_tile0(chanend_t, chanend_t);
void main_tile1(chanend_t, chanend_t);
}
int main(void)
{
chan tile0_to_tile1;
chan tile1_to_tile0;
par {
on tile[0]: main_tile0(tile1_to_tile0, tile0_to_tile1);
on tile[1]: main_tile1(tile0_to_tile1, tile1_to_tile0);
}
return 0;
}
在每个tile上,我们通过两个核心传递token,由**tile[1]**启动有向环:
#include <stdio.h>
#include <xcore/channel.h>
#include <xcore/parallel.h>
DECLARE_JOB(process, (chanend_t, chanend_t, char *, int));
void process(chanend_t cIn, chanend_t cOut, char * name, int init)
{
if (init)
{
chan_out_word(cOut, 1);// 将初始值1传出
}
while (1)
{
int token = chan_in_word(cIn);
printf("%s\n", name);
chan_out_word(cOut, token);
}
}
void main_tile0(chanend_t cIn, chanend_t cOut)
{
channel_t chan = chan_alloc();
PAR_JOBS(
PJOB(process, (cIn, chan.end_a, "tile0-core0", 0)),
PJOB(process, (chan.end_b, cOut, "tile0-core1", 0)));
chan_free(chan);
}
void main_tile1(chanend_t cIn, chanend_t cOut)
{
channel_t chan = chan_alloc();
PAR_JOBS(
PJOB(process, (cIn, chan.end_a, "tile1-core0", 0)),
PJOB(process, (chan.end_b, cOut, "tile1-core1", 1))); // 启动有向环
chan_free(chan);
}
按照正常方式构建示例,记得使用 xcc -g:
xcc -target=XU316-1024-QF60B-C24 -g multitile.xc main.c
运行示例会产生预期的结果,token在整个环之间传递:
$ xrun --io a.xe
tile0-core0
tile0-core1
tile1-core0
tile1-core1
tile0-core0
tile0-core1
...
交互式调试
现在,我们将使用XGDB观察多tile示例,这个token从core到core,从tile到tile传递。
要开始交互式调试会话:
xgdb a.xe
这将引发一个熟悉的GDB提示符。使用“connect”和“load”命令连接到目标硬件并加载XE应用:
(gdb) connect
0x00040000 in _start ()
(gdb) load
Loading setup image to XCore 0
...
使用tile 命令选择一个tile作为后续命令的焦点:
(gdb) tile 0
[Switching to task 1 (tile[0] core[0])]#0 0x00040000 in _start ()
以通常的方式添加断点:
(gdb) break main.c:16
Breakpoint 1 at 0x40156: file Z:/docs/docs_tools/tools-user-guide/tools-guide/quick-start/examples/debug\main.c, line 16.
切换到tile [1] 并在那里也添加一个断点:
(gdb) tile 1
[Switching to task 2 (tile[1] core[0])]#0 0x00040000 in _start ()
(gdb) break main.c:16
Breakpoint 2 at 0x4015a: file Z:/docs/docs_tools/tools-user-guide/tools-guide/quick-start/examples/debug\main.c, line 16.
查看所有断点。请注意,断点在每个tile上出现的地址不同-这是可以预料的,因为两个tile具有完全独立的地址空间,可能具有不同的内容:
(gdb) info breakpoints
Num Type Disp Enb Core Address What
1 breakpoint keep y 0 0x00040156 in process at Z:/docs/docs_tools/tools-user-guide/tools-guide/quick-start/examples/debug\main.c:16
2 breakpoint keep y 1 0x0004015a in process at Z:/docs/docs_tools/tools-user-guide/tools-guide/quick-start/examples/debug\main.c:16
现在,我们已经准备好运行多tile应用程序。使用 continue 和 info threads 命令运行应用程序到下一个断点,并检查它停在哪个tile/核心上:
(gdb) continue
[Switching to tile[0] core[0]]
Breakpoint 1, process (cIn=2147614978, cOut=2147615234, name=0x4511c "tile0-core0", init=0) at Z:/docs/docs_tools/tools-user-guide/tools-guide/quick-start/examples/debug\main.c:16
16 printf("%s\n", name);
Current language: auto; currently minimal
(gdb) info threads
4 tile[1] core[1] (dual issue) 0x000403c4 in chan_in_word ()
3 tile[1] core[0] (dual issue) 0x000403c4 in chan_in_word ()
2 tile[0] core[1] (dual issue) 0x000403f4 in chan_in_word ()
* 1 tile[0] core[0] process (cIn=2147614978, cOut=2147615234, name=0x4511c "tile0-core0", init=0) at src/xgdb-debug/main.c:16
每个线程旁的星号显示了后续命令当前聚焦的Tile/核心。通过重复发出continue和info threads命令,观察星号*****随着token在有向环中移动。
要结束交互式调试会话:
(gdb) quit
脚本调试
XGDB的使用可以通过命令文件(就像GDB那样)完全或部分脚本化。使用命令文件进行脚本调试的功能非常强大。它允许开发人员快速重现特定场景,甚至与其他开发人员共享这些场景。 要启动脚本调试会话,请使用xgdb -ex与标准GDB source命令:
$ xgdb -ex "source -v cmds.txt" a.xe
这条命令会使得GDB在任何交互式调试之前执行以下命令文件;下例中的结尾quit意味着这次GDB调试不会有任何交互,因此该示例完全是脚本化的。
# Setup
connect
load
# Add breakpoints
tile 0
break main.c:16
tile 1
break main.c:16
info breakpoints
# Run
set $count=5
while $count > -1
continue
info threads
set $count=$count-1
end
quit
总结
本教程演示了如何使用XGDB调试多tile Xcore应用程序。要进一步探索基于GDB构建的XMOS特定命令,请尝试:
(gdb) help xmos