Conditional breakpoint modifier to see if array has changed - c++

I was playing with the variable changes breakpoint modifier in Visual Studio 2012. From my understanding, the variable change modifier causes the debugger to break if the specified variable value changes from a previous location execution. I think that this would be useful in narrowing down memory overwrites. My very simple C++ code is this:
int main ()
{
printf("This program converts upper case chars to lower and vice versa\n");
char str[20]="lowercase";;
int i;
for (i=0; i < strlen(str); i++)
{
if (str[i]>=97 && str[i]<=122)
{
str[i]-=32;
}
else
{
str[i]+=32;
}
}
str[1] = 'o';
printf("%s\n",str);
system("PAUSE");
}
Now I set conditional breakpoint on two lines
str[i]=str[i]-32
printf("%s\n", str)
to hit when array str changes. To do this I set a location breakpoint, then select "condition" on right clicking and in the condition textbox I put str,20. Finally I select the "has changed" radio button.
Now what I'm seeing is this:
The breakpoint is hit everytime on the line str[i]-=32, but never on the line printf("%s\n", str) and I'm curious as to why. Obviously the array has changed because of the line preceding the printf statement, so why isn't the breakpoint hit?
What am I missing here?

You are only breaking when that memory is written, not read. The function printf only reads that memory.

Related

How to modify value of variable automatically at runtime when hitting a breakpoint and continuing execution in VS?

We can change value manually by changing in variable tooltip or local/auto/watch window.
But I want to change value of variable automatically to some specific hardcoded value or based on a code snippet.
For eg.-
int main()
{
int a=0,b=1,c=2;
//bla bla
for(int i=0; i<100; ++i)
{
executeMe();
}
//bla bla
}
I want to put a breakpoint on line "executeMe()" and change value of 'b' to hardcoded value 3 or based on variable value 'c', so executing instruction 'b=c'. And continues execution without stopping everytime on breakpoint.
How to do this in VS?
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.
Thanks to Tom McKeown for this solution on stackoverflow.com/a/15415763/2328412
You could use #if preprocessor directives, which is similar with below code.
int a = 0, b = 1, c = 2;
for (int i = 0; i < 100; ++i)
{
#if DEBUG
b=3;
#endif
executeMe();
}

During debugging my program jumps to nearest while statement without break or continue [C++]

When running my C++/Qt5 program under gdb I experienced what seems like an impossibility:
while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){
if(nullptr!=c){
// POINT-A
qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
const int left=bytesAvailable-bytesSpent;
totalAvailable-=bytesSpent;
if(left>=0){
if(left>0){
ds->skipRawData(left);
totalAvailable-=left;
}
else{
// POINT-B
qDebug()<<rct<<"LOLBOB";
}
}
else{
qWarning()<<"BAR";
return;
}
}
else{
qWarning()<<"FOO";
return;
}
}
In short, when I step from //POINT-A to //POINT-B everything is as expected, but as soon as I step past //POINT-B debugger jumps up to the first line of the program (while statement). But there are no break or continue or other flow-altering statements in the code. How is this possible?
I have tried rebuilding my code from scratch to eliminate a bogus linkage or similar problems, but the bug is reproducible still.
Any input is welcomed.
At POINT-B, you are inside an else, which is inside an if, which is inside an if. Once this else is done, there is nothing more to do in the whole tree.
Where would you expect the pointer to jump to??
Technically, it would go to the closing bracket two lines behind POINT-B, then to the closing bracket three lines behind POINT-B, and then to closing bracket eight lines behind POINT-B, and then to the closing bracket at the very end. All those do nothing, so they are skipped.
Take a paper and pencil, and diagram the logical flow of this chunk of code.
You will make a surprising discovery that the only statement that could possibly execute, after the statement you marked "POINT B", is the condition at the beginning of the while loop. After executing the "POINT B" statement, there are no more statements to execute in the body of the loop, so execution winds back to the while condition, for the next iteration.
Basically the loop just re-iterates. I believe it is functioning as it is supposed to. From Point-A the control goes like such:
If no.1 (Point-A) -> If no.2 -> Else corresponding to If no.3 -> back to end of If no.2 -> back to end of If no.1 -> back to end of while loop.
As the loop is over, the execution checks the loop's condition, (if it is satisfied) re-iterates, and eventually you reach Point-A again.
while()
{
if() // If no.1
{
// Point-A *****************************
if() // If no.2
{
if() // If no.3
{
}
else()
{
// Point-B *****************
}
}
else
{
}
}
else
{
}
}
To improve debugging and readability, do not keep nesting if blocks or loops - It is very hard to trace the execution.
Look if you write it this equivalent way:
while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){
if(nullptr==c){
qWarning()<<"FOO";
return;
}
// POINT-A
qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
const int left=bytesAvailable-bytesSpent;
totalAvailable-=bytesSpent;
if(left<0){
qWarning()<<"BAR";
return;
}
if(left>0){
ds->skipRawData(left);
totalAvailable-=left;
}
else{
// POINT-B
qDebug()<<rct<<"LOLBOB";
}
}

C++ character variable value of '\x1'

I'm failing to understand why would the loop exit at the value of character variable i = '\x1'
#include <iostream>
using namespace std;
int main()
{
char i;
for (i = 1; i < 10, i++;)
{
cout << i << endl;
}
return 0;
}
Can somebody please explain this behavior ?
This is wrong
for (i = 1; i < 10, i++;)
/* ^ should be ; */
You only declared 3 regions for the loop, but put your increment statement in the middle area, and left your increment area empty. I have no idea which statement in the middle area your compiler will choose to execute. Best not to try to be cute and deceive your compiler. Let alone some colleague who will read your code years from now and go WTF???
A for loop has 3 distinct areas delimited by semi-colons:
The initialization area. You can declare as many variables in here as you want. These can be delimited by commas.
The test area. This is where an expression goes to test if the loop should continue.
The post loop area. This region of code gets executed after every loop.
Try to keep it simple. If it is going to be more complicated then use a while loop.
The reason that i ends up being 1 is that when i++ is zero, which terminates the loop, then i will become 1 (That is what the form of the ++ operator you used does). As the other answered have pointed out, once you fix your code by moving i++ out of the condition by replacing the comma with a semicolon, then i will make it all the way to 10 as desired.
for (i = 1; i < 10; i++)
You wrote for statement wrong.

CodeBlocks Breakpoints Ignoring Scope

I set a breakpoint inside a conditional statement that checks for a certain value of a custom datatype. The game will break, but the line it breaks on is completely outside of my breakpoint's scope. Watch variables reveal that it just breaks the first time that loop is iterated through, rendering my debugging conditional statement absolutely useless.
In Visual Studio, the debugger would respect scope, and placing a breakpoint inside a conditional statement would only stop the game if that conditional evaluated to true. Why is this not the case with the GDB debugger in CodeBlocks? Is it because I'm using GDB in Windows? Here's the code:
for(int j = 0 ; j < r->components[i].size() ; j++)
{
itype_id type = r->components[i][j].type;
int req = r->components[i][j].count;
//DEBUGGING ONLY!!!!!!!!!
if(type == itm_coffee_raw)
{
int pleaseStop = 0;
if(pleaseStop == 0) //BREAKPOINT IS ON THIS LINE
bool dontstoptillyougetenough = true;
}
if (itypes[type]->count_by_charges() && req > 0) //GAME BREAKS HERE
{
if (crafting_inv.has_charges(type, req))
{
has_comp = true;
break;
}
}
else if (crafting_inv.has_amount(type, abs(req)))
{
has_comp = true;
break;
}
}
The code inside the if body doesn't really do anything, so the compiler could see it as "dead code" and remove it from the executable in an optimization pass. This means that the code in question doesn't actually exist in the final executable, and so you can't put a breakpoint there.
Turn off optimizations (always good when debugging in general) and it should work.

How to make a break point just after loop?

#include <iostream>
#include <vector>
using namespace std;
int in;
bool isPrime(int n) {
for (int i = 3; i <= n; i ++) {
if (n%i != 0) {
return false;
}
}
return true;
}
vector<int>* generateVector(int n) {
vector<int> v;
for (int i = 2; i < 20; i ++) {
if (i == n) {
continue;
}
if (isPrime(i+n)) {
v.push_back(i);
}
}
}
int main()
{
while(1) {
cin >> in;
vector<int>* nVectors[21];
for (int i = 1; i <= 20; i ++) {
nVectors[i] = generateVector(i);
} <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}
This some c++ code. And i would like to make a break point just after the for loop(the arrow show the position).
I have found one way to solve it through adding a statement after it then make break point in this statement. But adding a statement without a meaning make not feeling good. So is there a better solution?
I am using GDB for debugging.
PS: I have already known how to set breakpoint in gdb. My intent is to break after the for loop ends, and display what in nVectors. Thanks.
Sorry for all. It's not the issue about the gdb or debugging skill, but there is a bug in my code. So when i print nVectors, nothing was printed. After fixing it, every method you provides works fine. Thanks.
You can use a assembly break point, just need to understand the assembly code of for loop.
gdb <your_bin>
layout split
break *0x80488ad #assmebly code will look like
#0x80488ad jmp 0x8048874 <main+18>
gdb has a command to add break points
there are a couple of ways, but I think the one that might help you is :
(gdb) break filename:linenumber
so for example I want to break at line 10 in main.c
break main.c:10
you might want try a tutorial http://www.yolinux.com/TUTORIALS/GDB-Commands.html
Nope there has to be some statement for the debugger to be able to set breakpoint.
I don't think there is a way to directly do what you want but you can still do it. Set a breakpoint on the last statement of the loop. When the debugger breaks switch the disassembly view and scroll down until you find where you want to place the real breakpoint. This will effective set a breakpoint at a specific address rather than on a line number in a source file.
You can specify the source file and line of the end of the loop, like so, on the gdb command line:
b file.c:123
If you want to go right after the for loop, you'll want to actually set the break for the line of the closing bracket of the while() loop, I believe. But you can try both and see what gives the desired result.
Try to use until command. It is useful to avoid single stepping through a loop. Also from gdb manual:
until always stops your program if it attempts to exit the current
stack frame.
If it was me, I'd set an assembly breakpoint, like the others said. But if you don't want to get into that, there's a simpler way: Since you know the loop count (20), and it is not very big, you can set a breakpoint on the last statement inside the loop (in your case, the only statement inside the loop), with the condition
if (i == 19)
Alternatively, you can set an ignore count:
ignore bnum 19
where bnum is the breakpoint number. This is probably faster, but in your case the difference will be negligible.
See Breakpoints, watchpoints, and catchpoints in the gdb documentation for more information.