When you spend a full day tracking down a bug :-( Bug in SDCC 4.0?

صفحة 2/4
1 | | 3 | 4

بواسطة Giangiacomo Zaffini 2

Master (249)

صورة Giangiacomo Zaffini 2

31-08-2020, 08:36

@Bengalack : why don't You try later posted code back on SDCC?

بواسطة pgimeno

Champion (285)

صورة pgimeno

31-08-2020, 17:20

Edit: never mind, I saw your update later.

What happens if you change this line in main:

	for( n<0;n<HOW_MANY;n++ ) // just fill in some values

to this:

	for( n=0;n<HOW_MANY;n++ ) // just fill in some values

(note < vs =)

بواسطة pgimeno

Champion (285)

صورة pgimeno

31-08-2020, 17:54

This is the compiled fatal loop:

        ld      d,#0x00
00105$:
;blah.c:28: pr( p[ 5 ].uFileIndex[ 0 ] ); // the culprit
        ld      bc, #0x0019
        add     hl, bc
        ld      b,(hl)
        push    hl
        push    de
        push    bc
        inc     sp
        call    _pr
        inc     sp
        pop     de
        pop     hl
;blah.c:27: for( n=0;n<4;n++ )
        inc     d
        ld      a,d
        sub     a, #0x04
        jr      C,00105$

From that code, it is clear that hl is increasing in steps of 25 (19h) 4 times, and you don't have any data structure that long. From my understanding, hl should point to p at the beginning of the loop, and it adds 25 to it in order to access element [5], so I believe that the 'push hl' should actually be moved to the beginning of the loop, before adding bc, so that hl is preserved between iterations. Either that, or the addition of 25 should be moved out of the loop.

Clearly a compiler bug.

بواسطة pgimeno

Champion (285)

صورة pgimeno

31-08-2020, 18:50

Here's an even simpler test case; a function call and a struct are not necessary to trigger it.

void fill(char *q)
{
  unsigned char n;
  char p[6];

  // presence of this loop is important
  for(n = 0; n < 6; n++)
    p[n] = n + '0';

  for(n = 0; n < 5; n++)
    q[n] = p[1];  // p[1] is miscompiled here, incrementing p every iteration
}

#include <stdio.h>

int main()
{
  char q[6];
  fill(q);
  q[5] = 0;
  puts(q);
  return 0;
}

main() is not strictly necessary except to demonstrate that the output is wrong; compiling only the function using the -c flag and without main or the include still generates wrong code.

GCC correctly prints '11111'. I haven't tested, but I predict the output of sdcc to be '12345'.

بواسطة Bengalack

Champion (361)

صورة Bengalack

31-08-2020, 22:17

pgimeno wrote:

From my understanding, hl should point to p at the beginning of the loop, and it adds 25 to it in order to access element [5]

Yes, this was how I found the bug in the first place, stepping around in openmsx debugger. In the loop the code will find an address to look up a value, using an offset (25). After the first iteration, the offset was added to a value which was not stored (with its initial value) during the first iteration. The value in HL, as you point out. The aha-moment :-)

SDCC-devs commented on this being a serious issue, and one wanted it fixed in the next release 4.1 - but there is no guarantee for that.

At least I have a workaround for it (in the cases I'm aware of the trap)

بواسطة Bengalack

Champion (361)

صورة Bengalack

31-08-2020, 22:27

pgimeno wrote:

Here's an even simpler test case; a function call and a struct are not necessary to trigger it.

Nice! Simpler is better Big smile

Hope the devs fix it soon. To easy to step into accidentally.

بواسطة salutte

Master (132)

صورة salutte

01-09-2020, 06:44

As a heavy SDCC user, I thank you a lot for finding and filing this bug! It looks really dangerous!!

بواسطة Bengalack

Champion (361)

صورة Bengalack

01-09-2020, 21:11

pgimeno wrote:

GCC correctly prints '11111'. I haven't tested, but I predict the output of sdcc to be '12345'.

I have now tested it. It prints a square. A cursor. It's all broken.

I don't think I'm going to bother debugging it, sucks up the time. But! It might be related to another bug that is filed with SDCC and which is slated for the 4.1-release (suggested - there is no fix submitted yet). And it can be reproduced like this (the bug lies in the test-function which always returns c):

#include 

char test(char *p, int i, char c)
{
    p[0] = c;
    p[i] = 8;
    return p[0];
}

int main()
{
  char p[6];
  char n;

  for(n = 0; n < 6; n++)
	p[n] = 0;

  char result = test( p, 0, 5 );
  
  printf( "%d", result );
  
  return 0;
}

Output is 5. Expected is 8 of course.

Soooo. I have built a game engine using SDCC now, thousands of lines of code. Risky. Right now I have another strange behavior that suddenly popped up. Hmm. Likely my own bug... but - maybe not? :-)

بواسطة Grauw

Ascended (9750)

صورة Grauw

01-09-2020, 21:32

This is the worst kind of issue a compiler can have. Coders lose trust in the compiler, and it is extremely hard for the compiler to recover that trust.

The next time the coder encounters an issue, rather than looking for the logical explanation (an error in their code), they will always suspect the compiler, even if all those issues have been fixed and there is no problem with it. Distrust of the compiler causes inefficient debugging because it gives the coder the wrong mindset and will look for issues in the wrong places.

بواسطة ducasp

Champion (407)

صورة ducasp

02-09-2020, 00:08

Grauw wrote:

This is the worst kind of issue a compiler can have. Coders lose trust in the compiler, and it is extremely hard for the compiler to recover that trust.

The next time the coder encounters an issue, rather than looking for the logical explanation (an error in their code), they will always suspect the compiler, even if all those issues have been fixed and there is no problem with it. Distrust of the compiler causes inefficient debugging because it gives the coder the wrong mindset and will look for issues in the wrong places.

And, quite unfortunatelly, SDCC for z80 has quite a few of those... I have two or three scenarios where SDCC is creating bad code and I still need to find time to make a nice package of information to submit to them so they can investigated and fix it, for now, it was easier to work around doing things a little bit different to avoid the scenarios... It is an amazing tool, but at times, it can make you waste lots of time on bugs that are not on your code...

صفحة 2/4
1 | | 3 | 4