🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.sys.mac.programmer.codewarrior
9 messages
9 total messages Started by Jason Botwick Thu, 23 Jan 2003 05:13
Long long, optimization and weird debugger errors
#860
Author: Jason Botwick
Date: Thu, 23 Jan 2003 05:13
47 lines
3139 bytes
OK, so I have this code:

void TBlockStreamDocument::ReserveDiskSpace(long long &requestedSpace)
{
    HParamBlockRec pb;
    long long freeBytes;

    BlockZero_AC(pb);

    if (fDocStream->GetFile()->GetVolumeInfo(pb) == noErr)
    {
        // pb.*.* are both unsigned longs that return the amount
        // of free disk blocks and the size of these blocks, respectively.

        long long ioVFrBlk = pb.volumeParam.ioVFrBlk;
        long long ioVAlBlkSiz = pb.volumeParam.ioVAlBlkSiz;
        freeBytes = ioVFrBlk * ioVAlBlkSiz;
    }
    else
        freeBytes = 0;
    
    if (freeBytes < requestedSpace)
        requestedSpace = 0;
}

In my debug version of this app (optimization level 0), this works as
expected. In my release version (optimization level 4), this function sets
requestedSpace to 0 every time, because freeBytes always is set to 0. During
debugging, I can see that the "if" block is always executed in both the
release and debug versions. However, if I look at the variables window, in
the debug version, I can see where freeBytes is set to the appropriate value
in the debug version. But in the release version, the "value" of freeBytes
according to the debugger is  "*Buffer for SetVariable must be exact size of
variable*"

WTF?

No idea what that is supposed to mean. But coming out of the "if" block,
freeBytes is always 0 in the release version, but it's set to the correct
value in the debug version under identical circumstances.

If I change all of the long longs in this example to plain old longs, it
works. Which would be an OK solution, except that these days, a 32 bit int
isn't big enough to store the number of free bytes someone might have
available on their hard disk.

Is this an optimization bug, or am I missing something simple here?
Re: Long long, optimization and weird debugger errors
#861
Author: David Phillip Oster
Date: Thu, 23 Jan 2003 07:17
11 lines
2083 bytes
In article <BA54E438.7596%jbotwick@nc.rr.com>,
 Jason Botwick <jbotwick@nc.rr.com> wrote:

> in the debug version. But in the release version, the "value" of freeBytes
> according to the debugger is  "*Buffer for SetVariable must be exact size of
> variable*"
> 
> WTF?

You can't expect a debugger to track variables accurately in a highly 
optimized compile.
Re: Long long, optimization and weird debugger errors
#862
Author: Jason Botwick
Date: Thu, 23 Jan 2003 12:04
39 lines
2773 bytes
void TBlockStreamDocument::ReserveDiskSpace(long long &requestedSpace)
{
    HParamBlockRec pb;
    long long freeBytes;

    BlockZero_AC(pb);

    if (fDocStream->GetFile()->GetVolumeInfo(pb) == noErr)
    {
        // pb.*.* are both unsigned longs that return the amount
        // of free disk blocks and the size of these blocks, respectively.

        long long ioVFrBlk = pb.volumeParam.ioVFrBlk;
        long long ioVAlBlkSiz = pb.volumeParam.ioVAlBlkSiz;
        freeBytes = ioVFrBlk * ioVAlBlkSiz;
    }
    else
        freeBytes = 0;
    
    if (freeBytes < requestedSpace)
        requestedSpace = 0;
}

I forgot to mention that this code is running on x86.

And the problem isn't so much that the debugger isn't tracking the correct
values of the variables as it is that the value of freeBytes is coming out
to zero when I use optimization level 4.

If I reduce the optimization level to 1-3, the value of freeBytes is set to
the lo bytes. In the debugger, I can see where the freeBytes is split up
into lo and hi bytes, and the hi bytes are set to zero. In other words,
anytime freeBytes is greater than 0xFFFFFFFF, the high bytes are cut off.

Last night I tested this code on some different machines (different
processors), and found that even at optimization level 0, the hi bytes of
freeBytes is ignored.

Any ideas on why this would be?  
Re: Long long, optimization and weird debugger errors
#863
Author: MW Ron
Date: Thu, 23 Jan 2003 17:56
71 lines
3962 bytes
In article <BA54E438.7596%jbotwick@nc.rr.com>,
 Jason Botwick <jbotwick@nc.rr.com> wrote:

Hi,

In optimized code the actual code could be moved elsewehre or replaced 
so the value in the register does not reflect the variable when you 
think it should.

So I don't think this is a debugger bug.  However if you feel there is 
an optimization bug please submit this as a bug report to 
cw_bug@metrowerks.com  so we can look at it deeper.  Include a project 
that demonstrates the behavior.

Thanks, for the cooperation,

Ron
>
>void TBlockStreamDocument::ReserveDiskSpace(long long &requestedSpace)
>{
>    HParamBlockRec pb;
>    long long freeBytes;
>
>    BlockZero_AC(pb);
>
>    if (fDocStream->GetFile()->GetVolumeInfo(pb) == noErr)
>    {
>        // pb.*.* are both unsigned longs that return the amount
>        // of free disk blocks and the size of these blocks, respectively.
>
>        long long ioVFrBlk = pb.volumeParam.ioVFrBlk;
>        long long ioVAlBlkSiz = pb.volumeParam.ioVAlBlkSiz;
>        freeBytes = ioVFrBlk * ioVAlBlkSiz;
>    }
>    else
>        freeBytes = 0;
>    
>    if (freeBytes < requestedSpace)
>        requestedSpace = 0;
>}
>
>In my debug version of this app (optimization level 0), this works as
>expected. In my release version (optimization level 4), this function sets
>requestedSpace to 0 every time, because freeBytes always is set to 0. During
>debugging, I can see that the "if" block is always executed in both the
>release and debug versions. However, if I look at the variables window, in
>the debug version, I can see where freeBytes is set to the appropriate value
>in the debug version. But in the release version, the "value" of freeBytes
>according to the debugger is  "*Buffer for SetVariable must be exact size of
>variable*"
>
>WTF?
>
>No idea what that is supposed to mean. But coming out of the "if" block,
>freeBytes is always 0 in the release version, but it's set to the correct
>value in the debug version under identical circumstances.
>
>If I change all of the long longs in this example to plain old longs, it
>works. Which would be an OK solution, except that these days, a 32 bit int
>isn't big enough to store the number of free bytes someone might have
>available on their hard disk.
>
>Is this an optimization bug, or am I missing something simple here?
>

-- 
     Free Programming Courses at CodeWarrior U
          <http://www.codewarrioru.com>

 Metrowerks, maker of CodeWarrior  -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - http://www.metrowerks.com
Re: Long long, optimization and weird debugger errors
#864
Author: Raymond
Date: Thu, 23 Jan 2003 19:37
24 lines
2417 bytes
Jason

I had a similar problem and MW support tried to pacify me by saying I was
doing something wrong, and finally blew me off.
-- (MWRon, see: MW Tech support # 1-28735400)

But I am sure this is a MW compiler error... something about 64bit integers.
If the compiler puts the value (64bits) into the registers (using 2 32-bit
registers I guess), the compiler will reuse one of the registers, stomping
over your data.

MY solution was to force the long long to be on the stack. Always have a
variable in your routine(s) which received the address of freeBytes:

long long freeBytes;
long long* freeBytePtr;

freeBytePtr = &freeBytes;

POOF, my problem was solved.


I hope this helps.
ray
Re: Long long, optimization and weird debugger errors
#865
Author: MW Ron
Date: Thu, 23 Jan 2003 20:08
17 lines
1842 bytes
In article <iwXX9.1384$Xh6.582263850@newssvr13.news.prodigy.com>,
 "Raymond" <ray@n0.sp4m.powerproduction.n0.sp4m.com> wrote:

>I had a similar problem and MW support tried to pacify me by saying I was
>doing something wrong, and finally blew me off.
>-- (MWRon, see: MW Tech support # 1-28735400)

I'll look into it,  thanks for the bug number.

Ron

-- 
     Free Programming Courses at CodeWarrior U
          <http://www.codewarrioru.com>

 Metrowerks, maker of CodeWarrior  -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - http://www.metrowerks.com
Re: Long long, optimization and weird debugger errors
#855
Author: MW Ron
Date: Wed, 29 Jan 2003 20:56
107 lines
3901 bytes
In article <iwXX9.1384$Xh6.582263850@newssvr13.news.prodigy.com>,
 "Raymond" <ray@n0.sp4m.powerproduction.n0.sp4m.com> wrote:

>Jason
>
>I had a similar problem and MW support tried to pacify me by saying I was
>doing something wrong, and finally blew me off.
>-- (MWRon, see: MW Tech support # 1-28735400)

I looked into this and support thought that you had understood the 
question.  Here is a fuller description of why this is not an error and 
your code is non conformant.

Ron

   a left shift, can only operate in the context of the bits in the
   part being shifted. So shifting a 32-bit value by a value of 32
   or greater is undefined in the language standard.

   a constant like 5, is an int and will not get promoted to
   a "long long" or "unsigned long long" unless the code explicitly
   uses the long long (or unsigned long long) form of the constant:

   5LL or 5ULL

   or if there is an explicit type casting:

   (long long) 5 or (unsigned long long) 5

   When assigning a computation to a variable the implicit type convert
   happens after the expression is evaluated.

   so on PowerPC:

   (5 << 32) | (32777)

   produces either: 0x8009 or 0x800d

   In the first case the IR optimizer treated the undefined value
   as 0 (5 << 32) == 0. In the second case the code generator ANDed
   the shift amount with 31 such that (5 << 32) becomes (5 << 0) == 5.

   It will never produce 0x500008009, and even then the example
   is wrong as 0x500008009 & 0xFFFF000000000000 produces 0.

   Neither behavior will produce the results expected by the code 
example:

   void  main ( void )
   {
      UInt64 value;

      value =  ( ( 5 << 32 ) | ( 32777 ) );
      Routine_1( value );
   }

   void  Routine_1 ( UInt64 value )
   {
      Routine_2( value );
   }

   void  Routine_2 ( UInt64 value )
   {
      if( value & 0xFFFF000000000000 )
      {
         return; //no problems
      }
      else
      {
         complain(__LINE__);
      }
   }


therefore your code must be written like:

   void  main ( void )
   {
      UInt64 value;

      value =  ( ( ((UInt64)5) << 32 ) | ( 32777 ) );
      Routine_1( value );
   }

   void  Routine_1 ( UInt64 value )
   {
      Routine_2( value );
   }

   void  Routine_2 ( UInt64 value )
   {
      if( value & 0xFFFFFFFF00000000 )
      {
         return; //no problems
      }
      else
      {
         complain(__LINE__);
      }
   }

-- 
     Free Programming Courses at CodeWarrior U
          <http://www.codewarrioru.com>

 Metrowerks, maker of CodeWarrior  -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - http://www.metrowerks.com
Re: Long long, optimization and weird debugger errors
#858
Author: Raymond
Date: Wed, 05 Feb 2003 20:51
157 lines
6538 bytes
RE: 1-28735400
-----------------

Ron

Thank you very much for looking into this.
Unfortunately I made the mistake of simplifying my problem into Sample Code.

I do not believe the problem is with the flaws in this sample.

The problem is:
When I pass a 64bit value, the HIGH 32bits disappear. In the MW Debugger, I
can see the 64bit value is valid in the Caller, but the Callee does not
receive the full 64bits.
I have decided that this *is* a bug for the following reason:
-- If I create a variable (in the callee) which receives the Address of the
64bit value everything magically works
-- -- (See variable named "magically_makes_things_work" )

     void callee (unsigned long long important_value )
     {
     unsigned long long* magically_makes_things_work = (&important_value);

          //some code using important_value
     }

If the variable "magically_makes_things_work" is not present, then
"important_value" will not be accurate.
When the variable "magically_makes_things_work" is present, the value
of"important_value" is accurate.
-- I believe the variable "magically_makes_things_work" forces
"important_value" to be kept outside of the registers. Without the variable
"magically_makes_things_work," the MW Compiler tries to keep
"important_value" in the register and perhaps there is a bug in passing
64bits through the register.

So I hear you Ron (and your support agents) that creating a ULL the way I
demonstrated in the sample is nonstandard. I fully accept the responsibility
for creating a bogus sample. Sorry. But I was trying to demo the behavior I
was seeing in my more complicated program.
-- I feel my real issue was ignored because my demo program was flawed.

Can you see past my flawed sample and look at this issue again?
Thank you for your time
ray



"MW Ron" <mwron@metrowerks.com> wrote in message
news:mwron-AEB1B3.15564629012003@enews.newsguy.com...
> In article <iwXX9.1384$Xh6.582263850@newssvr13.news.prodigy.com>,
>  "Raymond" <ray@n0.sp4m.powerproduction.n0.sp4m.com> wrote:
>
> >Jason
> >
> >I had a similar problem and MW support tried to pacify me by saying I was
> >doing something wrong, and finally blew me off.
> >-- (MWRon, see: MW Tech support # 1-28735400)
>
> I looked into this and support thought that you had understood the
> question.  Here is a fuller description of why this is not an error and
> your code is non conformant.
>
> Ron
>
>    a left shift, can only operate in the context of the bits in the
>    part being shifted. So shifting a 32-bit value by a value of 32
>    or greater is undefined in the language standard.
>
>    a constant like 5, is an int and will not get promoted to
>    a "long long" or "unsigned long long" unless the code explicitly
>    uses the long long (or unsigned long long) form of the constant:
>
>    5LL or 5ULL
>
>    or if there is an explicit type casting:
>
>    (long long) 5 or (unsigned long long) 5
>
>    When assigning a computation to a variable the implicit type convert
>    happens after the expression is evaluated.
>
>    so on PowerPC:
>
>    (5 << 32) | (32777)
>
>    produces either: 0x8009 or 0x800d
>
>    In the first case the IR optimizer treated the undefined value
>    as 0 (5 << 32) == 0. In the second case the code generator ANDed
>    the shift amount with 31 such that (5 << 32) becomes (5 << 0) == 5.
>
>    It will never produce 0x500008009, and even then the example
>    is wrong as 0x500008009 & 0xFFFF000000000000 produces 0.
>
>    Neither behavior will produce the results expected by the code
> example:
>
>    void  main ( void )
>    {
>       UInt64 value;
>
>       value =  ( ( 5 << 32 ) | ( 32777 ) );
>       Routine_1( value );
>    }
>
>    void  Routine_1 ( UInt64 value )
>    {
>       Routine_2( value );
>    }
>
>    void  Routine_2 ( UInt64 value )
>    {
>       if( value & 0xFFFF000000000000 )
>       {
>          return; //no problems
>       }
>       else
>       {
>          complain(__LINE__);
>       }
>    }
>
>
> therefore your code must be written like:
>
>    void  main ( void )
>    {
>       UInt64 value;
>
>       value =  ( ( ((UInt64)5) << 32 ) | ( 32777 ) );
>       Routine_1( value );
>    }
>
>    void  Routine_1 ( UInt64 value )
>    {
>       Routine_2( value );
>    }
>
>    void  Routine_2 ( UInt64 value )
>    {
>       if( value & 0xFFFFFFFF00000000 )
>       {
>          return; //no problems
>       }
>       else
>       {
>          complain(__LINE__);
>       }
>    }
>
> --
>      Free Programming Courses at CodeWarrior U
>           <http://www.codewarrioru.com>
>
>  Metrowerks, maker of CodeWarrior  -  "Software Starts Here"
> Ron Liechty - MWRon@metrowerks.com - http://www.metrowerks.com
Re: Long long, optimization and weird debugger errors
#859
Author: MW Ron
Date: Wed, 05 Feb 2003 22:26
174 lines
6665 bytes
In article <sPe0a.827$AO5.797@newssvr16.news.prodigy.com>,
 "Raymond" <ray@powerproduction.com> wrote:


Yes  I'll ask that this be revisited.

Ron

>RE: 1-28735400
>-----------------
>
>Ron
>
>Thank you very much for looking into this.
>Unfortunately I made the mistake of simplifying my problem into Sample Code.
>
>I do not believe the problem is with the flaws in this sample.
>
>The problem is:
>When I pass a 64bit value, the HIGH 32bits disappear. In the MW Debugger, I
>can see the 64bit value is valid in the Caller, but the Callee does not
>receive the full 64bits.
>I have decided that this *is* a bug for the following reason:
>-- If I create a variable (in the callee) which receives the Address of the
>64bit value everything magically works
>-- -- (See variable named "magically_makes_things_work" )
>
>     void callee (unsigned long long important_value )
>     {
>     unsigned long long* magically_makes_things_work = (&important_value);
>
>          //some code using important_value
>     }
>
>If the variable "magically_makes_things_work" is not present, then
>"important_value" will not be accurate.
>When the variable "magically_makes_things_work" is present, the value
>of"important_value" is accurate.
>-- I believe the variable "magically_makes_things_work" forces
>"important_value" to be kept outside of the registers. Without the variable
>"magically_makes_things_work," the MW Compiler tries to keep
>"important_value" in the register and perhaps there is a bug in passing
>64bits through the register.
>
>So I hear you Ron (and your support agents) that creating a ULL the way I
>demonstrated in the sample is nonstandard. I fully accept the responsibility
>for creating a bogus sample. Sorry. But I was trying to demo the behavior I
>was seeing in my more complicated program.
>-- I feel my real issue was ignored because my demo program was flawed.
>
>Can you see past my flawed sample and look at this issue again?
>Thank you for your time
>ray
>
>
>
>"MW Ron" <mwron@metrowerks.com> wrote in message
>news:mwron-AEB1B3.15564629012003@enews.newsguy.com...
>> In article <iwXX9.1384$Xh6.582263850@newssvr13.news.prodigy.com>,
>>  "Raymond" <ray@n0.sp4m.powerproduction.n0.sp4m.com> wrote:
>>
>> >Jason
>> >
>> >I had a similar problem and MW support tried to pacify me by saying I was
>> >doing something wrong, and finally blew me off.
>> >-- (MWRon, see: MW Tech support # 1-28735400)
>>
>> I looked into this and support thought that you had understood the
>> question.  Here is a fuller description of why this is not an error and
>> your code is non conformant.
>>
>> Ron
>>
>>    a left shift, can only operate in the context of the bits in the
>>    part being shifted. So shifting a 32-bit value by a value of 32
>>    or greater is undefined in the language standard.
>>
>>    a constant like 5, is an int and will not get promoted to
>>    a "long long" or "unsigned long long" unless the code explicitly
>>    uses the long long (or unsigned long long) form of the constant:
>>
>>    5LL or 5ULL
>>
>>    or if there is an explicit type casting:
>>
>>    (long long) 5 or (unsigned long long) 5
>>
>>    When assigning a computation to a variable the implicit type convert
>>    happens after the expression is evaluated.
>>
>>    so on PowerPC:
>>
>>    (5 << 32) | (32777)
>>
>>    produces either: 0x8009 or 0x800d
>>
>>    In the first case the IR optimizer treated the undefined value
>>    as 0 (5 << 32) == 0. In the second case the code generator ANDed
>>    the shift amount with 31 such that (5 << 32) becomes (5 << 0) == 5.
>>
>>    It will never produce 0x500008009, and even then the example
>>    is wrong as 0x500008009 & 0xFFFF000000000000 produces 0.
>>
>>    Neither behavior will produce the results expected by the code
>> example:
>>
>>    void  main ( void )
>>    {
>>       UInt64 value;
>>
>>       value =  ( ( 5 << 32 ) | ( 32777 ) );
>>       Routine_1( value );
>>    }
>>
>>    void  Routine_1 ( UInt64 value )
>>    {
>>       Routine_2( value );
>>    }
>>
>>    void  Routine_2 ( UInt64 value )
>>    {
>>       if( value & 0xFFFF000000000000 )
>>       {
>>          return; //no problems
>>       }
>>       else
>>       {
>>          complain(__LINE__);
>>       }
>>    }
>>
>>
>> therefore your code must be written like:
>>
>>    void  main ( void )
>>    {
>>       UInt64 value;
>>
>>       value =  ( ( ((UInt64)5) << 32 ) | ( 32777 ) );
>>       Routine_1( value );
>>    }
>>
>>    void  Routine_1 ( UInt64 value )
>>    {
>>       Routine_2( value );
>>    }
>>
>>    void  Routine_2 ( UInt64 value )
>>    {
>>       if( value & 0xFFFFFFFF00000000 )
>>       {
>>          return; //no problems
>>       }
>>       else
>>       {
>>          complain(__LINE__);
>>       }
>>    }
>>
>> --
>>      Free Programming Courses at CodeWarrior U
>>           <http://www.codewarrioru.com>
>>
>>  Metrowerks, maker of CodeWarrior  -  "Software Starts Here"
>> Ron Liechty - MWRon@metrowerks.com - http://www.metrowerks.com
>
>

-- 
     Free Programming Courses at CodeWarrior U
          <http://www.codewarrioru.com>

 Metrowerks, maker of CodeWarrior  -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - http://www.metrowerks.com
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads