为啥 Visual C++ 不会在特定函数中遇到断点或单步执行?
Posted
技术标签:
【中文标题】为啥 Visual C++ 不会在特定函数中遇到断点或单步执行?【英文标题】:Why does Visual C++ not hit a breakpoint in, or step through a specific function?为什么 Visual C++ 不会在特定函数中遇到断点或单步执行? 【发布时间】:2008-11-19 17:51:19 【问题描述】:我有以下几点:
classA::FuncA()
... code
FuncB();
... code
classA::FuncB(const char *pText)
SelectObject(m_hDC, GetStockObject ( SYSTEM_FONT));
wglUseFontBitmaps(m_hDC, 0, 255, 1000);
glListBase(1000);
glCallLists(static_cast<GLsizei>(strlen(pText)), GL_UNSIGNED_BYTE, pText);
我可以在 FuncA 的任何地方打断点。如果我尝试进入 FuncB,它就会跳过。它将接受 FuncB 中的断点,但从不命中它。我知道它正在执行 FuncB,因为我可以在 FuncB 中调用 MessagBox() 并获取消息框。
在远离大量 VC6 使用几年之后,我是 VS2005 的新手。我在 VC6 的日子里回忆起的一种情况是,如果符号信息不可用。但是,在这种情况下,两个函数都在同一个文件中,因此符号信息必须正确。同样在那种情况下,我认为您甚至无法设置断点。
我已经尝试了所有愚蠢的巫术,比如重建整个解决方案。
我忽略了什么愚蠢的事情?
编辑:添加了 FuncB 的代码,以回应关于它可能基本上可以内联的评论。 (这只是来自 MSDN 的 wglUseFontBitmaps [减去 cmets 这里] 的确切示例代码)。我看不出内联会如何阻碍单步执行每个调用。
【问题讨论】:
【参考方案1】:确保禁用所有编译器优化 (/Od)。编译器优化可能会导致调试器断点出现问题。
【讨论】:
是的,就像断点处的代码可能已经不存在了。【参考方案2】:不确定问题出在哪里,但您可以尝试的一件事是查看反汇编代码。您可以使用 VS 在源代码和禁用视图之间切换。我在工作中没有 IDE,所以条款可能会略有偏差。
如果您将调试器置于此模式,您可以看到正在执行的汇编指令。这有时有助于确定这类问题。有时,虽然通常不使用调试版本,但调用会被编译器优化。
【讨论】:
【参考方案3】:如果一切都失败,请尝试更新到 VS2005 SP1(如果您还没有)...
听起来确实很奇怪!
【讨论】:
【参考方案4】:感谢您发布代码。这显然不是我的猜测。
为了后代,为了澄清问题,我的猜测是,如果 (1) 函数是一行并且 (2) 编译器内联函数,那么 (3) 调试器可能不知道如何进入它.这个猜测依赖于some debuggers do have trouble with inlined code and other compiler optimizations.我对 Visual Studio 的调试器不够熟悉,无法说出它是否在该列表中。
在大多数使用 stabs 格式的系统上,-g 允许使用只有 GDB 才能使用的额外调试信息;这些额外的信息使 GDB 中的调试工作更好,但可能会使其他调试器崩溃或拒绝读取程序。 ...
GCC 允许您将-g 与-O 一起使用。优化代码所采取的捷径有时可能会产生令人惊讶的结果:您声明的某些变量可能根本不存在;控制流可能会短暂地移动到您没有预料到的地方;某些语句可能无法执行,因为它们计算常量结果或它们的值已经在手边;有些语句可能会在不同的地方执行,因为它们被移出循环。
GCC 手册曾经有一个声明,即某些编译器会拒绝在优化代码中发出调试符号,因为它们的调试器无法遵循它。
【讨论】:
【参考方案5】:其实我也遇到过类似的问题,在运行程序时发现代码没有被编译,所以在尝试运行之前确保你“编译”了程序
【讨论】:
以上是关于为啥 Visual C++ 不会在特定函数中遇到断点或单步执行?的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 2022 中调试时,C++ 语言的子函数内“读取字符串字符时出错”,这是为啥?
如何在 Visual Studio Express 2013(C++) 中获取特定驱动器的当前目录?
C++ 中的舍入值。为啥 printf、iostream 和 round 函数 [可能] 表现不同,具体取决于 Visual Studio 和 Windows 版本?