debugging 如何在C++中的空语句上设置断点?

jpfvwuh4  于 2022-11-14  发布在  其他
关注(0)|答案(7)|浏览(227)

具体地说,我想编写一个
1)允许我设置断点
2)不执行任何其他操作
3)不引起编译器警告

#define NO_OP   ((void)0)

void main()
{
    bool b = true;
    if (b)
        NO_OP;  // I try to set a breakpoint here, but

}               // it jumps to here (in Visual Studio 2010)

我也试过

#define NO_OP   (assert(1))             // doesn't work
#define NO_OP   (sizeof(int))           // doesn't work
#define NO_OP   __asm{}                 // doesn't work
#define NO_OP   do {(void)0;} while(0)  // warning: conditional is constant

到目前为止唯一管用的就是

#define NO_OP   { int x = 0; x = x; }

一定有更好的办法。

编辑

谢谢Blorgbeard,__asm{ nop }确实可以工作。但是我刚刚意识到任何带括号的东西都不完美(有问题吗?),因为它在后面留下了一个无用的分号。(后来)我对汇编程序一窍不通,但是我试着去掉括号,瞧!答案就在这里:谢谢!
"为好奇的人“
下面是一个不那么荒谬的例子:

string token = GetNextToken();
if (!Ignore(token))
{
    // process token
    DoThis(token);
    DoThat(token);
}

这段代码是完整的--只要程序能正常运行,我并不关心被忽略的令牌的任何信息。

string token = GetNextToken();
if (Ignore(token))
{
    NO_OP; // when desired, set breakpoint here to monitor ignored tokens
}
else
{
    // process token
    DoThis(token);
    DoThat(token);
}
ggazkfy8

ggazkfy81#

在msvc x64上,有一个内部函数:

__nop;

头文件:<intrin.h>
文件:https://learn.microsoft.com/en-us/cpp/intrinsics/nop?view=msvc-170

exdqitrt

exdqitrt2#

__asm int 3怎么样?还有,优化启用了吗?这可能是其他失败的原因(实际上从未尝试在它们上中断)。

yzckvree

yzckvree3#

你可以定义一个全局的unsigned int debug_counter,那么你的“no-op”宏就可以是debug_counter++。很肯定编译器不会删除它,但是绝对肯定的是,在某个地方放一些代码来打印计数器的值。

sqserrrh

sqserrrh4#

myassert.h中定义并在应用程序中的任何位置包含(在Visual Studio?中强制包含)。

// Works cross-platform. No overhead in release builds
#ifdef DEBUG

    // This function may need to be implemented in a cxx module if
    // your compiler optimizes this away in debug builds
    inline bool my_assert_func(const bool b)
    {
        // can set true/false breakpoints as needed
        if (b) {
            return true;
        }
        else {
            return false;
        }
    }

    #define myassert(b) assert(my_assert_func(b))

#else // RELEASE

    // In release builds this is a NOP
    #define myassert(b)    ((void)0)

#endif

#define DEBUG_BREAKPOINT myassert(true)

现在您可以:

string token = GetNextToken();
if (Ignore(token)) 
    DEBUG_BREAKPOINT;
}
else {
    // process token
    DoThis(token);
    DoThat(token);
}
abithluo

abithluo5#

实际的无操作指令:

__asm nop
dffbzjpn

dffbzjpn6#

也许你可以这样做:

#define BREAKPOINT __asm { int 3; }

这将调用中断3,这是断点中断。这将在代码中设置一个断点,它被 * 编译 * 为代码的一部分。
现在,如果你只想在某个操作上设置断点,除了允许你在那一行上中断之外,它实际上什么也不做。我认为你必须在不优化的情况下编译代码,因为你实现的NO_OP很可能会被优化编译器在代码之外优化,而优化开关是打开的。
另一点是,这似乎是一件非常奇怪的事情。据我所知,人们通常会在一行代码上设置一个断点。看看变量状态是什么,一次步进一行,等等。我真的不明白在一行代码上设置一个断点对你的程序没有任何意义,这将帮助你调试任何东西。

nhjlsmyf

nhjlsmyf7#

C++03:

inline void __dummy_function_for_NO_OP () {}
#define NO_OP __dummy_function_for_NO_OP ()

int main () {
    NO_OP;
}

C++11语言:

#define NO_OP [](){}()

int main () {
    NO_OP;
}

相关问题