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

Page 1/4
| 2 | 3 | 4

By Bengalack

Master (220)

Bengalack's picture

30-08-2020, 20:14

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

You trust the compiler - in 99,99% of the time the problem is in your own code. And I'm no expert in C, but current behaviour is strange. It originates from my current project of about 8000 lines of code, and was really hard to find. I have isolated the problem, and it goes like this:

#include 

typedef struct {
	unsigned char uFileIndex[ 1 ];
} SpriteMap;

#define HOW_MANY 10

void pr( unsigned char x )
{
    printf( "Value: %d\r\n", x );
}

void doStuff( SpriteMap p[] )
{
    unsigned char n;

	/*
    unsigned char x = p[ 5 ].uFileIndex[ 0 ];
    for( n=0;n<4;n++ )
        pr( x );
	*/
	
    for( n=0;n<4;n++ )
        pr( p[ 5 ].uFileIndex[ 0 ] );
}

void main(void) 
{
	unsigned char n;

	SpriteMap p[ HOW_MANY ];
	
	for( n<0;n<HOW_MANY;n++ ) // just fill in some values
		p[ n ].uFileIndex[ 0 ] = n;

	doStuff( p );
}

So, I have 10 SpriteMap-objects. They each hold a value equal to their index. So, if I want to get the value from the fifth object, I expect to get 5. If I get that value multiple times, I expect to get 5 each time. In my sample, I try to get the value 4 times. I also print it. Here is the result:

Value: 5
Value: 0
Value: 0
Value: 224

If I uncomment the part where I put the value in a variable (x), I get this (correct) output:

Value: 5
Value: 5
Value: 5
Value: 5
Value: 5
Value: 5
Value: 5
Value: 5

I have converted the code to use pointers instead of arrays - same result. If I put the "SpriteMap" as global variable, and not pass as parameter, I get all 5's (correct). If I replace the function-call to "pr" with just printf, I get all 5's (correct).

This sounds crazy to me. I had to spend time in the openmsx debugger to find this (after hours of moving things around).

So either I'm doing something wrong, or SDCC is.

Login or register to post comments

By jltursan

Prophet (2333)

jltursan's picture

30-08-2020, 21:10

Can't see anything blatantly wrong...
Have you tried to declare the array without referencing the typedef?; so using a standard "unsigned char p[HOW_MANY][1]". Or another one, don't use "unsigned char uFileIndex[ 1 ];" but "unsigned char uFileIndex;" when declaring typedef.

By Thom

Hero (651)

Thom's picture

30-08-2020, 21:18

Have you tried this code in another C-compiler?

I have (https://www.onlinegdb.com/online_c_compiler), but get only zeros and an exit code 4.

By geijoenr

Master (180)

geijoenr's picture

30-08-2020, 21:46

@Bengalak SDCC has a few bugs indeed. I came across a few of them when dealing with static variables for instance. But normally you can write pretty complex code and it works just fine.

I am not sure what you intend to do, but the code you are showing looks really awkward for regular C standards. Feeding strange code the compiler makes it more likely that you hit bugs nobody noticed before.

You should be able to find the assembler output somewhere after compiling, if you post it here we can see what is happening in more detail.

By mcolom

Master (147)

mcolom's picture

30-08-2020, 22:51

I tried with gcc on Linux. It compiled without any warnings at it gave the expected results (it prints 5 with or without commenting those lines):

./a.out 
Value: 5
Value: 5
Value: 5
Value: 5

Edit: I corrected the bug mentioned below thinking that it was a bad copy-paste, I didn't notice it was wrong in the original code. These results are after fixing it.

By Sandy Brand

Master (197)

Sandy Brand's picture

30-08-2020, 22:44

You made a tiny typo in your for-loop in the main() function which makes the loop abort most likely on an undefined value for variable n.

Just replace n<0 with n=0

Smile

By Bengalack

Master (220)

Bengalack's picture

30-08-2020, 23:11

@jltursan - This example is a simplified version of my real problem. The array used to be greater than 1. I can change that to 5, in a new sample. Same error.
@Thom - I have not tried this in another compiler. I use SDCC with lots of assembly in-between the C. Not sure how to easily switch here.
@geijoenr - Yes, it might look a bit odd, when stripped down to something that shows the problem. And actually, I can make it smaller - one call smaller - I'll post it here in a bit.
Sandy Brand - Thanks, yes, typo, but does not change the problem.

I'm reporting this on the SDCC-forums now.

By Bengalack

Master (220)

Bengalack's picture

30-08-2020, 23:09

A bit smaller sample. Same problem. Will use this to report on the SDCC forums.

#include 

typedef struct {
	unsigned char uFileIndex[ 5 ];
} SpriteMap;

#define HOW_MANY 10

void pr( unsigned char x )
{
	// the value here, x, when passed in directly from
	// the "p[ 5 ].uFileIndex[ 0 ]" has the correct value
	// in the first call, but is wrong in all subsequent 
	// calls
    printf( "Value: %d\r\n", x );
}

void main(void) 
{
	unsigned char n;

	SpriteMap p[ HOW_MANY ];
	
	for( n=0;n<HOW_MANY;n++ )
		p[ n ].uFileIndex[ 0 ] = n;
	
	for( n=0;n<4;n++ )
        	pr( p[ 5 ].uFileIndex[ 0 ] ); // the culprit 
}

By Bengalack

Master (220)

Bengalack's picture

30-08-2020, 23:32

Thanks for the feedback everyone.

@geijoenr - as for assembly code, yes I have looked at the code, and I have found the error. It's a bit complicated, so I guess I'll leave it "unposted" for now Smile I have filed a bug report with SDCC-devs. Hope they pick it up soon.

The sample is now so simple, it's like, it must be me doing something wrong Smile I mean, this is SDCC version 4, and I'm sure there are thousands of executables being built with this. Such a bug should not have survived so long. Very strange.

By S0urceror

Master (138)

S0urceror's picture

31-08-2020, 07:35

Bengalack wrote:

I mean, this is SDCC version 4, and I'm sure there are thousands of executables being built with this. Such a bug should not have survived so long. Very strange.

Thousands of executables maybe yes. With the Z80 code generator maybe no.

Couple of months ago I had a similar problem and I debugged it down to the assembly to see wrong code was emitted. By turning off optimizations and moving the main to be the first function instead of the last it started generating right code.

So it’s not flawless in it’s code generation. That is at least my humble experience.

By Bengalack

Master (220)

Bengalack's picture

31-08-2020, 08:27

@mcolom - thanks for trying the code out and confirming.
@Thom - that tool is pretty cool. Now I have tested it, and makes me confident that this is not my fault:

@S0urceror - ok, maybe not thousands on z80 :) But yeah, I have found some other peculiarities, which I took some screenshots, but didn't care to report to the devs, as I couldn't make a repro-case that was small enough. We should probably have had a "beware"-thread, so that people can avoid getting into the same traps of the (known) bugs. Of course it would be best if they fixed it, but it seems like there is a year between each release :-O

Page 1/4
| 2 | 3 | 4