是否必须以调试方式编译 Tensorflow C++ DLL 才能根据它调试/运行代码?

Posted

技术标签:

【中文标题】是否必须以调试方式编译 Tensorflow C++ DLL 才能根据它调试/运行代码?【英文标题】:Should Tensorflow C++ DLL be necessarily compiled in debug modus to be able to debug/run code depending on it? 【发布时间】:2021-12-29 11:23:36 【问题描述】:

目前我正在为一个专有软件编写扩展程序。不幸的是,日志并不完全可用,因此正在进行中。扩展使用 Microsoft Visual Studio 2019 编译为 DLL,此 DLL 依赖于 Tensorflow 2.6 DLL。该扩展基本上使用

加载保存的模型
LoadSavedModel(session_options, run_options, m_modelDir,  tensorflow::kSavedModelTagServe , &model_bundle_lite);

并使用

对图像进行推理
model_bundle_lite.GetSession()->Run(inputs_, output_names, , &predictions);

Tensorflow DLL 是根据说明使用 bazel 构建的。

如果我使用发布配置编译我的扩展,目前功能上似乎没有问题。我们想检查一些方面,使用调试配置编译我们的扩展并利用原始的 Tensorflow.dll。什么都没有改变,模型是一样的,图像是一样的。但扩展在LoadSavedModel(session_options, run_options, m_modelDir, tensorflow::kSavedModelTagServe , &model_bundle_lite); 处崩溃 标准catch 语句未捕获这些错误。我无法调试模型加载后的代码。

这种行为的原因是什么?我只想检查我们代码的功能,我不想自己调试 TF 函数。

【问题讨论】:

您是否尝试过为此使用结构化异常处理? 我试过这个。但它似乎不起作用,至少直接不起作用。 “不能在需要对象展开的函数中使用 __try”。对代码进行一点重组并将其放在单独的函数中并没有帮助。正在检查其他选项... 【参考方案1】:

在 Visual Studio 中,您可以通过禁用优化并启用调试输出来获取“发布”配置中的调试信息;只要您不更改运行时库并避免更改预处理器标志。

因此,“发布”配置实际上可以主要是“调试”配置。

这可以在每个项目(以及每个文件的某些设置)的基础上完成。

更多细节在: https://docs.microsoft.com/en-us/cpp/build/how-to-debug-a-release-build?view=msvc-170

并且 /Z7 调试格式可能在您的场景中具有优势。

但不要尝试混合“Debug”和“Release”项目配置,有些库调试设置不能这样禁用。

【讨论】:

感谢您的建议。我会试试的。 应该补充一点,您甚至不必禁用优化。调试优化代码更难,但并非不可能 - 并且可能需要触发一些错误。【参考方案2】:

混合调试和发布版本可能会导致基于生成代码的严重问题。调试构建可以使用一些特殊的调试分配器或其他你不知道的东西。

您可以尝试附加诸如 WinDbg 之类的内容并再次加载模型以获取有关该问题的更多信息。这经常帮助我查看在加载过程中是否引发了任何结构化异常。为此,您必须:

安装 Windb(谷歌即可) 打开它并将调试器附加到您的应用程序 尝试加载模型 检查日志并查找任何抛出的异常

【讨论】:

感谢您的建议(还有结构化异常处理)!我会试试这个。

以上是关于是否必须以调试方式编译 Tensorflow C++ DLL 才能根据它调试/运行代码?的主要内容,如果未能解决你的问题,请参考以下文章

C编译器中是不是有调试模式编译标志的标准?

GDB调试指南-启动调试

是否可以使用lldb调试gcc编译的程序,或者使用gdb调试clang编译的程序?

你真的会正确地调试TensorFlow代码吗?

调试选项 -g 如何更改二进制可执行文件?

如何使用 SSE4.2 和 AVX 指令编译 Tensorflow?