Reputation: 638
When I step through the following code with GDB, the execution flow progresses in an unintuitive way. Specifically, when it steps into f
, the first line it goes to is the return statement.
#include <iostream>
int f(int m) {
int arr[m];
std::cout << "hello" << std::endl;
return 0;
}
int main() {
f(2);
}
GDB output:
(gdb) break main
Breakpoint 1 at 0x12fd: file main.cpp, line 11.
(gdb) r
Starting program: /home/eric/Documents/confusing_gdb/a.out
Breakpoint 1, main () at main.cpp:11
11 int main() {
(gdb) n
12 f(2);
(gdb) s
f (m=21845) at main.cpp:3
3 int f(int m) {
(gdb) n
8 return 0;
(gdb) n
4 int arr[m];
(gdb) n
6 std::cout << "hello" << std::endl;
(gdb) n
hello
8 return 0;
(gdb) n
9 }
(gdb) n
main () at main.cpp:13
13 }
The command I used to compile it and run GDB is
g++ -g3 main.cpp && gdb a.out
Here are some variations I've tried which also give this behavior:
arr
in a for
loopint arr[m];
line with int arr[m] = {1,2};
Here are some variations I've tried which DO NOT give this behavior:
int arr[m];
int arr[m]
to int arr[5]
This behavior is particularly annoying with breakpoints because if you break at the return statement, the function hasn't run yet and you can't print out any variables. And also if you continue from this point, it will run and exit the function, not breaking when it seems like it should. Here is an example to show what I mean:
(gdb) break 9
Breakpoint 1 at 0x11e8: file main.cpp, line 9.
(gdb) r
Starting program: /home/eric/Documents/confusing_gdb/a.out
Breakpoint 1, f (m=2) at main.cpp:9
9 return 0;
(gdb) p arr
value requires 1431654200 bytes, which is more than max-value-size
(gdb) c
Continuing.
hello
[Inferior 1 (process 25477) exited normally]
What could explain this behavior, and what could possible fixes be?
Upvotes: 1
Views: 625
Reputation: 17073
What could explain this behavior,
Your tests explain it fairly well, no? It is caused by having a variable length array. If you want a deeper explanation, the executable is probably allocating space for the array on the stack. This confuses the debugger for a bit because memory locations have changed from what was determined at compile time. Once the allocation is complete, the debugger re-orients itself and finds the current line for debugging.
Or maybe the debugger is not "confused" so much as "unsure what feedback would be least confusing to the programmer". In any case, your code wanders into a non-standard language extension and GDB is doing what it can to keep up.
and what could possible fixes be?
Well, the fixes you listed are to make the array fixed-length or to remove the array completely. Either would work for this code sample, but I suspect your real code would actually use the array (if so, thanks for trimming out the noise).
The standard way to get a variable length array is std::vector
.
std::vector<int> arr{m};
Upvotes: 2