For Programmers: Free Programming Magazines  


Home > Archive > Visual Studio > March 2004 > I just found a HUGE bug in visual C++ 6.0 code generation...









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author I just found a HUGE bug in visual C++ 6.0 code generation...
fungus

2004-03-28, 10:32 pm

Create a new "Hello, world!" project and try this:

int main(int argc, char* argv[])
{
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE\n");
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8\n");
return 0;
}


See any problem with the output...? I get the first
string printed twice!


The disassembly confirms the problem:

8:
00401028 push offset string (0042201c)
0040102D call printf (00401070)
00401032 add esp,4
9:
00401035 push offset string (0042201c)
0040103A call printf (00401070)
0040103F add esp,4

It's the same address for both lines of code...


This is Visual C++ 6.0 with latest service packs,
etc. installed.


So the question is: Who do I report this to...?


--
<\___/> "To err is human, to moo bovine."
/ O O \
\_____/ FTB. For email, remove my socks.



David Lowndes

2004-03-28, 10:32 pm

>Create a new "Hello, world!" project and try this:
>
>int main(int argc, char* argv[])
>{
> printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE\n");
> printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8\n");
> return 0;
>}
>
>
>See any problem with the output...? I get the first
>string printed twice!


You're right - that's a good one!

Whatever the problem was, it's not there in VC7.1 (VS2003), so
presumably MS know about it, so maybe they have a known work-around if
you need one.

>So the question is: Who do I report this to...?


To be sure of a response I think you'll need to phone MS PSS.

Dave
--
MVP VC++ FAQ: http://www.mvps.org/vcfaq
Matt Porter

2004-03-28, 10:32 pm

how the heck did you find that one?


"fungus" <openglMY@SOCKSartlum.com> wrote in message
news:0iq7c.4099939$uj6.12760024@telenews.teleline.es...
> Create a new "Hello, world!" project and try this:
>
> int main(int argc, char* argv[])
> {
> printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE\n");
> printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8\n");
> return 0;
> }
>
>
> See any problem with the output...? I get the first
> string printed twice!
>
>
> The disassembly confirms the problem:
>
> 8:
> 00401028 push offset string (0042201c)
> 0040102D call printf (00401070)
> 00401032 add esp,4
> 9:
> 00401035 push offset string (0042201c)
> 0040103A call printf (00401070)
> 0040103F add esp,4
>
> It's the same address for both lines of code...
>
>
> This is Visual C++ 6.0 with latest service packs,
> etc. installed.
>
>
> So the question is: Who do I report this to...?
>
>
> --
> <\___/> "To err is human, to moo bovine."
> / O O \
> \_____/ FTB. For email, remove my socks.
>
>
>



Rudy Ray Moore

2004-03-28, 10:32 pm

Holy cow, how did you find this?

"fungus" <openglMY@SOCKSartlum.com> wrote in message
news:0iq7c.4099939$uj6.12760024@telenews.teleline.es...
> Create a new "Hello, world!" project and try this:
>
> int main(int argc, char* argv[])
> {
> printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE\n");
> printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8\n");
> return 0;
> }
>
>
> See any problem with the output...? I get the first
> string printed twice!
>
>
> The disassembly confirms the problem:
>
> 8:
> 00401028 push offset string (0042201c)
> 0040102D call printf (00401070)
> 00401032 add esp,4
> 9:
> 00401035 push offset string (0042201c)
> 0040103A call printf (00401070)
> 0040103F add esp,4
>
> It's the same address for both lines of code...
>
>
> This is Visual C++ 6.0 with latest service packs,
> etc. installed.
>
>
> So the question is: Who do I report this to...?
>
>
> --
> <\___/> "To err is human, to moo bovine."
> / O O \
> \_____/ FTB. For email, remove my socks.
>
>
>



fungus

2004-03-28, 10:32 pm

Matt Porter wrote:

> how the heck did you find that one?
>


It wasn't easy.

The original program was inserting strings into a
MySQL database and the database started complaining
that I was inserting duplicate strings.

After investigating, I reduced it to the code below
and the bug was still there.
[color=darkred]


--
<\___/> "To err is human, to moo bovine."
/ O O \
\_____/ FTB. For email, remove my socks.


Walter Briscoe

2004-03-28, 10:32 pm

In message <DpN7c.4123048$uj6.12891253@telenews.teleline.es> of Tue, 23
Mar 2004 02:37:23 in microsoft.public.vstudio.general, fungus
<openglMY@SOCKSartlum.com> writes[color=darkred]
>Matt Porter wrote:
>
>
>It wasn't easy.
>
>The original program was inserting strings into a
>MySQL database and the database started complaining
>that I was inserting duplicate strings.
>
>After investigating, I reduced it to the code below
>and the bug was still there.
>

The problem seems to be:
"Pool string constants" only compares 32 bytes to determine equality.

Not using /GF or /Gf gives a workaround. You may be able to introduce
differences in the 1st 32 bytes; you may want to use techniques which do
not make such heavy use of constants.

The trouble with using traditional commercial software is that you can't
fix the product yourself and the supplier has no interest in doing so
and supplies with an agreement which allows them to do so. Nobody is
sufficiently interested in overturning such agreements. (Free software
has other problems.)

Congratulations on providing the example. ;-)
--
Walter Briscoe
fungus

2004-03-28, 10:32 pm

Walter Briscoe wrote:
>
>
>
> The problem seems to be:
> "Pool string constants" only compares 32 bytes to determine equality.
>


Nope. I haven't got that turned on, and if you change
any letters near the end of the string the problem
goes away.

Besides, if that were true then every string in my
original program would have been equal. As it was
I got two clashes in 500 strings.

> The trouble with using traditional commercial software is that you can't
> fix the product yourself and the supplier has no interest in doing so
> and supplies with an agreement which allows them to do so. Nobody is
> sufficiently interested in overturning such agreements. (Free software
> has other problems.)
>


Let this stand as an example. Microsoft has been promising
another service pack for VC++ 6.0 for years (if nothing
else to fix the problem when you have Norton Antivirus
installed), but now that VS .Net is available they donīt
seem very interested...

....and I hate VS .Net. It's ugly and it seriously short
changes people who are only interested in C++ and don't
want to me "managed" by Microsoft.



--
<\___/> "To err is human, to moo bovine."
/ O O \
\_____/ FTB. For email, remove my socks.


Rudy Ray Moore

2004-03-28, 10:32 pm


"fungus" <openglMY@SOCKSartlum.com> wrote in message
news:1yU7c.4131682$uj6.12920530@telenews.teleline.es...
> ...and I hate VS .Net. It's ugly and it seriously short
> changes people who are only interested in C++ and don't
> want to me "managed" by Microsoft.


FYI, I work on a large native c++ cross platform gui application. (Takes
about 2o minutes to compile the whole thing).

I'm don't like VS .Net. Not because it's ugly or due to "managed code", but
because it's distugstingly slower than VS6, especially for my multi-project
workspace.

See my website for a comparison between VS6 and VS7.1 compile and link
times:


Rudy Ray Moore

2004-03-28, 10:32 pm


"Rudy Ray Moore" <rudymoore@hotmail.com> wrote in message
news:OSNmUVQEEHA.1376@TK2MSFTNGP10.phx.gbl...
> See my website for a comparison between VS6 and VS7.1 compile and link
> times:


Oops:

http://www.stankevitz.com/visualstudio/


fungus

2004-03-28, 10:32 pm

Rudy Ray Moore wrote:
>
> I'm don't like VS .Net. Not because it's ugly or due to "managed code", but
> because it's distugstingly slower than VS6
>


Oh, yeah, that too....VS .Net takes twice as long
to compile things.

It stayed on my machine for an afternoon or so then
I went back to VC++ 6.0.


PS: Microsoft, how do I get a refund for my $500...?



--
<\___/> "To err is human, to moo bovine."
/ O O \
\_____/ FTB. For email, remove my socks.


Walter Briscoe

2004-03-28, 10:32 pm

In message <1yU7c.4131682$uj6.12920530@telenews.teleline.es> of Tue, 23
Mar 2004 10:44:13 in microsoft.public.vstudio.general, fungus
<openglMY@SOCKSartlum.com> writes
>Walter Briscoe wrote:
>
>Nope. I haven't got that turned on, and if you change
>any letters near the end of the string the problem
>goes away.
>
>Besides, if that were true then every string in my
>original program would have been equal. As it was
>I got two clashes in 500 strings.


Please prove what you say!
You probably have /Gf implicitly set with /O1 or /O2. I am guessing.
If so I suggest you use the following which is derived from the
documentation:
:: /O1 /Og /Os /Oy /Ob1 /Gs /Gf /Gy Creates the smallest code in the majority of cases.
:: /O2 /Og /Oi /Ot /Oy /Ob1 /Gs /Gf /Gy Creates the fastest code in the majority of cases.

Can you reproduce the following? Please show a counter-example.
I failed to get anywhere with #pragma optimize.

C:\WINNT\Temp) cl /nologo /Gf doubles.C & doubles
doubles.C
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE

C:\WINNT\Temp) cl /nologo /GF doubles.C & doubles
doubles.C
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE

C:\WINNT\Temp) cl /nologo doubles.C & doubles
doubles.C
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8

C:\WINNT\Temp) type doubles.c
#include <stdio.h>

int main( void )
{
// 12345678 1 2345678 2 2345678 3 2345678
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE\n");
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8\n");
return 0;
}

C:\WINNT\Temp) cl /nologo /O1 doubles.C & doubles
doubles.C
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE

C:\WINNT\Temp)

--
Walter Briscoe
fungus

2004-03-28, 10:32 pm

Walter Briscoe wrote:

I think it's pretty obvious that the "compare 32 bytes"
theory is wrong. If that were so:

a) The compiler writer would be an idiot.

b) Somebody would definitely have noticed this before now.


[color=darkred]
>
> Please prove what you say!


a) This happens in a debug build - no optimizations!

b) My options (copied and pasted from the project settings) are:

/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG"
/D "_CONSOLE" /D "_MBCS" /Fp"Debug/bug.pch" /Yu"stdafx.h"
/Fo"Debug/" /Fd"Debug/" /FD /GZ /c


I didn't change any options. This is a brand new
command line "Hello, world" project with those
two lines of code pasted in.


--
<\___/> "To err is human, to moo bovine."
/ O O \
\_____/ FTB. For email, remove my socks.


Rudy Ray Moore

2004-03-28, 10:32 pm


"Walter Briscoe" <wbriscoe@ponle.demon.co.uk> wrote in message
news:aN4nYBwow$XAFwwp@ponle.demon.co.uk...
> "Pool string constants" only compares 32 bytes to determine equality.


32 bytes? Four characters?

printf("Hello world\n");
printf("Hell is a hot place\n");


Rudy Ray Moore

2004-03-28, 10:32 pm

"Rudy Ray Moore" <rudymoore@hotmail.com> wrote in message
news:eqgfEBdEEHA.4084@TK2MSFTNGP11.phx.gbl...
> 32 bytes? Four characters?


Doh... I wish I could retract that post. 32 bytes is 32 characters.
Oh,well, at least I'm not using my real name :)


Chris

2004-03-28, 10:32 pm

Just to make sure you all know....you don't have to use managed c++. You
can use VC++.net in the same way as VC++6.

Chris

"Rudy Ray Moore" <rudymoore@hotmail.com> wrote in message
news:OSNmUVQEEHA.1376@TK2MSFTNGP10.phx.gbl...
>
> "fungus" <openglMY@SOCKSartlum.com> wrote in message
> news:1yU7c.4131682$uj6.12920530@telenews.teleline.es...
>
> FYI, I work on a large native c++ cross platform gui application. (Takes
> about 2o minutes to compile the whole thing).
>
> I'm don't like VS .Net. Not because it's ugly or due to "managed code",

but
> because it's distugstingly slower than VS6, especially for my

multi-project
> workspace.
>
> See my website for a comparison between VS6 and VS7.1 compile and link
> times:
>
>



Walter Briscoe

2004-03-28, 10:32 pm

In message <gWf8c.4165566$uj6.13069399@telenews.teleline.es> of Wed, 24
Mar 2004 13:20:12 in microsoft.public.vstudio.general, fungus
<openglMY@SOCKSartlum.com> writes
>Walter Briscoe wrote:
>
>I think it's pretty obvious that the "compare 32 bytes"
>theory is wrong. If that were so:
>
>a) The compiler writer would be an idiot.

That is your assessment of the situation. I know everybody - including
me - makes idiotic mistakes.

>
>b) Somebody would definitely have noticed this before now.

Perhaps! Perhaps not!

>
>
>
What reason have you for not doing what I asked? You assume software
will behave in a reasonable manner. My experience suggests otherwise.
[color=darkred]
>
>a) This happens in a debug build - no optimizations!
>
>b) My options (copied and pasted from the project settings) are:
>
>/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG"
>/D "_CONSOLE" /D "_MBCS" /Fp"Debug/bug.pch" /Yu"stdafx.h"
>/Fo"Debug/" /Fd"Debug/" /FD /GZ /c
>
>
>I didn't change any options. This is a brand new
>command line "Hello, world" project with those
>two lines of code pasted in.


I infer - forgive me if wrong - that you are not comfortable working
with a command line. I gave you something which was fully specified.
I will try to use a crystal ball to guess what you did. I am slightly
irritated that you did not detail it yourself.

1) I started the IDE from the command line with msdev
2) I created a new "Win32 Console Application" project in a new
workspace. The project name is idouble; the location is c:\temp - I
removed idouble from this. I selected 'A "Hello World! application'.
That expects source to be in idouble.cpp.
3) I altered idouble.cpp to read:
// idouble.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int main(int argc, char* argv[])
{
// 12345678 1 2345678 2 2345678 3 2345678
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE\n");
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8\n");
return 0;
}

[This is quiet because stdafx.h quietly includes stdio.h]

4) "Rebuild All" built Debug\idouble.exe which fails as desired.
5) From idouble.plg and other knowledge, I created C:\Temp\idouble.bat.
It (roughly) duplicated what is done in the IDE by "Rebuild All" and
running the executable. I don't show it here because it is ugly and
pointed me to an IDE-oriented workaround.

6) I started simplifying idouble.bat. The problem vanished when I
removed /ZI from the idouble.cpp compilation line.
7) I went back to the IDE and found I had a workaround by changing
Project\Settings\C/C++/General/Debug Info: from "Program Database for
Edit and Continue" to "Program Database"
8) I was unsurprised to find the release build continued to fail. I
implicitly removed /Gf by changing /O2 in "Project Options:" to /Og /Oi
/Ot /Oy /Ob1 /Gs /Gy

In the real world, I assume you have a project which consists of many
modules. I suggest you make changes to the build instructions for the
module which has the problem. I leave the details to you.

Please show your experience and detail if and how it differs from mine.
--
Walter Briscoe
Walter Briscoe

2004-03-28, 10:32 pm

In message <gWf8c.4165566$uj6.13069399@telenews.teleline.es> of Wed, 24
Mar 2004 13:20:12 in microsoft.public.vstudio.general, fungus
<openglMY@SOCKSartlum.com> writes
[snipped complete article]
In my earlier work, I looked up /ZI in MSDN and found but did not report
the following which may be relevant:
/Zi Causes Code Motion Optimization Suppression
BUG: Expansion of __LINE__ Macro Is Incorrect When Using /ZI
PRB: Use of /ZI May Cause Access Violation
This contains a really useful "By default the compiler switch /ZI
(Program Data Base for Edit and Continue) uses the compiler switch /GF."
Unfortunately, there seems to be no way of switching off /GF or /Gf.
--
Walter Briscoe
fungus

2004-03-28, 10:32 pm

Walter Briscoe wrote:
>
> In my earlier work, I looked up /ZI in MSDN and found but did not report
> the following which may be relevant:
> /Zi Causes Code Motion Optimization Suppression


Whatever the hell that is.


--
<\___/> "To err is human, to moo bovine."
/ O O \
\_____/ FTB. For email, remove my socks.


fungus

2004-03-28, 10:32 pm

Walter Briscoe wrote:

>
>
> I infer - forgive me if wrong - that you are not comfortable working
> with a command line.


Not true. I'm an old Unix hack myself, I'm just not
good at using VC++ from the command line - just
*look* at how many options there are.

> I gave you something which was fully specified.
> I will try to use a crystal ball to guess what you did. I am slightly
> irritated that you did not detail it yourself.
>


Use the wizard to create a new "command line" project
of type "hello, world".

> 6) I started simplifying idouble.bat. The problem vanished when I
> removed /ZI from the idouble.cpp compilation line.
>
> In the real world, I assume you have a project which consists of many
> modules. I suggest you make changes to the build instructions for the
> module which has the problem. I leave the details to you.
>


I changed the strings, adding the "xxxx" part with sprintf()
at runtime.


--
<\___/> "To err is human, to moo bovine."
/ O O \
\_____/ FTB. For email, remove my socks.


karen

2004-03-28, 10:33 pm


"Walter Briscoe" <wbriscoe@ponle.demon.co.uk> wrote in message
news:dUJ2OB6TXUYAFwYe@ponle.demon.co.uk...
> In message <1yU7c.4131682$uj6.12920530@telenews.teleline.es> of Tue, 23
> Mar 2004 10:44:13 in microsoft.public.vstudio.general, fungus
> <openglMY@SOCKSartlum.com> writes
>
> Please prove what you say!
> You probably have /Gf implicitly set with /O1 or /O2. I am guessing.
> If so I suggest you use the following which is derived from the
> documentation:
> :: /O1 /Og /Os /Oy /Ob1 /Gs /Gf /Gy Creates the smallest code in the

majority of cases.
> :: /O2 /Og /Oi /Ot /Oy /Ob1 /Gs /Gf /Gy Creates the fastest code in the

majority of cases.
>

<snip>
> --
> Walter Briscoe


No matter what the compiler settings are, should the following code produce
the following output?
// hello1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int main(int argc, char* argv[])
{
printf("Hello World!\n");
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE\n");
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC8\n");
printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC9\n");
return 0;
}

(note that the last two strings differ by one char at the end of the line.)
And the output (sent to a text file so I could cut and paste it...)
Hello World!
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWRMM-2JD2-CWPE-Y3DE
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWX4A-EJ3A-H2U4-DHC9

It knows the last two strings aren't equal, and prints the last one
correctly.
-karen


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com