I'm debugging an application (C++), and I've found a point in the code where I want to change a value (via the debugger). So right now, I've got a breakpoint set, whereupon I do:
Debugger reaches breakpoint
I modify the variable I want to change
I hit F5 to continue running
lather, rinse, repeat
It's hitting this breakpoint a lot, so I would like to automate this. I would like to set the Breakpoint to run a macro, and continue execution.
However, I have no experience writing VisualStudio macros, so I don't know the commands for modifying a variable of the executing program. I've looked around, but haven't found anything helpful online so far.
I found how to do this with a macro. Initially, I tried using Ctrl-Shift-R to record a macro of keystrokes, but it stopped recording when I did Ctrl-Alt-Q. But I was able to edit the macro to get it to work. So here's what I did, in case anyone else wants to do something similar.
Tools -> Macros -> Macro Explorer
Right Click -> New macro
Public Module RecordingModule
Sub setvalue()
DTE.Debugger.ExecuteStatement("variable_name=0")
End Sub
End Module
This macro will execute the assignment statement, setting my variable (in this case, making it a NULL pointer).
Right Click on a BreakPoint -> When Hit...
Check "Run a macro"
Select Macros.MyMacros.RecordingModule.setvalue
Check "Continue execution"
Click OK
Then, I was able to run my program, automatically adjusting a pointer to NULL as it went. This was very useful for testing, and did not require recompiling.
Looking for similar today and found that you can also use the 'Print a message:' option instead of a macro. Values from code can be printed by placing them inside {}. The key is that VS will also evaluate the content as an expression - so {variable_name=0} should achieve the same as the macro example.
If you are think of a macro in the same way as Microsoft excel, then you're out of luck. It doesn't quite work that way.
In C++, a macro refers to a small inline function created with #define. It is a preprocessor, so a macro is like using a replace on all its references with its body.
For example:
#define add(a,b) ((a)+(b))
int main() {
int a=3, b=4, c=5, d=6, e, f;
d = add(a,b);
e = add(c,d);
}
Would like to the c++ compiler as:
int main() {
int a=3, b=4, c=5, ...;
d = ((a)+(b));
e = ((c)+(d));
}
Now, back to your question. If the variable is within scope at this breakpoint, just set it from within your code:
myVar = myValue;
If it is not, but it is guaranteed to exist, you may need a little hack. Say that this variable is an int, make a global int pointer. If this variable is static, make sure to set it to its address, and back to NULL inside it's scope. If it is dynamic, you may need some extra work. Here is an example:
int* globalIntPointer;
void func() {
*globalIntPointer = 3;
//...
}
int main() {
int a = 5;
globalIntPointer = &a;
func();
//...
globalIntPointer = NULL; // for safety sake
return 0;
}
You can execute a VS macro when a breakpoint is hit (open the breakpoints window, right click on the breakpoint in question, and select "When Hit..." off the popup menu). I'm less certain about writing a macro that modifies a variable of the program under debug though -- I've never done that, and a quick try with attempting to record a macro to do it doesn't seem to work (all it records is activating the right window, not changing the value).
Select "Condition..." and write an assignment for the variable in question in the "Condition:" textbox. This will naturally resolve to "true" with it not being an actual conditional test. Therefore, the breakpoint is never hit, and your variable has been set accordingly.
Related
I'm currently writing some kind of a "skeleton" for tests to be performed using Lauterbach scripts.
In this skeleton I want to have a part in which all test specific definitions shall be done, e.g. functions to set breaks on, variables to be altered etc. This part shall be just near the top of the script file, so that other users do not have to go through the complete script file, changing values here and there.
Some of the variables that'll be used are defined function-local within the C-code to be tested. So, these become available to the Lauterbach script only once the scope of that function has been entered - which is deeply within the skeleton script code.
Is there a way to define a macro for these variables just way before the scope has been entered?
Let's give some example structure:
LOCAL &funcToTest // the function we want to test
LOCAL &varToBeSet // a variable within the function we want to alter
LOCAL &valueToBeSet // the value we want to set &varToBeSet to
... // some more definitions here
&funcToTest=someFunc
&varToBeSet=status
&valueToBeSet=1
... // some test code following here that sets up log files, screen areas
... // start the program to be tested etc.
IF (Register(PC)==ADDRESS.OFFSET(&funcToTest))
(
// OK - we've hit the breakpoint inside the function to test
... // Run to some point where we can set the local variable
Var.Set &varToBeSet=&valueToBeSet
... // Go on with the program and see what happens - this will be logged
)
The problem is that Lauterbach complains at the line &varToBeSet=status
with Symbol not found in this context - which is correct, because it is a local variable.
Looking at the symbols via View->Symbols->SymbolsTreeView (or by giving the command Symbol.List.Tree) I can find the symbol (in this particular case found under the node some_module.some_function.status). Clicking on it gives the information in the TRACE32 status status line \\some_app\some_module\some_func\status with type (auto STATUS), scope local, location stack.
Changing my script to read &varToBeSet=\\some_app\some_module\some_func\status instead of &varToBeSet=status, however, does not help much. In this case Lauterbach complains with no access to that symbol.
Is there a way, I can delay evaluation of the macro to some point where it is actually used instead of having it evaluated when it is defined?
Use quotes:
&varToBeSet="\\some_app\some_module\some_func\status"
Is there any way to change value of variable to on a conditional breakpoint and continue execution.
My code is like this
switch(var){ //conditional breakpoint on this line
case 1:
break;
...
}
I put conditional breakpoint like below
(var == 0 ) || (var ==1) is true
So when this breakpoint hits, I want to change var = 2, and continue execution.
What I found: I found Action also, but it only log messages. Is there any way to executing a statement like var = 2 as Action taken on this conditional breakpoint.
I don't want to change code because building it takes hell lot of time.
Note: I am working C++ on Visual studio 2015
In Log a message to Output Window write {my_variable=12345} the side effect of log output is assigning 12345 to my_variable.
Take into account that Log a message can accept and evaluate complex expressions in curly braces.
You can modify a variable directly in memory to change the execution flow through a quick watch (Shift+F9) or watch window in Visual Studio.
Make sure that in Tools / Options / Debugging you have the "Enable Edit and Continue" Enabled/Checked and then you will be able to edit your code while debugging and continue without the need to rebuild or to stop execution.
More information can be found in How to: Enable and Disable Edit and Continue
This used to work, I can't seem to get it to work now. Worked excellent on loops and also good for altering values without altering the source or the code (and accidently committing it).
Conditional break point, break if true
(url = "http://localhost:1234/") != url
This works thanks to assignment always returns it's assigned value. This will never be true as url becomes localhost
HI,
I am very much new to using Visual studio.
I am trying to debug an application.
where i came across a statement like below:
double tmp =
myPart->bat_qty() * timeFactor / myPart->AUB() * myPart->UCost * myAIM->param->myAnalysisParams->wd_year;
in VS when put the cursor at
timeFactor
myPart->UCost
myAIM->param->myAnalysisParams->wd_year
it shows the corresponding values.But Not of the values returned by
myPart->bat_qty()
myPart->AUB()
what is the easiest way to find the values returned by those functions.
Apologies if this appears to be a cliche kind of a query.But i am completely new to VS.
I need a better way to find the values returned without editing the files for storing the values in some temporary variables.i mean i sould not edit the files.
In VS 2010 you can put the breakpoint at the function call site and activate the "Autos" Window (if the Autos window is not visible you can make it visible from Debug -> Windows -> Autos Ctrl + Alt + V, A). In the Autos Window after you step over the function call (F10) you will see something in the lines of:
Name Value Type
[Func] Returned [Return Value] [Return Type]
where [Return Value] and [Return Type] are the appropriate return value and type for your function named [Func].
I hope this helps.
This has the advantage that you do not have to edit the code. The disadvantage I see is that if the returned type is complex you cannot expand it and inspect its attributes like you can do if you assign the return value to an automatic variable. However for simple structs the return value is expanded to something like this: {var1=[val1], var2=[val2]...} where var1, var2 are the attributes of the struct.
As far as I know the Autos Window is there (and did the same thing) back in VS 6.0 so this applies to VS 2005 too I guess (someone asked about VS 2005 too).
The quickest way is just to enter myPart->bat_qty() in the Immediate window. This way you don't need to change the code.
Assign them to a temporary, like this :
const double bat_qty_val = myPart->bat_qty();
const double AUB_val = myPart->AUB();
then use those in the equation instead of calling functions.
Off the top of my head, and Im sure there would be a more elegant way, but you could assign the return values of bat_qty() and AUB() to a temporary variable and watch them in the debugger.
Visual Studio keeps trying to indent the code inside namespaces.
For example:
namespace Foo
{
void Bar();
void Bar()
{
}
}
Now, if I un-indent it manually then it stays that way. But unfortunately if I add something right before void Bar(); - such as a comment - VS will keep trying to indent it.
This is so annoying that basically because of this only reason I almost never use namespaces in C++. I can't understand why it tries to indent them (what's the point in indenting 1 or even 5 tabs the whole file?), or how to make it stop.
Is there a way to stop this behavior? A config option, an add-in, a registry setting, hell even a hack that modifies devenv.exe directly.
As KindDragon points out, Visual Studio 2013 Update 2 has an option to stop indenting.
You can uncheck TOOLS -> Options -> Text Editor -> C/C++ -> Formatting -> Indentation -> Indent namespace contents.
Just don't insert anything before the first line of code. You could try the following approach to insert a null line of code (it seems to work in VS2005):
namespace foo
{; // !<---
void Test();
}
This seems to suppress the indentation, but compilers may issue warnings and code reviewers/maintainers may be surprised! (And quite rightly, in the usual case!)
Probably not what you wanted to hear, but a lot of people work around this by using macros:
#define BEGIN_NAMESPACE(x) namespace x {
#define END_NAMESPACE }
Sounds dumb, but you'd be surprised how many system headers use this. (glibc's stl implentation, for instance, has _GLIBCXX_BEGIN_NAMESPACE() for this.)
I actually prefer this way, because I always tend to cringe when I see un-indented lines following a {. That's just me though.
Here is a macro that could help you. It will remove indentation if it detects that you are currently creating a namespace. It is not perfect but seems to work so far.
Public Sub aftekeypress(ByVal key As String, ByVal sel As TextSelection, ByVal completion As Boolean) _
Handles TextDocumentKeyPressEvents.AfterKeyPress
If (Not completion And key = vbCr) Then
'Only perform this if we are using smart indent
If DTE.Properties("TextEditor", "C/C++").Item("IndentStyle").Value = 2 Then
Dim textDocument As TextDocument = DTE.ActiveDocument.Object("TextDocument")
Dim startPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
Dim matchPoint As EditPoint = sel.ActivePoint.CreateEditPoint()
Dim findOptions As Integer = vsFindOptions.vsFindOptionsMatchCase + vsFindOptions.vsFindOptionsMatchWholeWord + vsFindOptions.vsFindOptionsBackwards
If startPoint.FindPattern("namespace", findOptions, matchPoint) Then
Dim lines = matchPoint.GetLines(matchPoint.Line, sel.ActivePoint.Line)
' Make sure we are still in the namespace {} but nothing has been typed
If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace[\s\w]+)?[\s\{]+$") Then
sel.Unindent()
End If
End If
End If
End If
End Sub
Since it is running all the time, you need to make sure you are installing the macro inside in your EnvironmentEvents project item inside MyMacros. You can only access this module in the Macro Explorer (Tools->Macros->Macro Explorer).
One note, it does not currently support "packed" namespaces such as
namespace A { namespace B {
...
}
}
EDIT
To support "packed" namespaces such as the example above and/or support comments after the namespace, such as namespace A { /* Example */, you can try to use the following line instead:
If System.Text.RegularExpressions.Regex.IsMatch(lines, "^[\s]*(namespace.+)?[\s\{]+$") Then
I haven't had the chance to test it a lot yet, but it seems to be working.
You could also forward declare your types (or whatever) inside the namespace then implement outside like this:
namespace test {
class MyClass;
}
class test::MyClass {
//...
};
Visual Studio 2017+
You can get to this "Indent namespace contents" setting under Tools->Options then Text Editor->C/C++->Formatting->Indention. It's deep in the menus but extremely helpful once found.
I understand the problem when there are nested namespaces. I used to pack all the namespaces in a single line to avoid the multiple indentation. It will leave one level, but that's not as bad as many levels. It's been so long since I have used VS that I hardly remember those days.
namespace outer { namespace middle { namespace inner {
void Test();
.....
}}}
I have created this datastructure:
class Event
{
public:
Event(EVENT_TYPE type, void* pSender = 0, int content1 = 0,
int content2 = 0, int content3 = 0, int content4 = 0);
~Event(void);
// ... some functions
protected:
EVENT_TYPE itsType;
void* itsPointerToSender;
int itsContent_1;
int itsContent_2;
int itsContent_3;
int itsContent_4;
int numStacked;
};
whose constructor is simply
Event::Event(EVENT_TYPE type, void* pSender, int content1, int content2, int content3, int content4)
: itsType(type),
itsPointerToSender(pSender),
itsContent_1(content1),
itsContent_2(content2),
itsContent_3(content3),
itsContent_4(content4),
numStacked(0)
{
}
For some strange reason I can't understand, the VS debugger cannot and will not show me whatever is contained in itsContent_4. If I put a watch on the variable, itsContent_4 gives me a symbol "itsContent_4" not found while doing the same thing with itsContent_3 works perfectly. I'm not sure the variable even exists as far as the compiler is concerned!
Am I missing something here?
Edit: Now it seems (even stranger) that changing the order of the variables in the declaration creates an even bigger mess! I tried placing itsContent_4 before itsContent_1 and now itsContent_1 is being initialized with the value intended for itsContent_4! What is going on here? I'm suspecting something to do with naming, so I'll try renaming them all and see what happens.
Edit 2: Yes, apparently changing the variable names to itsContent_a instead of itsContent_1 and so forth works perfectly. Is there some restriction as to using numbers in a variable name?
Sounds to me like the debugger is using the wrong .pdb file. Tools + Options, Debugging, General, ensure that "Require source files to exactly match the original version" is checked.
While debugging with a breakpoint active, use Debug + Windows + Modules and right-click your executable in the list. Click "Symbol Load Information" to find out where the debugger found the .pdb file.
Another possible mishap is that this class is defined in a separately compiled executable, like a DLL, which was compiled with incompatible settings. So that the layout of the object no longer matches. That's not that likely in this case.
Check that you're not trying to debug a release build. In a release build the optimiser can remove unused variabled and change the order in which statements are executed. This can be confusing when debugging.