views:

588

answers:

4

I want to set a breakpoint in unmanaged C++, in Visual Studio 2005, but I would like to ignore this breakpoint if the call stack is in a specific function. Is there a way to do this?

A: 

You could put a DebuggerStepThrough attribute on the calling method, altho this will stop all breakpoints being hit on the calling method, rather than just the specific method

lomaxx
Is it possible with unmanaged code?
Jazz
A: 

Update: OP initially didn't make it clear at the beginning unmanaged C++ was being used. So this answer is pretty useless now because it'll only work with managed code. That said I'll leave it be in case someone stumbles over it and finds it usefulor didn't know about JMC:

Whilst DebuggerStepThrough is still a valid method to prevent stepping into code there are times when you do want to step in. This means having to locate and comment out the DebuggerStepThrough attribute.

.NET 2.0 introduced a new attribute: DebuggerNonUserCode. This works in conjunction with the Debug Just My Code setting in Tools->Options->Debugging->General->Enable Just My Code.

If Enable Just My Code is checked then any method decorated with the DebuggerNonUserCode attribute won't be stepped into. If you do want to re-enable debugging of code marked with DebuggerNonUserCode periodically then just uncheck this setting. This saves some time having to locate and comment out code you'd normally not be interested in stepping through.

To use either attribute just decorate the methods of your choosing like this:

// The .NET 1.1 way
[DebuggerStepThrough]
public static void IgnoreMeAlways()
{
    Console.WriteLine("Hello...where is everybody!");
}

//The .NET2.0/VS2005/2008 way. Use in conjunction with Debug Just My Code
[DebuggerNonUserCode]
public static void NonUserCodeSomeTimes()
{
    Console.WriteLine("Longtime no see");
}

HTH
Kev

Kev
It seems to only work with managed code, doesn't it?
Jazz
Yes...unfortunately. I guessed you may have been using managed C++
Kev
Unfortunately, it is unmanaged C++.
Jazz
Sadly the last time I touched unmanaged C++ was in VS6, a long time ago, so I doubt I'll be much help :(
Kev
Let's just keep this post at 0 so it sorts down... no need to slam Kev's rep...
Aardvark
Cheers dewd....if I'd known it was unmanaged c++ I would never have bothered making all that effort to achieve minus 1 :)
Kev
Thinking about this - even with this feature I'm not sure how this helps the problem??
Aardvark
Ja....now I've re-read it a few more times and seeing j's answer I see what he means now.
Kev
+3  A: 

If you have a commercial edition of Visual Studio, you should be able to set a breakpoint early in the calling routine, then change its "When Hit..." behaviour to "Run a macro". You'll need to write a macro that programmatically disables the breakpoint in the called function -- use this as the macro to run. (Hopefully someone else can describe how such a macro can be written.) Then set other breakpoints on all exit points of the calling function, and change their behaviour to reenable the breakpoint in the called function.

If you have an Express Edition, you'll find that the "Run a macro" checkbox is greyed out unfortunately. In this case, if you have access to the source code for the calling function, I suggest the following:

  1. Make a global int variable, bp_enabled, initially set to 1.
  2. --bp_enabled on the first line of calling_function().
  3. ++bp_enabled at all exit points of calling_function().
  4. Change the "Condition..." properties of the breakpoint in the called function to break only when bp_enabled == 1. (Go to Debug | Windows | Breakpoints, then right-click the breakpoint.)

A bit of a hack, but it gets the job done.

[EDIT: Fixed to work properly even if calling_function() happens to call itself recursively (either directly or indirectly)...]

j_random_hacker
If you can change the code there should be easier ways to make this happen - but j's idea is good.
Aardvark
With a macro, it's a bit slow, but it works great.
Jazz
A: 

You could put breaks on all the lines that call your method in question (except in that one caller routine you don't want to stop). I can see this being difficult if the routine is called from a lot of places, or invoked in non-obvious ways.

Changing the code just for debugging seems like the easiest - if possible.

Aardvark