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

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.

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

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

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"?

sizeof reference to array in gdb

int main()
{
typedef unsigned char a4[4];
a4 p1;
a4& p2 = p1;
p2[1]=1;
cout<<sizeof(p2);
return p2[1];
}
Compile, start gdb and put breakpoint on return. If you type p sizeof(p2), gdb will print 8 instead of 4 which will be printed if you start the program. If you write in gdb p sizeof(*p2), the output is 4 (the size of array). I think this is because gdb treats p2 as pointer(reference is implemented behind the scene as pointer).
Tested with compilers GCC 4.8.2 and Clang 4.3 on GDB 7.7 linux arch., ubuntu 13.10,
Is this correct or a bug in gdb?
Here's a modified version of your program. I've changed the array size from 4 to 17 to ensure that its size is distinguishable from anything else. I've also changed the type and variable names to make the code easier to follow, and added #include <iostream> so it actually compiles. I've also removed some unnecessary stuff.
#include <iostream>
int main()
{
typedef unsigned char char17[17];
char17 arr17;
char17& arr17_ref = arr17;
std::cout << "sizeof(arr17) = "
<< sizeof arr17
<< ", sizeof(arr17_ref) = "
<< sizeof(arr17_ref)
<< "\n";
return 0;
}
When I compile and run it on my system, the output is 17.
When I run it under gdb, I get 8 (the size of a pointer on my system):
$ gdb ./c
GNU gdb (GDB) 7.5-ubuntu
[snip]
Reading symbols from /home/kst/c...done.
(gdb) b 12
Breakpoint 1 at 0x40097e: file c.cpp, line 12.
(gdb) r
Starting program: /home/kst/c
sizeof(arr17) = 17, sizeof(arr17_ref) = 17
Breakpoint 1, main () at c.cpp:12
12 return 0;
(gdb) p sizeof(arr17)
$1 = 17
(gdb) p sizeof(arr17_ref)
$2 = 8
(gdb) c
Continuing.
[Inferior 1 (process 23420) exited normally]
(gdb) q
$
Yes, this is a bug in gdb. gdb is supposed to evaluate expressions as they'd be evaluated in a running program; in this case, it fails to do so.
(I'm using gcc 4.7.2 and gdb 7.5 on Linux Mint 14.)
UPDATE :
The OP submitted a bug report: https://sourceware.org/bugzilla/show_bug.cgi?id=16675
and it's been fixed. The patch was approved and committed 2014-04-14. I still see the bug in gdb 7.7.1, but it's fixed in 7.11.1.

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.