gdb conditional break point,cannot find symbol for string global variable? - c++

I've got a short program:
#include<string>
using namespace std;
int i=0;
string s="a";
void f()
{
++i;//I wish to break here based on the value of "s"
}
int main()
{
f();
s+="b";
f();
s+="c";
f();
s+="d";
f();
return 0;
}
I compile and run, break at 'main', enter program, and try to set another point inside "f":
(gdb) b main
Breakpoint 1 at 0x4009c0: file 1.cpp, line 11.
(gdb) r
Starting program: /home/dev/a.out
Breakpoint 1, main () at 1.cpp:11
11 f();
(gdb) n
12 s+="b";
(gdb) b 6 if strcmp(s.c_str(),"abc")==0
No symbol "s" in current context.
If failed, but as "s" is a global variable, it should be seen by all kinds of context, right?
Why gdb say no symbol "s"?

Related

Can I execute commands silently in gdb?

Is there a way to execute a command silently so that it doesn't print feedback (such as Breakpoint 1 at 0x5c4 after setting a breakpoint)? Such a feature would be especially useful for me for a scripted debugging session.
#include <stdio.h>
int main() {
int i;
for(i=0;i<1000;i++) {
printf("%d\n", i);
}
return 0;
}
inside gdb
(gdb) break 6
(gdb) commands
(gdb) silent
(gdb) end
Alternatively, if you want to skip few initial breakpoints
ignore 1 999

Printing structure varibales at a particular point

Lets say we have a structure with some variables.
Is it possible to values of those variables at a particular point of execution..?
One way might be to print each of them individually.
But my point is, is there a way to check values of all the variables in that structure at a particular point of time, without having to use printf or cout to print each variable value..?
Just wondering if this is possible atleast in gdb..!!
it is possible in gdb, no problem:
For example:
x.C
#include <iostream>
struct A {
int x;
int y;
};
int main(int argc,char **argv) {
A a;
a.x=10;
a.y=11;
std::cout << "Hello world" << std::endl;
}
compiling:
g++ -g -o x x.C
running on gdb
gdb x
(gdb) break main
Breakpoint 1 at 0x40096c: file x.C, line 10.
(gdb) run
Starting program: /home/jsantand/x
Breakpoint 1, main (argc=1, argv=0x7fffffffde98) at x.C:10
10 a.x=10;
(gdb) next
11 a.y=11;
(gdb) next
12 std::cout << "Hello world" << std::endl;
(gdb) print a
$1 = {x = 10, y = 11}
(gdb) quit
Doing that on your code, traces, etc... it will be be more difficult as C++ lacks reflection.
You could do it by hand or if you're adventurous, create something to generate automatically operator<< for your classes an structs/classes so that they provide a string representation. You need some basic C++ parser at least.

C++ gdb print array gives No symbol "d" in context

I am trying to debug a C++ program but I face the below issue when trying to print the contents of the array.
I have declared a array of chars as below in the c++ program
using namespace std;
int main() {
string s;
cin >> s;
char d[s.size()];
int i=0;
int j=0;
while(j<s.size()) {
if(s[j] != '+') {
d[i++] = s[j];
}
j++;
}
}
I use the below commands to compile the above code and run gdb
g++ -g main.cpp -o main
gdb main
However when I debug and hit the below command in GDB I get the below error.
Command entered in GDB : p *d#10
No symbol "d" in current context.
Can you please let me know what I can do so that all the contents of the array is printed?
Until you run the program, there are no variables to print. For your program, you should set a breakpoint at the last line of main, and run the program. When the program stops at the breakpoint, you can then print d.
(gdb) list 15
10 while(j<s.size()) {
11 if(s[j] != '+') {
12 d[i++] = s[j];
13 }
14 j++;
15 }
16 }
(gdb) break 15
Breakpoint 1 at 0x80488b9: file x.cc, line 15.
(gdb) run
Starting program: /home/jxh/StackOverflow/gdb/a.out
1234567890
Breakpoint 1, main () at x.cc:15
15 }
(gdb) p *d#10
$2 = "1234567890"
(gdb)
Make sure to turn off compiler optimizations. This link gives a little more detail.

Why does gdb show two different returns?

Last week I was a debugging a code and a weird situation came up: gdb passes through two different return clauses. I made a simple example that illustrates the situation:
#include <iostream>
using namespace std;
int test() {
string a = "asd";
string b = "asd";
while (true) {
if (a == b) {
return 0;
}
}
return -1;
}
int main() {
int result = test();
cout << "result: " << result << endl;
}
When debugging the code I got:
(gdb) b main
Breakpoint 1 at 0x1d4c: file example.cpp, line 19.
(gdb) r
Starting program: /Users/yuppienet/temp/a.out
Reading symbols for shared libraries +++. done
Breakpoint 1, main () at example.cpp:19
19 int result = test();
(gdb) s
test () at example.cpp:7
7 string a = "asd";
(gdb) n
8 string b = "asd";
(gdb) n
11 if (a == b) {
(gdb) n
12 return 0;
(gdb) n
15 return -1;
(gdb) n
16 }
(gdb) n
main () at example.cpp:20
20 cout << "result: " << result << endl;
(gdb) n
result: 0
21 }
(gdb) n
0x00001ab2 in start ()
I noted that even if gdb shows line 15, the return value is 0 (the finish command confirms this as well).
So the question is: why does gdb show line 15: return -1, even if the function is not really returning this value?
Thanks!
Edit:
I forgot to mention that I compiled with the following line:
g++ -Wall -pedantic -g -pg example.cpp
I suspect you're seeing the function epilogue. Your two strings have destructors, which are being implicitly called on return. Check out what the disassembly says to be sure, but I suspect that both return statements are mapping to something along the lines of:
stash return_value;
goto epilogue;
and correspondingly:
epilogue:
destroy a; // on the stack, so destructor will be called
destroy b;
really_return(stashed value);
The epilogue appears to come from line 15 as a side-effect of how g++ does line numbering - a fairly simple format, really just a list of tags of the form "address X comes from line number Y" - and so it's reporting 15 as the closest match. Confusing in this case, but correct a lot of the time.
Probably because the program counter register passes through the instructions that best map to the final return, i.e. the function's exit sequence. The actual return value is probably kept in a register, so the first return just loads the proper value and jumps to the end of the function, and then that address is "back-mapped" to the source code line of the final return.
You don't say, but if you compiled with optimization that is exactly the kind of behavior you would see in gdb. You see the first line setting up the return value, and then it jumps to the real return instruction but in C++ you see the entire thing including the return value.

How can I step through nested function calls in GDB?

Sometimes I want to debug functions like this:
my_func1(my_func2(my_func3(val)));
Is there a way I can step through this nested call in GDB?
I want to step through my_func3, then my_func2, then my_func1, etc.
What command are you stepping with? next would go to next line when debugging my_func1(my_func2(my_func3(val)));, but step should enter my_func3.
Example:
int my_func1(int i)
{
return i;
}
int my_func2(int i)
{
return i;
}
int my_func3(int i)
{
return i;
}
int main(void)
{
return my_func1(my_func2(my_func3(1)));
}
Debugged:
(gdb) b main
Breakpoint 1 at 0x4004a4: file c.c, line 19.
(gdb) run
Starting program: test
Breakpoint 1, main () at c.c:19
19 return my_func1(my_func2(my_func3(1)));
(gdb) step
my_func3 (i=1) at c.c:14
14 return i;
(gdb) step
15 }
(gdb) step
my_func2 (i=1) at c.c:9
9 return i;
(gdb) step
10 }
(gdb) step
my_func1 (i=1) at c.c:4
4 return i;
(gdb) step
5 }
(gdb) step
main () at c.c:20
20 }
(gdb) cont
Continuing.
Program exited with code 01.
(gdb)
If you know the where the function definition is in the source code one solution will be to put break point inside that function.
Yes, although you may have get your hands dirty with the disassembly. First try the step command (abbreviation s). If that doesn't put you into my_func3(), try instead the stepi command (abbreviation si) to step one instruction at a time. This may take several invocations, since there can be a lot of instructions setting up the function call arguments and cleaning up afterwards.