VS 2015:断点目前不会被击中。没有为此文档加载任何符号

时间:2015-10-14 23:22:41

标签: c++ cmake visual-studio-2015 static-libraries

问题

我有一个C ++(* .cpp)文件,它是静态库项目的一部分,我不能放置一个活动的断点。当我这样做时,它给了我在这篇文章标题中看到的通知。 我可以在同一个项目中的任何其他C ++文件中放置断点,并且在调试期间它会被点击 。这个C ++文件没有什么特别之处。我使用CMake生成项目,我也引用可执行项目中的类。没有链接错误,只是调试器说没有为该源文件加载调试符号。我已经尝试了几种尝试和诊断错误的方法,而且在我的案例中我没有得到很好的答案。

我尝试了什么

  1. 将此文件与同一项目中的其他* .cpp文件进行比较:我交叉检查此测试文件与我测试的其他文件之间的编译器标记,以验证是否能够放置有效的断点。没有什么不同。
  2. 重建整个解决方案:正如您可能猜到的那样,这没有帮助
  3. 使用CMake重新创建整个解决方案:这也没有任何区别。
  4. 在源文件中包含main()并引用该文件中的类的文件:这有所不同。我能够在课堂上放置断点并且它的代码正在被执行,而以前,它不是。
  5. 有关代码的更多信息

    • 我所指的C ++文件是RoCreateCharacterSuccess.cpp
    • roREGISTER_PACKET的工作是在应用程序初始化时将此数据包类注册到另一个类(RoPacketTranslator)。
    • 注册数据包类时会调用constructor of RoCreateCharacterSuccess
    • 当断点未激活时,此构造函数不会被调用。我知道这是因为这个数据包类并不存在于它应该注册的类中。它类似于RoCreateCharacterSuccess.cpp,它永远不会成为它应该存在的静态库的一部分。但如果我故意更改文件以引入语法错误,那么库就无法构建。
    • 要使此文件能够拥有活动断点,我必须在应用程序中使用转换程序手动注册数据包。

    还有其他人见过这样的问题吗?我此刻难过,试图了解发生了什么。任何帮助揭示这里发生的事情都会很棒!感谢您抽出时间阅读这个问题。

    编辑:我忘了提到这个问题是诊断出来的,因为我试图诊断为什么字符创建数据包在{{3}时没有被翻译成RoCreateCharacterSuccess个对象}}。我后来发现RoCreateCharacterSuccess课程没有在RoPacketTranslator课程注册。试图设置一个断点来检查构造函数是否被调用导致了这个问题。

    解决方案

    感谢@ user1,我知道发生了什么。因此,在我的可执行文件the character gets successfully created中,我只访问了where I refer to this class (or an instance of it),它位于头文件中,并且可能由编译器内联到可执行文件中。就编译器而言,这是我与该类的唯一交互。我没有调用它RoCreateCharacterSuccess::getCharacter()。这意味着编译器有机会优化该部分代码(我确实打开了该选项)。

    解决方案:我将与RoCreateCharacterSuccess::getCharacter()交互的唯一方法的定义移到了cpp文件中,因此避免了内联和强制编译器链接到定义RoCreateCharacterSuccess类的静态库的一部分,从而触发向翻译类注册RoCreateCharacterSuccess类的行为。

1 个答案:

答案 0 :(得分:2)

首先,我在这里看不到任何 问题 。这不是C ++编译器或链接器的问题。

  

我可以在同一个项目中的任何其他C ++文件中放置断点   在调试过程中它会被击中。这没什么特别的   C ++文件。我使用CMake生成项目,我也参考了   可执行项目中的类。没有链接错误,只是   该调试器表示没有为此加载调试符号   源文件。

这里真正发生的是,当您的可执行程序没有在静态库中看到对模块 - RoCreateCharacterSuccess.cpp的显式调用时,它将不会链接到该模块。

如果程序需要在模块中定义符号,那么该模块将被链接;如果没有,它将被跳过。因此,RoCreateCharacterSuccess.cpp模块中的任何函数,符号都不会存在。

RoCreateCharacterSuccess.cpp被视为未使用的模块。

由于尚未为模块加载符号,因此Visual Studio最终报告不会命中断点。这很明显。

  

要使此文件能够拥有活动断点,我必须这样做   在应用程序中使用翻译器手动注册数据包。

当您在应用程序中使用转换程序模块手动注册数据包时,RoCreateCharacterSuccess.cpp模块已链接且断点可用。您可以在该模块中点击断点。

  

就像RoCreateCharacterSuccess.cpp永远不会成为静态的一部分   它应该是库。但如果我故意更改文件   为了引入语法错误,库无法构建。

BTW,对于任何程序都是如此,任何语法错误都会导致编译失败。我知道你这样做是为了检查你的程序是否加载了正确的模块,但这确实不是问题。

更新 @Vite Falcon我很高兴我的答案给了你一些提示,找出断点不活跃的原因。显然,正是编译器正在优化内联函数调用并打破模块和程序之间的连接。