This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Regression: incorrect line numbers in debug info since 4.5+
- From: "Peter A. Felvegi" <petschy at praire-chicken dot com>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 25 Jun 2012 18:15:55 +0200
- Subject: Regression: incorrect line numbers in debug info since 4.5+
Hello,
I found out while single stepping a new template function in gdb that
gcc generates bad/inaccurate line numbers in the debug info.
Optimization was turned off, but the execution jumped strangely, see
below. gcc-4.4 and the current clang produced the expected results, gcc
4.5, 4.6, 4.7, 4.8 all had problems. The code was factored out from a
proof-of-concept hack.
Here is the trace that was produced in gdb by single stepping the
program with 'n'. The program was compiled w/ gcc 4.8.0 git commit e7ae865c:
COLLECT_GCC=gcc-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)
g++-4.8.0 -g -O0 -Wall -Wextra -o dbginfobug.o -c dbginfobug.cpp
g++-4.8.0 -g -o dbginfobug dbginfobug.o
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 attached the cpp source, and also the preprocessed version, if it
makes any difference.
I couldn't find anything similar in bz, please let me know whether this
is a new issue and I will file a bugreport.
Regards, Peter
#include <stddef.h>
#include <stdio.h>
template<typename C>
void do_print(C* buf, size_t siz, const C* fmt)
{
const C* f = fmt;
C* o = buf;
C* e = buf + siz;
unsigned gai = 0;
while (C c = *f++) {
if (c == '$') {
C c2 = *f;
if (c2 == '$') {
++f;
goto lit;
}
unsigned ai = gai;
if (c2 == '{') {
++f;
C c3 = *f;
if (c3 >= '0' && c3 <= '9') {
ai = 0;
while (C c4 = *f) {
if (c4 < '0' || c4 > '9') {
break;
}
ai *= 10;
ai += c4 - '0';
++f;
}
} else {
++gai;
}
do {
C x = *f++;
if (x == '}') {
break;
}
if (x == 0) {
fprintf(stderr, "ERROR: no closing brace\n");
return;
}
if (x == 'f') {
break;
} else {
fprintf(stderr, "ERROR: invalid format specifier char '%c'\n", x);
return;
}
} while (1);
} else {
++gai;
}
} else {
lit:
if (o < e) {
*o = c;
}
++o;
}
}
printf("RESULT (%zu chars): '%s'\n", o - buf, buf);
}
void foo()
{
char buf[256];
do_print(buf, sizeof(buf), "T $$ ${1}\n");
}
int main()
{
foo();
}
Attachment:
dbginfobug.E.gz
Description: GNU Zip compressed data