http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53770
Bug #: 53770 Summary: Regression: incorrect line numbers in debug info since 4.5+ Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: debug AssignedTo: unassig...@gcc.gnu.org ReportedBy: pets...@gmail.com Created attachment 27703 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27703 the test case Single stepping the code from the debugger shows bad lines at places, the code is correct however. Command to produce the executable: g++-4.8.0 -o dbginfobug dbginfobug.cpp -save-temps -g -O0 -Wall -Wextra -v Using built-in specs. COLLECT_GCC=g++-4.8.0 COLLECT_LTO_WRAPPER=/home/usr-local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ./configure --enable-languages=c,c++ --program-suffix=-4.8.0 Thread model: posix gcc version 4.8.0 20120605 (experimental) (GCC) COLLECT_GCC_OPTIONS='-o' 'dbginfobug' '-save-temps' '-g' '-O0' '-Wall' '-Wextra' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /home/usr-local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/cc1plus -E -quiet -v -iprefix /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/ -D_GNU_SOURCE dbginfobug.cpp -mtune=generic -march=x86-64 -Wall -Wextra -g -fworking-directory -O0 -fpch-preprocess -o dbginfobug.ii ignoring nonexistent directory "/home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../x86_64-unknown-linux-gnu/include" ignoring duplicate directory "/home/usr-local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0" ignoring duplicate directory "/home/usr-local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/x86_64-unknown-linux-gnu" ignoring duplicate directory "/home/usr-local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/backward" ignoring duplicate directory "/home/usr-local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/include" ignoring duplicate directory "/home/usr-local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/include-fixed" ignoring nonexistent directory "/home/usr-local/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../x86_64-unknown-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0 /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/x86_64-unknown-linux-gnu /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/backward /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/include /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/include-fixed /usr/local/include /usr/include End of search list. COLLECT_GCC_OPTIONS='-o' 'dbginfobug' '-save-temps' '-g' '-O0' '-Wall' '-Wextra' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /home/usr-local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/cc1plus -fpreprocessed dbginfobug.ii -quiet -dumpbase dbginfobug.cpp -mtune=generic -march=x86-64 -auxbase dbginfobug -g -O0 -Wall -Wextra -version -o dbginfobug.s GNU C++ (GCC) version 4.8.0 20120605 (experimental) (x86_64-unknown-linux-gnu) compiled by GNU C version 4.8.0 20120605 (experimental), GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 GNU C++ (GCC) version 4.8.0 20120605 (experimental) (x86_64-unknown-linux-gnu) compiled by GNU C version 4.8.0 20120605 (experimental), GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: c6a0954413719d6fcdda7217d65221de COLLECT_GCC_OPTIONS='-o' 'dbginfobug' '-save-temps' '-g' '-O0' '-Wall' '-Wextra' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' as -v --64 -o dbginfobug.o dbginfobug.s GNU assembler version 2.22 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.22 COMPILER_PATH=/home/usr-local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/:/home/usr-local/bin/../libexec/gcc/ LIBRARY_PATH=/home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/:/home/usr-local/bin/../lib/gcc/:/home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64/:/lib/../lib64/:/usr/lib/x86_64-linux-gnu/:/home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-o' 'dbginfobug' '-save-temps' '-g' '-O0' '-Wall' '-Wextra' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /home/usr-local/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o dbginfobug /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/crtbegin.o -L/home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0 -L/home/usr-local/bin/../lib/gcc -L/home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../.. dbginfobug.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /home/usr-local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o gcc used above was built from git commit e7ae865c. The machine was a Debian Wheezy/AMD64 box. 4.8 produced the most weird behavior, although each minor version starting from 4.5 had problems. 4.4 was ok, clang was also ok. gdb version was 7.4.1. This was the trace when stepping through the template function do_print(), called from foo() with 'n' in gdb: 11 while (C c = *f++) { 12 if (c == '$') { 56 if (o < e) { 57 *o = c; 59 ++o; // the first anomaly: the line printed is AFTER the loop, while we're still in the loop // this happens only with 4.8, after each iteration 62 printf("RESULT (%zu chars): '%s'\n", o - buf, buf); 11 while (C c = *f++) { 12 if (c == '$') { 56 if (o < e) { 57 *o = c; 59 ++o; 62 printf("RESULT (%zu chars): '%s'\n", o - buf, buf); ... 62 printf("RESULT (%zu chars): '%s'\n", o - buf, buf); 11 while (C c = *f++) { 12 if (c == '$') { 13 C c2 = *f; 14 if (c2 == '$') { 18 unsigned ai = gai; 19 if (c2 == '{') { 20 ++f; 21 C c3 = *f; 22 if (c3 >= '0' && c3 <= '9') { 23 ai = 0; 24 while (C c4 = *f) { 25 if (c4 < '0' || c4 > '9') { 28 ai *= 10; 29 ai += c4 - '0'; 30 ++f; 24 while (C c4 = *f) { 25 if (c4 < '0' || c4 > '9') { // doesn't stop on the break with 4.8, stops with earlier versions // !!! we should be after the closing brace of the loop, yet we're still inside 30 ++f; (gdb) p c4 // this is quite a gotcha: c4 of type C is not in the scope anymore, but some constant // of type mynumber creeps in the scope from libm. // this wasn't too helpful understanding what's going on... $16 = {i = {1431655765, -1079683755}, x = -0.041666666666666664} (gdb) p f $17 = 0x400a18 "}\n" 36 C x = *f++; // f was not incremented (correctly), despite it stood on the line ++f (gdb) p f $18 = 0x400a18 "}\n" 37 if (x == '}') { // now it stops on this break. what's the difference compared to the above if() where it didn't stop? 38 break; 62 printf("RESULT (%zu chars): '%s'\n", o - buf, buf); 11 while (C c = *f++) { 12 if (c == '$') { I also did another function, do_print2(), which is the same as do_print(), but it's not a template, C is replaced with char. The interesting thing is, that the trace is not exactly the same: if the condition is true in line 25/85, the break is not stepped on. So far this is common. The templated version shows line 30 (++f) after that, which is definitely incorrect, while the non-template version shows line 91, which is the closing brace of the while loop, from which we're breaking out.