【问题标题】:Can I set a breakpoint in included code?我可以在包含的代码中设置断点吗?
【发布时间】:2010-01-12 18:04:59
【问题描述】:

我有类似下面代码sn-ps的东西:

// file alpha.c
void function_A()
{
    int i;
    #include "code.h"
}

//file beta.c
void function_B()
{
    int i;
    #include "code.h"
}

// file code.h
for(i = 1;i < 10;i++)
{
    // do some stuff
    if (very_rare_event)
    {
        // do something else
    }
}

是的,我完全意识到它破坏了各种编码实践,但那是另一回事(它是一个非常庞大、非常复杂、非常古老的系统的一部分,并且不会很快改变)。

我的问题是:是否可以在 code.h 中的“//做其他事情”点设置断点,您可以指定它是从 alpha.c 中包含的实例还是beta.c?如果有,怎么做?

【问题讨论】:

    标签: c visual-studio-2008 breakpoints


    【解决方案1】:

    将#defines 放在主文件中:

    // file alpha.c
    #define BREAK_FOR_ME 'A'
    void function_A()
    {
        int i;
        #include "code.h"
    }
    
    // file beta.c
    #define BREAK_FOR_ME 'B'
    void function_B()
    {
        int i;
        #include "code.h"
    }
    

    然后在code.h中:

    // file code.h
    for(i = 1;i < 10;i++)
    {
        // do some stuff
        if (very_rare_event)
        {
    
        #ifdef BREAK_FOR_ME
            switch (BREAK_FOR_ME)
            {
            case 'A':
                // set breakpoint here...
                break;
    
            case 'B':
                // or here...
                break;
            }
        #endif
    
            // do something else
        }
    }
    

    【讨论】:

    • +1 巧妙的开关使用。由于常量 switch 表达式可能会收到编译器警告,但如果您正在编写包含这样的代码,我认为编译器警告可能是您最不担心的。
    • 当只涉及几个文件并且您不想太频繁地更改或添加断点位置时,这可能没问题。但它并不能很好地扩展 - 太多了,而且您可能正在接近修复古怪编码实践的努力水平。
    【解决方案2】:

    好的,我想用很多不同的方式告诉你为什么需要更改系统,但你已经表示你知道这不好并且不会改变,所以我会尝试避免这样做。

    您可以按照以下方式做一些事情吗:

    // file alpha.c
    void function_A()
    {
        int i;
        const int foo = 1;
        #include "code.h"
    }
    

    并在 code.h 中设置条件断点,条件为 foo == 1 ?做同样的事情,但设置 foo = 2 让函数 B 在那里中断。

    【讨论】:

      【解决方案3】:

      function_Afunction_B 中设置断点,然后单步执行包含的代码。然后,您可以在需要的地方设置断点。

      这假设您已禁用大多数编译器链接器优化。

      【讨论】:

        【解决方案4】:

        在 .c 文件中使用 #defines,在 .h 文件中使用 #ifdefs。在#ifdef 中放置一些非操作(可能先递增然后递减一个计数器),然后在此处设置断点。请注意,您需要在其中进行一些操作,因为您只能在实际操作上设置断点。

        所以:

        // file alpha.c
        #define FILE_ALPHA
        void function_A()
        {
            int i;
            #include "code.h"
        }
        #undef FILE_ALPHA
        
        //file beta.c
        #define FILE_BETA
        void function_B()
        {
            int i;
            #include "code.h"
        }
        #undef FILE_BETA
        
        // file code.h
        for(i = 1;i < 10;i++)
        {
            // do some stuff
            if (very_rare_event)
            {
                // do something else
                #if defined FILE_ALPHA
                    i++; //Set breakpoint here...
                    i--;
                #elif defined FILE_BETA
                    i++; //...or here...
                    i--;
                #else
                    i++; //...or here.
                    i--;
                #endif
            }
        }
        

        【讨论】:

          【解决方案5】:

          由于可能很少需要这样的东西,因此在 C 源代码级别弄清楚如何做到这一点或跳过一堆麻烦可能是不值得的。

          所以,我可能只是查看我想要中断的函数的反汇编并在汇编级别设置断点。

          作为一个实验,我通常在code.h的行上设置了一个断点,调试器的Breakpoint窗口出现了一个断点树:

          o  code.h, line 9
          |
          +-- o   code.h, line 9
          |
          +-- o   code.h, line 9
          

          可以禁用每个条目。没有简单的方法可以通过查看来确定哪个对应于function_A(),哪个对应于function_B() - 我必须在启用两者的情况下运行程序,然后关闭我不感兴趣的那个第一击。不是一个很好的可用性体验,但考虑到这种情况可能非常罕见,也不会太令人惊讶。

          如果您需要更频繁地执行此操作,Visual C/C++ 应该允许您使用 "Context Operator" 完全指定断点:

          {[function],[source],[module] } location
          

          但我无法弄清楚如何在调试器 IDE 中实际使用此语法。如果有人有详细信息,我将不胜感激。

          Debugging tools for Windows 中的 WinDBG 也支持这种语法(或非常相似的东西),但我目前无法准确验证它是如何(或是否)工作的)。

          【讨论】:

            猜你喜欢
            • 2011-07-11
            • 2019-11-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-01-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多