cuda-gdb 支持内置变量的实现机制
cuda 编程会使用到的诸如 threadIdx、blockIdx 等内置变量。cuda-gdb 调试 cuda 代码时,也需要支持这些内置变量相关的调试,例如直接 p 这些内置变量,或者使用这些内置变量设置条件断点,cuda-gdb 的用户手册中也说明了条件断点支持使用内置变量。
那么 cuda-gdb 是如何实现内置变量的支持的呢?
首先,想到的是将内置变量放到调试信息中。但是,通过搜索 cudump 解析的调试信息,并没有找到内置变量的信息。这说明内置变量不是放在调试信息中。此外,非 debug 版本程序的调试也支持内置变量,这也能说明内置变量不可能放到调试信息中。
然后,直接调试 cuda-gdb 源码,分析内置变量的来源。
编译 debug 版本的 cuda-gdb 源码(nv 直接开放 cuda-gdb 源码,例如 这里),使用 gdb 调试 cuda-gdb (gdb --args cuda-gdb a.out
),可以从 lookup_symbol
函数作为入口,关于 gdb 调试信息更多背景知识,可以戳 GDB 源码分析系列文章三:调试信息的处理、符号表的创建和使用。最后在一个名为 <anonymous_objfile
> 的特殊 objfile 的符号表中找到了内置变量的信息:
调用栈如下:
最后,查找 <anonymous_objfile> 的特殊 objfile 的创建。到这里就很容易找到根源了,原来 cuda-gdb 是为内置变量创建了一个特殊的 objfile,然后将内置变量放入到这个 objfile 的符号表中,具体见 cuda_create_builtins_objfile
函数:
这样,在流程上,对内置变量的处理就和普通变量一样了,兼容性非常好。
不得不说,这是一个简单而巧妙的方案。