This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]