Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pinpoint where a long function returns

Tags:

c++

c

return

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.

like image 968
Baiyan Huang Avatar asked Aug 21 '09 10:08

Baiyan Huang


2 Answers

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;

    // ...
}
like image 119
Crashworks Avatar answered Sep 28 '22 00:09

Crashworks


Sounds like it's time to refactor LongFunction()...

A 1000 line function is a bad code smell. Spend the time refactoring it into smaller, more maintainable functions. You'll find the bug(s) while you're at it, and it will be a worthwhile investment for the future.

like image 35
Roddy Avatar answered Sep 27 '22 23:09

Roddy