NO

Author Topic: Bug using an global array of structs, overwriting variables  (Read 5207 times)

neo313

  • Guest
When using a global array of structs i have  identified the following bug:

1. The struct has two members of any kind
2. when you assing a value to the first member the second member gets overwritten, in fact the next 4 bytes get overwritten
   so if you have 4 chars they all get overwritten
3.This only happens if you have a global array struct defined out of scope
4. If the array is of size 1 the bug does not appear, size must be 2 or more

My sscce:

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct test_s
{
float  val ;
int bol ;

} ;

#define LEN 5

struct test_s mystr[LEN] ;

int main( void )
{
for( int i = 0 ; i < LEN ; i += 1 )
{
mystr[i].val = 321.0f ;
mystr[i].bol = 1 ;
}

for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f   %d" , mystr[i].val , mystr[i].bol ) ;

for( int i = 0 ; i < LEN ; i += 1 )
mystr[i].val = 0.0f ; //set only val to 0

for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f   %d" , mystr[i].val , mystr[i].bol ) ; //both values get printed as 0, WRONG!

    return 0;
}



Output should be  http://ideone.com/qWpKPF

321.000000   1
 321.000000   1
 321.000000   1
 321.000000   1
 321.000000   1
 0.000000   1
 0.000000   1
 0.000000   1
 0.000000   1
 0.000000   1

but is

 321.000000   1
 321.000000   1
 321.000000   1
 321.000000   1
 321.000000   1
 0.000000   0
 0.000000   0
 0.000000   0
 0.000000   0
 0.000000   0

Can someone please verify this on their version of Pelles IDE.

MY system: Windows 7 32 bit Professional, Service Pack 1 ( Build 7601 ), Pelles Version 7.00.355

« Last Edit: June 22, 2013, 09:31:22 PM by neo313 »

JohnF

  • Guest
Re: Bug using an global array of structs, overwriting variables
« Reply #1 on: June 22, 2013, 09:36:57 PM »
The bug goes away with no optimizations.

John

neo313

  • Guest
Re: Bug using an global array of structs, overwriting variables
« Reply #2 on: June 22, 2013, 09:44:15 PM »
The bug goes away with no optimizations.

John

Indeed it does, so it is a pelles bug;
i forgot to check for optimizations

neo313

  • Guest
Re: Bug using an global array of structs, overwriting variables
« Reply #3 on: June 22, 2013, 10:29:00 PM »
Minor update:

If I switch the variable position in struct test_s this i get this output:   (with optimizations of course)

321.000000   1
321.000000   1
321.000000   1
321.000000   1
321.000000   1
0.000000   1
0.000000   0
0.000000   0
0.000000   0
0.000000   0
« Last Edit: June 22, 2013, 10:30:59 PM by neo313 »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2091
Re: Bug using an global array of structs, overwriting variables
« Reply #4 on: June 23, 2013, 08:22:25 AM »
Seems to zeroing whole struct:
Code: [Select]
for( int i = 0 ; i < LEN ; i += 1 )
mystr[i].val = 0.0f ; //set only val to 0
[0040104F] BFC4904000             mov               edi,mystr
[00401054] 31C0                   xor               eax,eax
[00401056] B928000000             mov               ecx,28
[0040105B] F3AA                   rep stosb         
[0040105D] 31DB                   xor               ebx,ebx
May the source be with you

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Bug using an global array of structs, overwriting variables
« Reply #5 on: June 23, 2013, 01:33:46 PM »
The bug comes from static values optimizations, infact if you move your code in a function and pass as parameters the initialization values the compiler doesn.t overwrite struct:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct test_s
{
float  val ;
int bol ;

} ;

#define LEN 5

struct test_s mystr[LEN] ;

void test(float a, float b)
{
for( int i = 0 ; i < LEN ; i += 1 )
{
//mystr[i].val = 321.0f ;
mystr[i].val = a ;
mystr[i].bol = 1 ;
}

for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f   %d" , mystr[i].val , mystr[i].bol ) ;

for( int i = 0 ; i < LEN ; i += 1 )
//mystr[i].val = 0.1f ; //set only val to 0
mystr[i].val = b ; //set only val to 0

for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f   %d" , mystr[i].val , mystr[i].bol ) ; //both values get printed as 0, WRONG!

}

int main( void )
{
test(321.0f, 0.0f);
    return 0;
}

Below I report a code piece from my FtypeLib where something similiar happens:
Code: [Select]
#pragma optimize(none)
/*+@@fnc@@----------------------------------------------------------------*//*!
 \brief DynStrFmtAppend
 \date Created  on Wed Apr 10 22:05:13 2013
 \date Modified on Wed Apr 10 22:05:13 2013
\*//*-@@fnc@@----------------------------------------------------------------*/
_FMT_2_3 LPDYNSTR __cdecl DynStrFmtAppend (LPDYNSTR *dynstr, DWORD *cChr, const WCHAR *Fmt, ...)
{
int cLen = 0;
    va_list ap;

    va_start(ap, Fmt);

cLen = vFmtStrTextLen(Fmt, ap) + 1;

if (cChr)
*cChr = cLen;

if (!dynstr)
return NULL;

_LPDYNSTR p = GETDYNSTRPTR(*dynstr);

if (!p)
return NULL;

p = ResizeDynStr(p, cLen);
if (!p)
{
*dynstr = NULL;
return NULL;
}

vswprintf((p->str)+wcslen(p->str), cLen, Fmt, ap);

    va_end(ap);

*dynstr = GETDYNSTRSTR(p);

/*
* COMPILER BUG REPORT.
* When optimizations are on the following line reports always the former string length!
* That's why the compiler makes 2 wrong assumptions:
* 1. That nobody modified the string from the previous 'wcslen' calculation.
* But 'vswprintf' does.
* 2. That the register 'edi', holding the former wcslen(p->str), has not been
* changed before reuse.
*/
p->len = wcslen(p->str) + 1;

return GETDYNSTRSTR(p);
}
#pragma optimize()

Yes advanced optimizations have some bugs  :'(
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

neo313

  • Guest
Re: Bug using an global array of structs, overwriting variables
« Reply #6 on: June 23, 2013, 08:28:08 PM »
Is there any chance that this bug will get fixed, or in other words is pelles still being supported by the author?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Bug using an global array of structs, overwriting variables
« Reply #7 on: June 24, 2013, 11:37:32 AM »
As far as we know he is still supporting even if we don't have any date for updates.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide