如何精确定位长函数返回的位置 [英] How to pinpoint where a long function returns

查看:118
本文介绍了如何精确定位长函数返回的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有一个名为LongFunction的1000行代码的函数,我们使用它:

  bool bSuccess = LongFunction ); 
assert(bSuccess);

这里我在调试时得到了一个断言,我知道LongFunction有问题,找到函数在哪里遇到问题和返回:


  1. 我可以一步一步地调试它,


  2. 我可以搜索关键字return(或者更精确的搜索使用RegExp)


  3. #define return TRACE( LINE ); return


它有效,但有以下问题:




  • 它会打印太多的冗余信息,因为返回经常使用(或者我们可以使用一些EnvVar来打开或关闭它)

  • 以下情况:if(bOK)return true;



您有其他有关如何确定问题的创意吗? >

编辑
以下是一些细节让我们专注于这个问题。


  1. 这是关于C ++,而不是平台规范。


  2. 我们不想重构函数是的,我知道我们应该),我们甚至不想改变任何代码 - 在这一点上,我们只是想提供一些设施,使我们的应用程序调试更容易。


  3. LongFunction()有多个退出点,返回类型不需要bool(HRESULT,用户定义的错误代码...)


当前讨论的摘要:

我们有一些争议:


  1. 您应该重构该函数。

    是的,每个人都知道我们应该,但这不是重点。如果我打电话重构该功能,我不会在这里问问题。

    / li>
  2. 找到LongFunction()返回失败的位置不起作用。

    我总是第一个找到错误发生地点发生了什么,我很好奇为什么这不帮助,你在这种情况下做了什么? (假设我已经熟悉函数的工作原理)


我们有两个合理的解决方案:



  • 从Crashworks的ReturnMarker,函数中的堆栈对象将在函数返回时析构,在析构函数中设置断点将显示它返回的位置调试程序


  • CMyBool(x)from Binary& Sadsido,将LongFunction的返回类型更改为CMyBool,它可以从bool中得到结果,从LongFunction返回将禁止该对象,因此只需在构造函数中设置断点即可。



    1. 解决方案

      显然你应该重构这个函数,但在C ++中你可以使用这个简单的权宜之计在五分钟内处理: p>

        class ReturnMarker 
      {
      public:
      ReturnMarker(){};
      〜ReturnMarker()
      {
      dummy + = 1; //< - 把你的断点放在这里
      }
      static int dummy;
      }

      int ReturnMarker :: dummy = 0;

      ,然后在函数顶部实例化一个ReturnMarker。当它返回时,该实例将超出范围,你将击中析构函数。

        void LongFunction $ b {
      ReturnMarker foo;

      // ...
      }


      Suppose there is a function with 1000 code of line named LongFunction, and we used it:

      bool bSuccess = LongFunction();
      assert(bSuccess);
      

      Here I got an assert when debugging, and I know there is something wrong with LongFunction, so I need to find where the function meet problems and returns:

      1. I could probably debug it step by step, it works but is time-consuming, we don't what to do it this way.

      2. I could search the keyword "return" (or even more refined search use RegExp), and set breakpoint at those returns, it should be faster, but it is still tedious manual work which can't be automated.

      3. #define return TRACE(LINE); return

      It works but have following problems:

      • It will print too much redundant information as return is frequently used.(Or we could use some EnvVar to switch it on or off)
      • Does't work for following case: if(bOK) return true;

      Do you have any other creative ideas on how to pinpoint the problem?

      Edit: Here are some details to let us focus on the problem.

      1. It is about C++, and not platform specfic.

      2. We don't want to refactoring the functions(Yea, I know we should), we even don't want to change any code - at this point we just want to provide some facility to make our application debugging easier. I also believe this should be a common requirement, don't you ever run into this?

      3. The LongFunction() have multiple exit point, and the return type is not necessay bool(HRESULT, user defined errorcode...)

      Edit: A summary of current discussions:
      We have some controversies:

      1. You should refactor the function.
        Yea, everyone know that we should, but that is not the point.If I had make the call to refactor the function, I won't be here to ask the question.

      2. Find where the LongFunction() returns failure doesn't help.
        It is always the first thing I do to locate where the error occurs to know what happened, I am curious why this doesn't help, what did you do in this situation? (Assume I am already familiar with how the function works)

      And we have 2 reasonable solutions:

      1. ReturnMarker from Crashworks, a stack object in the function will destruct when function returns, set the breakpoint at the destructor will show you where it returns in debuger

      2. CMyBool(x) from Binary & Sadsido, change the return type of LongFunction to CMyBool which can contruct from a bool, return from LongFunction will contruct that object, so just set a breakpoint at the constructor will work.

      解决方案

      Obviously you ought to refactor this function, but in C++ you can use this simple expedient to deal with this in five minutes:

      class ReturnMarker
      {
         public:
         ReturnMarker()  {};
         ~ReturnMarker() 
         {
            dummy += 1; //<-- put your breakpoint here
         }
         static int dummy;
      }
      
      int ReturnMarker::dummy = 0;
      

      and then instance a single ReturnMarker at the top of your function. When it returns, that instance will go out of scope, and you'll hit the destructor.

      void LongFunction()
      {
          ReturnMarker foo;
      
          // ...
      }
      

      这篇关于如何精确定位长函数返回的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆