在 SWIG 接口后面调试 Tensorflow 的 C++ 代码

debugging Tensorflow's C++ code behind the SWIG interface

我不确定如何调试(大概是使用 GDB)SWIG 接口后面的 Python 代码。

我可以使用 ipdb 来观察 Tensorflow 的 Python 代码一直到 SWIG 包装器的执行(例如 session.py 中的 tf_session.TF_Run),但我会喜欢调试 SWIG 接口后面的 C++ 代码。

大概我用 bazel build --config debug 构建了 Tensorflow,但是当从 Python 接口调用时,如何将 gdb 附加到生成的代码?

TensorFlow 的 C++ 代码与调用它的 Python 代码在同一进程中执行(或者,如果您使用的是分布式版本,则与 Python 程序之一在同一进程中执行创建了 tf.GrpcServer).

Python 和 C++ 之间最简单的接口是 tensor_c_api.h 中的纯 C API。要拦截这些调用之一,您可以将 gdb 附加到 Python 解释器的进程 ID,即 运行 TensorFlow,并在其中一个函数上创建断点。

例如,使用交互式 Python 会话,在第一个终端中输入:

$ python
>>> import tensorflow
>>> import os
>>> os.getpid()
14680

然后,在另一个终端,开始gdb:

$ gdb -p 14680
[...]
(gdb) break TF_NewSession
Breakpoint 1 at 0x7f15f450a4d0
(gdb) continue
Continuing.

返回 Python 解释器,创建一个新会话:

>>> sess = tf.Session()

解释器将暂停,您的调试器将打印如下内容:

Breakpoint 1, 0x00007f15f450a4d0 in TF_NewSession () from [...]/tensorflow/python/_pywrap_tensorflow.so
(gdb) backtrace
#0  0x00007f15f450a4d0 in TF_NewSession () from [...]/tensorflow/python/_pywrap_tensorflow.so
#1  0x00007f15f3ac5cdb in _wrap_TF_NewSession () from [...]/tensorflow/python/_pywrap_tensorflow.so
#2  0x000000000049968d in PyEval_EvalFrameEx ()
#3  0x00000000004a090c in PyEval_EvalCodeEx ()
#4  0x0000000000499a52 in PyEval_EvalFrameEx ()
[...]

您现在可以使用 gdb 的全部功能来调试 TensorFlow。