我怀疑我们在VS2013中遇到了编译错误。设置单个断点实际上会将断点插入到代码的两个不同地址中。
我在源文件(MessageServerManager.cpp
)的第89行设置断点。下面是代码部分的一个片段(类中的常规方法):
87: void MessageServerManager::setup_dsp_emulation()
88: {
89: auto dsp_emulation_setting = util::get_env_var("DSP_EMULATION");
90: _emulating_dsp = !dsp_emulation_setting.empty();
91:
92: if (_emulating_dsp)
当我这样做时,VS2013的断点窗口中会出现一个断点。但是,当构建并执行代码时(顺便关闭优化),视图将更改为以下内容:
请注意,这两个断点位于不同的地址。当第一个断点被击中时,VS中突出显示的行是第89行,但是当查看反汇编时,它实际上是另一段代码(对象的构造函数)。
由于它位于对象构造函数中,因此分享如何创建此对象可能是个好主意。这是一个单身,基本上如下所示:
class MessageServerManager : public boost::basic_lockable_adapter < std::recursive_mutex >
{
public:
inline static MessageServerManager& instance() { static MessageServerManager manager; return manager; }
void start_dsp_facing_server();
private:
MessageServerManager();
}
我们第一次访问MessageServerManager
时,我们正在调用start_dsp_facing_server()
(它是main()
的前几行之一):
MessageServerManager::instance().start_dsp_facing_server();
以下是位于错误位置的断点的反汇编代码。显示的C ++代码是应该设置断点的方法(start_dsp_facing_server()
),但反汇编的代码明显不同(它是构造函数):
87: void MessageServerManager::setup_dsp_emulation()
88: {
89: auto dsp_emulation_setting = util::get_env_var("DSP_EMULATION");
011AAB8F push 0
011AAB91 mov ecx,dword ptr [this]
011AAB94 add ecx,8
011AAB97 call std::shared_ptr<messaging::IMessageServer>::shared_ptr<messaging::IMessageServer> (010619C9h)
011AAB9C mov byte ptr [ebp-4],1
90: _emulating_dsp = !dsp_emulation_setting.empty();
011AABA0 push 0
011AABA2 mov ecx,dword ptr [this]
011AABA5 add ecx,10h
011AABA8 call std::unique_ptr<radian::SimpleThread,std::default_delete<radian::SimpleThread> >::unique_ptr<radian::SimpleThread,std::default_delete<radian::SimpleThread> > (0106E5CAh)
011AABAD mov byte ptr [ebp-4],2
91:
92: if (_emulating_dsp)
93: {
如果我查看断点另一个位置的反汇编,该部分也会显示第89行,但它是正确的反汇编。
这是在VS2013更新4,C ++本机应用程序中,与Boost 1.56.0和Qt 5.3.1,32位链接。
有没有人见过这个,知道潜在的原因,以及可能的解决方案?
我见过this question (and the suggestion about line endings),我知道优化可以重新排序代码并导致奇怪的调试器行为,但我批量转换我的文件以确保它们具有正确的行结尾,并且我们已经优化了关闭。
我会发布一个显示此行为的最小示例,但我无法使用其他代码按需重现此内容。