Wrong breakpoint being hit - c++

Sorry if this question was answered already, but I didn't found anything relevant. I'm experiencing a strange issue in Visual Studio 2013 C++ Win32 application when debugger incorrectly hits the breakpoint. Here is a sample code:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int a = 3;
int b = 1;
for (int i = 3; i >= 1; i--)
if (i % 2)
a = a*a;
b++;
return b;
}
I set breakpoint on b++ line. I'm familiar with debugging and breakpoints when debugging c# code (and very beginner in c++) and based on my experience, the breakpoint on b++ line should be hit only when for loop is ended. However it hits for each loop iteration, but the code (increment) doesn't execute.
Here is a screenshot of VS with relevant information

Actually this code is ok and should work as you expected.
VS allows you to place a breakpoint at the end of an execution block (the if statement inside the for loop in this case).
As you did not wrap the if statement with curly braces (as in the image above), VS assumes that the breakpoint you placed in the b++ statement refers to the end of the for execution block and therefore breaks, without executing the b++ statement.

Related

Does GDB in RISC-V support Program Context aware breakpoint?

I would like to learn if existing GDB for RISC-V supports Program Context aware breakpoints?
By program context aware breakpoints : I mean, when there is JAL or JALR instruction PC changes when there is a function call. in other cases in Function call ==> PC = PC + (Current Program Counter + 4)
in Function Return : PC = PC - (Return address (ra register value) ).
I have installed fedora(risc-V) on my ubuntu(virtual machine). Since it is virtual machine I can't print PC register value, that is why I couldn't check if it supports Program Context aware breakpoint or not?
My second question is : How can I print PC register value on my qemu risc-v virtual machine?
#include<stdio.h>
int check_prime(int a)
{
int c;
for (c=2;c<a;c++)
{
if (a%c == 0 ) return 0;
if (c == a-1 ) return 1;
}
}
void oddn(int a)
{
printf("oddn --> %d is an odd number \n",a);
if (check_prime(a)) printf("oddn --> %d is a prime number\n",a);
}
int main()
{
int a;
a=7;
if (check_prime(a)) printf("%d is a prime number \n",a);
if (a%2==1) oddn(a);
}
This is the program I am trying to breakpoint using GDB.
As you see on the picture it breaks twice(which should break once only).
It also gives error :
Error in testing breakpoint condition:
Invalid data type for function to be called
What you're looking for is documented here:
https://sourceware.org/gdb/current/onlinedocs/gdb/Convenience-Funs.html#index-_0024_005fstreq_002c-convenience-function
You should look at $_caller_is, $_caller_matches, $_any_caller_is, and $_any_caller_matches.
As an example, to check if the immediate caller is a particular function we could do this:
break functionD if ($_caller_is ("functionC"))
Then main -> functionD will not trigger the breakpoint, while main -> functionC -> functionD will trigger the breakpoint.
The convenience functions I listed all take a frame offset that can be used to specify which frame GDB will check (for $_caller_is and $_caller_matches) or to limit the range of frames checked (for $_any_caller_is and $_any_caller_matches).

Why there is a dead loop in the generated assembly for a Cortex-M interrupt handler?

I am learning the Cortex-M with the MDK uVision IDE. I wrote a simple SysTick_Handler() to replace the WEAK default SysTick_Handler() which is a simple dead loop.
My SysTick_Handler():
The disassembly:
I am confused by the the highlighted assembly line. It is simply a dead loop.
Why is it there? Why the toolchain still generated it despite that I already overwrite the WEAK default implementation with my own SysTick_Handler?
I can still place a breakpoint at that line and it can be hit. And in that case, my code will never be executed.
But strange thing is, if I removed the breakpoint at that line, my code can then be reached. How is that possible?
(Thanks to all the hints the community provided. I think I can explain it now.)
The dead loop is part of my main() function, which is like below. The main() function is just above my SysTick_Handler in the same C file.
int main (void)
{
LED_Initialize();
SysTick->VAL = 0x9000;
//Start value for the sys Tick counter
SysTick->LOAD = 0x9000;
//Reload value
SysTick->CTRL = SYSTICK_INTERRUPT_ENABLE|SYSTICK_COUNT_ENABLE; //Start and enable interrupt
while(1)
{
; // <========= This is the dead loop I saw!
}
}
To double confirm, I modified the while loop to below:
int main (void)
{
volatile int32_t jj = 0;
LED_Initialize();
SysTick->VAL = 0x9000; //Start value for the sys Tick counter
SysTick->LOAD = 0x9000; //Reload value
SysTick->CTRL = SYSTICK_INTERRUPT_ENABLE|SYSTICK_COUNT_ENABLE; //Start and enable interrupt
while(1)
{
;
jj+=0x12345; // <====== add some landmark value
}
}
The generated code is like this now:
Though it is still placed under the SysTick_Handler. I place a break point there to check what's really going on:
The R1 is the constant 0x12345. The R0 is the local variable jj. We can see the R1 does contain the landmark value 0x12345, which is added to R0 (jj). So it must be part of my while(1) loop in the main().
So, the disassembly is correct. Only that the debugger failed to provide a correct interleaving between the source and the disassembly.
And btw, remember to rebuild the target after modifying the code otherwise the uVision IDE debugger will not reflect the latest change....

Do while loops stop verifying after condition isn't met anymore?

I have recently started learning c++ and I have a question regarding the last section I reached, the while loop one.
In this code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int i = 0;
while (i <= 5) {
cout << "Hello" << endl;
i = i + 1;
}
return 0;
}
will the while command continue checking if i <=5 after the value goes over 5 or will it stop?
If I was making a program and changed the value of i down the line to one that meets the condition of the loop would it start again or would I have to rewrite the loop code again?
Thanks in advance for the answers!
edit: Thanks for your answers and comments. I tried putting into code what I was thinking and I noticed that changing the value of i after the loop didn't make it start again(meaning that it had already stopped checking after i surpassed 5).
I realize it was a stupid question that I could have simply solved by trying to put it into code, but I still asked for answers just to be sure. Thanks again!
If you changed i to 0 after the loop has ended like this:
int main()
{
int i = 0;
while (i <= 5) {
cout << "Hello" << endl;
i = i + 1;
}
i=0;
return 0;
}
The loop wouldn't start again because it would just set i to 0 and then go to return 0. Once the loop is executed it won't be run again.
Note that C++ executes the code sequentially, this means that its goes through every line, executes it, then goes to the next one. This is confusing for loops because you see previous code being executed again; therefore, to solve this dilemma, think of the loop segment as a block, once this block executes, the normal sequential execution continues.
For Future reference: C++ has a beautiful feature called Multi-threading, where you can allow several code to execute in a parallel fashion. You will meet this feature sometime in the future.

If statement not executed slows program

I have an if statement that is currently never executed, however if I print something to the screen it takes over ten times longer for the program to run than if a variable is declared. Doing a bit of research online this seems to be some kind of branch prediction issue. Is there anything I can do to improve the program speed?
Basically both myTest and myTest_new return the same thing except one is a macro and one is a function. I am just monitoring the time it takes for bitTest to execute. and it executes in 3 seconds with just declaration in if statement but takes over a minute when Serial.print is in if statement even though neither are executed.
void bitTest()
{
int count = 0;
Serial1.println("New Test");
int lastint = 0;
Serial1.println("int");
for (int index = -2147483647; index <= 2147483647; index+=1000) {
if (index <= 0 && lastint > 0) {
break;
}
lastint = index;
for (int num = 0; num <= 31; num++) {
++1000;
int vcr1 = myTest(index, num);
int vcr2 = myTest_new(index, num);
if (vcr1 != vcr2) {
Serial1.println("Test"); // leave this println() and it takes 300 seconds for the test to run
//int x = 0;
}
} // if (index)
} // for (index)
Serial1.print("count = ");
Serial1.println(count);
return;
}
It is much less likely to be caused by a branch prediction (that branch prediction shouldn't be influenced by what you do inside your code) but by the fact that
{
int x = 0;
}
simply does nothing, because the scope of x ends at }, so that the compiler simply ditches the whole if clause, including the check. Note that this is only possible because the expression that if checks has no side effects, and neither does the block that would get executed.
By the way, the code you showed would usually directly be "compiled away", because the compiler, at compile time, can determine whether the if clause could ever be executed, unless you explicitly tell the compiler to omit such safe optimizations. Hence, I kind of doubt your "10 times as slow" measurement. Either the code you're showing isn't the actual example on which you demonstrate this, or you should turn on compiler optimization prior to doing performance comparisons.
The reason why your program takes forever is that it's buggy:
for (int index = -2147483647; index <= 2147483647; index+=1000) {
simply: at a very large index close to the maximum integer value, a wrap-around will occur. There's no "correct" way for your program to terminate. Hence you invented your strange lastint > 0 checking.
Now, fix up the loop (I mean, you're really just using every 1000th element, so why not simply loop index from 0 to 2*2147483?)
++1000;
should be illegal in C, because you can't increase a constant numeral. This is very much WTF.
All in all, your program is a mess. Re-write it, and debug a clean, well-defined version of it.

Variable declaration in c++

when i run the following c++ code
#include<iostream>
int main()
{
for(int i=1;i<=10;i++)
{
cout<<i<<endl;
}
cout<<i;
getch();
return 0;
}
I get result from no. 1 to 11.
i don't understand why the value of i = 11 after the block of for loop is finished,Please give me the reason.I have declared i inside for loop and scope of i has been finished after loop so why i get the outpout i=11 after execute second cout statement .I have not declared i in the variable declaration inside main.My question is that is i is visible outside of for loop?
Thanks in advance.
For multiple reasons, this program does not compile. You are either using an extremely old compiler, an extremely permissive compiler, or not showing us the program you're actually having a problem with.
From your comments it seems that you actually can compile it. I can only guess that you are using a very old compiler. Perhaps an old MS-DOS compiler (Zortech C++? Turbo C++?) since the getch function is not generally a standard library function and doesn't do the right thing in the curses library anyway. It's probably an old BIOS-based function from the MS-DOS days.
The standard was changed awhile ago (over 10 years now) so that variable declarations in the parenthesized section of a for loop are local to that loop. It was once not actually the case that this was true.
I no longer have access to any compiler that's so old it doesn't handle things this way. I'm surprised anybody does. Your program will not compile on my compiler.
Here is a version of your program that does compile, even though it requires the -lcurses option to link:
#include <iostream>
#include <curses.h>
using ::std::cout;
using ::std::endl;
int main()
{
for(int i=1;i<=10;i++)
{
cout<<i<<endl;
}
getch();
return 0;
}
Notice how the offending cout << i; statement is gone? That because it will not compile on a modern compiler.
Now, lets edit your program some more so it will compile with the cout << i; statement you're vexed about:
#include <iostream>
#include <curses.h>
int main()
{
using ::std::cout;
int i;
for (i = 1; i <= 10; i++)
{
cout << i << '\n';
}
cout << "last: " << i << '\n';
getch();
return 0;
}
This, of course, does print out last: 11 at the very end. This happens for a very obvious reason. What value does i have to have in order for the i <= 10 test to fail? Why, any value greater than 10! And since i is having one added to it every loop iteration, the first value i has that has the property of being greater than 10 is 11.
The loop test happens at the top of the loop and is used to decide if the remainder of the loop should be executed or not. And the increment happens at the very bottom of the loop (despite appearing in the body of the for statement). So i will be 10, will be printed, and then 1 will be added to it. Then the loop test (i <= 10) will be done, it will be discovered that 11 <= 10 is false, and control will drop out of the loop down to the print statement after the loop, and last: 11 will be printed.
And yes, the exact same thing will happen in C.
Because the loop breaks when the condition i<=10 becomes untrue, and this can happen when i becomes 11. Simple!
I think you wanted to write i < 10 .
Also, as #Omnifarious noted in the comment, the code shouldn't even compile, as i doesn't exist outside the loop. Maybe, you've declared i outside the loop, in your original code?
Besides the fact that it shouldn't compile (because i doesn't exist outside the loop block).
The loop runs from 1 to 10, so it stops when i reaches 11 and the condition fails. So i is 11 in the end of the loop.
This is because you have an old compiler.
cout<<i<<endl; should not compile, as cout and endl need to be qualified by the std namespace.
Fixing that, std::cout<<i; shouldn't compile because your variable is loop-scoped, so shouldn't even be visible outside the loop.
Fixing that, here's your code:
#include<iostream>
#include<conio.h>
int main()
{
int i;
for(i = 1; i <= 10; i++)
{
std::cout << i << std::endl;
}
std::cout << i;
getch();
return 0;
}
It should become more obvious why 11 is printed now.
When i == 10, the loop executes, increments i, and checks its value. It is then equal to 11, so it exits the loop.
Then you have another print statement, that will print the post-loop value, which is 11.
Here's the output I get from that corrected program:
1
2
3
4
5
6
7
8
9
10
11
This is the same as you are getting.
If you only want to print 1-10, then why have the extra std::cout << i;?
Recommendation
Get an up to date C++ compiler that will give you syntax errors on things that are no longer valid in standard-compliant C++
Get rid of the extra std::cout << i;
Keep your i variable loop-scoped, as in your original code
The result from my recommendations will be that you only see 1 through 10 printed, and you will have slightly fewer unexpected surprises in the future (as some "bad" and surprising code won't even compile).