views:

239

answers:

6

I am debugging a source code that has a lot of big #define'd MACRO routines. I am interesting in stepping into them, but I guess, VC++ does not allow step-in functionality ... so,

  • I am converting them into functions, but this is becoming hard for me

Is there a way to step into MACRO routines? especially in VC++?

PS: I can port the whole code into gcc, if gcc compiler supports stepping into MACRO

+1  A: 

To the best of my knowledge, the only debugger that could step into macros is out of business (SoftICE). Great example of why you shouldn't write 50-line macros, really. So, overall...good luck.

Michael Foukarakis
@Micheal, I am just the maintainer, and every time I encounter a big MACRO feel like shooting the person who wrote the code.
Alphaneo
You have it worse than everyone, then. :)
Michael Foukarakis
+1  A: 

Macros are compiled by the preprocessor, so the compiler will be incapable of generating debug info to step through macros.

Tullo
+2  A: 

Long answer. No.

You can generate a full listing of the macros expanded in Compiler options. It might help somewhat, but it won't give you debugger capabilities

cmroanirgo
+2  A: 

In addition to all correct answers above: what I usually do is to show mixed display (C+assembly). This shows what really happens. Even if you are no expert in the underlying assembly, it gives an idea what happens (i.e. is it a trivial replacement or a complex loop). Also it will provide additional opportunities to step into functions. For instance, if your macro is

#define foo(a) i++;foo_func(a,i)

your debugger will show something like looping and what kind of variables are used). You can use the macro definition as a reference to understand it.

00411454  mov         dword ptr [j],eax 
00411457  cmp         dword ptr [j],0Ah 
0041145B  jge         wmain+58h (411478h) 
    {
     foo(j);
0041145D  mov         eax,dword ptr [i] 
00411460  add         eax,1 
00411463  mov         dword ptr [i],eax 
00411466  mov         eax,dword ptr [i] 
00411469  push        eax  
0041146A  mov         ecx,dword ptr [j] 
0041146D  push        ecx  
0041146E  call        foo_func (411028h) 
00411473  add         esp,8 
    }

This gives a clue that variables i and j are used to call function foo_func.

If you use Visual C++, it will allow you to step into functions called from a macro (F11); not individual statements though.

Adriaan
Since this is the nearest to what I could do for my problem, I am accepting this answer.
Alphaneo
+1  A: 

When you use a macro, the code behind it is expanded all on to the same source code line, as far as the debugger is concerned. The debugger sees MY_MACRO(), and treats that single line no matter how much code is really inside the macro.

In C++, templates can do most of the things macros can, but they work much, much more elegantly. Since they're a real part of the language, you can step in to them with the debugger, too! For example:

// Macro FIND() - ugly, buggy, and can't ever be stepped in to by debugger!
#define FIND(begin, end, value) \
{ \
    for ( ; begin != end; ++begin) { \
        if (*begin == value) \
            break; \
    } \
}

// Templated find() - works beautifully and can be debugged like a real function!
template<typename Iter, typename T>
Iter find(Iter begin, Iter end, const T& value)
{
    for ( ; begin != end; ++begin) {
        if (*begin == value)
            return begin;
    }
}

Note: find() is of course a standard library function, but I've simply written this to compare it to a macro, to demonstrate how it can be debugged. Not to mention the macro version has lots of other problems. Rule of thumb: avoid macros for writing code whenever possible!

AshleysBrain
Firstly, Alphaneo uses a library and it is awkward to change all the marcros to templates. Secondly, templates are not available in C and people have many good reasons to use C only.
+1  A: 

Probably my answer is not helpful for VC++ users. On Unix, I do something like this:

gcc -E prog.c | indent > prog-formatted.c

i.e., you preprocess the program and reformat it.