I have something analogous to the following code snippets:
// file alpha.c
void function_A()
{
int i;
#include "code.h"
}
and
//file beta.c
void function_B()
{
int i;
#include "code.h"
}
and
// file code.h
for(i = 1;i < 10;i++)
{
// do some stuff
if (very_rare_event)
{
// do something else
}
}
Yes, I am fully aware that its breaking all sorts of coding practices, but that's another story (its all part of a very large, very complex, very old system and its not going to be changed any time soon).
My question is this: Is it possible to set a breakpoint within code.h at t开发者_JAVA百科he "// do something else" point, in a way that you can specify whether it is the instance of being included from alpha.c or beta.c? And if so, how?
Put #defines in the main files:
// 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"
}
Then in 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
}
}
Ok, I would like to tell you in lots of different ways why you need to change the system, but you've indicated that you are aware that this is not good and that it won't change so I'll try to refrain from doing that.
Could you perhaps do something along the lines of this:
// file alpha.c
void function_A()
{
int i;
const int foo = 1;
#include "code.h"
}
and set a conditional breakpoint in code.h with the condition foo == 1 ? Do the same thing but set foo = 2 for function B to break there.
Set a breakpoint in function_A
or function_B
, then Step Into the included code. You can then set a breakpoint where you need it.
This assumes that you've disabled most compiler and linker optimizations.
Use #define
s in your .c files, and #ifdef
s in the .h file. Put some non-operation (perhaps increment then decrement a counter) inside the #ifdef
, and set your breakpoint there. Note that you need to have some operation in there, as you can only set a breakpoint on an actual operation.
So:
// 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
}
}
Since something like this is probably needed only rarely, it probably wouldn't pay to figure out how to do it at the C source level or to jump through a bunch of hoops.
So, I'd probably just look at the disassembly for the function I wanted to break in and set the breakpoint at the assembly level.
As an experiment, I set a breakpoint on the line in code.h
normally, and the debugger's Breakpoint window showed up with a tree of breakpoints:
o code.h, line 9
|
+-- o code.h, line 9
|
+-- o code.h, line 9
Each entry could be disabled. There was no easy way to figure out which one corresponded to function_A()
and which was for function_B()
just by looking - I had to run the program with both enabled, and turn off the one I wasn't interested in when it was first hit. Not a great usability experience, but not too surprising given how rare the situation probably is.
If you need to do this more regularly, Visual C/C++ is supposed to let you fully specify a breakpoint using a "Context Operator":
{[function],[source],[module] } location
but I haven't been able to figure out how to actually use this syntax in the debugger IDE. If anyone has details, I'd appreciate a comment.
WinDBG in the Debugging tools for Windows also supports this syntax (or something very similar), but I can't verify exactly how (or if) it works at the moment).
精彩评论