-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Closed
Labels
Description
Originally from https://sourceware.org/bugzilla/show_bug.cgi?id=31896.
Sometimes if conditions don't get is_stmt flag and gdb skips them during stepping.
To reproduce, compile test.cpp:
1 #include <iostream>
2
3 bool predicate(int v) {
4 return v == 7;
5 }
6
7 void f(int v) {
8 if (v) { // break here
9 std::cout << "branch1\n";
10 }
11 else if(predicate(v)) {
12 std::cout << "branch2\n";
13 } else if(predicate(v+1)) {
14 std::cout << "branch3\n";
15 }
16 }
17
18 int main() {
19 f(0);
20 return 0;
21 }
> clang++-18 -g -O0 test.cpp
Try stepping in gdb:
> gdb a.out
(gdb) b test.cpp:8
Breakpoint 1 at 0x116b: file test.cpp, line 8.
(gdb) run
Breakpoint 1, f (v=0) at test.cpp:8
8 if (v) { // break here
(gdb) next
11 else if(predicate(v)) {
(gdb) next
16 }
(gdb)
Notice that gdb didn't stop at the last branch condition on line 13.
> llvm-dwarfdump-18 --debug-line a.out
...
Address Line Column File ISA Discriminator OpIndex Flags
------------------ ------ ------ ------ --- ------------- ------- -------------
0x0000000000001140 3 0 0 0 0 0 is_stmt
0x0000000000001147 4 14 0 0 0 0 is_stmt prologue_end
0x000000000000114e 4 5 0 0 0 0
0x0000000000001153 4 5 0 0 0 0 epilogue_begin
0x0000000000001160 7 0 0 0 0 0 is_stmt
0x000000000000116b 8 9 0 0 0 0 is_stmt prologue_end
0x000000000000116f 8 9 0 0 0 0
0x0000000000001175 9 19 0 0 0 0 is_stmt
0x0000000000001188 10 5 0 0 0 0 is_stmt
0x000000000000118d 11 23 0 0 0 0 is_stmt
0x0000000000001190 11 13 0 0 0 0
0x0000000000001195 11 13 0 0 0 0
0x00000000000011a2 12 19 0 0 0 0 is_stmt
0x00000000000011b5 13 5 0 0 0 0 is_stmt
0x00000000000011ba 13 25 0 0 0 0
0x00000000000011bd 13 26 0 0 0 0
0x00000000000011c0 13 15 0 0 0 0
0x00000000000011c5 13 15 0 0 0 0
0x00000000000011d2 14 19 0 0 0 0 is_stmt
0x00000000000011e5 0 19 0 0 0 0
0x00000000000011ef 16 1 0 0 0 0 is_stmt epilogue_begin
0x0000000000001200 18 0 0 0 0 0 is_stmt
0x000000000000120f 19 5 0 0 0 0 is_stmt prologue_end
0x0000000000001216 20 5 0 0 0 0 is_stmt
0x0000000000001218 20 5 0 0 0 0 epilogue_begin
0x000000000000121e 20 5 0 0 0 0 end_sequence
For the branch on the line 11 both closing } of the previous block on line 10 and the else if get is_stmt flag.
The branch on the line 13 has only one instruction marked with the is_stmt flag. Gdb treats it as the last instruction of the previous block and doesn't stop there.