also with /EHa: VC6 optimizer bug with _com_raise_error 
Author Message
 also with /EHa: VC6 optimizer bug with _com_raise_error

hi all,

Quote:
> Your code will work as expected if you add the /EHa compiler option.
> The default (/EHsc) does not handle asynchrnous exceptions.

i posted some sample code that caused an access violation when
compiled with /O2. ms support thankfully responded and recommended to
set /EHa, enabling asynchronous exception handling. the access
violation was gone, but it apparently was only hidden.

the following code will again AV when compiled with /EHa (by the way,
this code will work when compiled without /EHa...) the only difference
to the previous code is one additional structB on the stack,
immediately after winMain, again changing stack layout slightly.

thanks for any tips on how to reliably remove this problem.

-manfred

#define WIN32_LEAN_AND_MEAN            
#include <windows.h>
#include <comdef.h>               // for _com_raise_error
//#include "SEHframe.h"

struct structA
{
        structA()   { x = 0; y = 0; }
        ~structA()  { }
        double x, y;

Quote:
};

struct structB
{
        structB(char* p) : m_ptr(0) { }
        ~structB()
        {
                if(m_ptr != NULL)
                        ++*m_ptr;                       // never
executed
        }
        char* m_ptr;

Quote:
};

void func(structB, structA, structA, int, int, int)
{
        structA a, b, c;
        _com_raise_error(E_FAIL);       // causes access violation
with /O2

Quote:
}

int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
        structB p(0), q(0);     // here, one additional instance

        try {
//              WalkSEHFrames("pre func");    
                func(0, structA(), structA(), 0, 0, 0);
        }
        catch(const _com_error& ce) {
                ce;
                ::MessageBox(0, "made it into catch block", "/O2 bug",
MB_OK);
        }
        return 0;

Quote:
}



Sun, 27 Mar 2005 14:35:31 GMT  
 also with /EHa: VC6 optimizer bug with _com_raise_error

Quote:
> hi all,

> > Your code will work as expected if you add the /EHa compiler option.
> > The default (/EHsc) does not handle asynchrnous exceptions.

> i posted some sample code that caused an access violation when
> compiled with /O2. ms support thankfully responded and recommended to
> set /EHa, enabling asynchronous exception handling. the access
> violation was gone, but it apparently was only hidden.

Good repro :)  I didn't like the /EHa explanation either!

For me, this code AV's when compiled with /EHa /O2 or with /EHsc /O2.
Compiled with /O1 it's fine.  Sounds like with VC6 using /O1 is the only
workaround.  Given that _com_raise_error really doesn't do anything too
special, in my mind that makes /O2 unusable in VC6, since there's no telling
when some other equally innocent-looking code will run into this bug.

In any case, this bug is apparently fixed in VS.NET, where the code works no
matter what options I try.

-cd



Sun, 27 Mar 2005 21:38:33 GMT  
 also with /EHa: VC6 optimizer bug with _com_raise_error
FWIW, here some more details.

the AV is happening in the structB destructor. the line i innocently
marked with 'never executed' _is_ executed, and that's the problem.

i changed structB slightly to:

struct structB
{
#define MYPTR ((char*) 0xdeadbeef)
        structB(char* p) : m_ptr(MYPTR) { }
        ~structB()
        {
                if(m_ptr != MYPTR)
                        ::MessageBox(0, "pointer corrupted", "",
MB_OK);
        }
        char* m_ptr;

Quote:
};

m_ptr is initialized and never changed, so it should retain its value.

assembler code for the destructor looks like this:

        cmp     DWORD PTR [ecx], -559038737             ; deadbeefH
        je      SHORT $L41963
        push    ...

$L41963:
        ret     0

so, [ecx] is supposed to be pointing to the instance of structB, and
hence to it's single member, the pointer. in our problematic cases,
however, ecx is off by 4 bytes. it points to garbage; the long next to
the pointed value holds the real structB. dereferencing the garbage
value causes the AV.

-manfred



Mon, 28 Mar 2005 00:00:35 GMT  
 also with /EHa: VC6 optimizer bug with _com_raise_error
Manfred,

OK my  explanation was wrong<beating the head..>

I got the compiler devs to take a look at this and please see the answer by
"Eric Christoffersen  and Paul Leathers" in original thread.
Sorry for the confusion.

Btw, I am not always wrong!

Hope this helps.

Thank you,
Bobby Mattappally
Microsoft VC++/C# Team

This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------

Quote:

>Newsgroups: microsoft.public.vc.language
>Subject: Re: also with /EHa: VC6 optimizer bug with _com_raise_error
>Date: Wed, 09 Oct 2002 18:00:35 +0200

>FWIW, here some more details.

>the AV is happening in the structB destructor. the line i innocently
>marked with 'never executed' _is_ executed, and that's the problem.
m
>i changed structB slightly to:

>struct structB
>{
>#define MYPTR ((char*) 0xdeadbeef)
>    structB(char* p) : m_ptr(MYPTR) { }
>    ~structB()
>    {
>            if(m_ptr != MYPTR)
>                    ::MessageBox(0, "pointer corrupted", "",
>MB_OK);
>    }
>    char* m_ptr;
>};

>m_ptr is initialized and never changed, so it should retain its value.

>assembler code for the destructor looks like this:

>    cmp     DWORD PTR [ecx], -559038737             ; deadbeefH
>    je      SHORT $L41963
>    push    ...

>$L41963:
>    ret     0

>so, [ecx] is supposed to be pointing to the instance of structB, and
>hence to it's single member, the pointer. in our problematic cases,
>however, ecx is off by 4 bytes. it points to garbage; the long next to
>the pointed value holds the real structB. dereferencing the garbage
>value causes the AV.

>-manfred



Mon, 28 Mar 2005 08:38:34 GMT  
 also with /EHa: VC6 optimizer bug with _com_raise_error

Quote:

>I got the compiler devs to take a look at this and please see the answer by
>"Eric Christoffersen  and Paul Leathers" in original thread.
>Sorry for the confusion.

no problem, thanks for forwarding.
Quote:

>Btw, I am not always wrong!

i'm sure! ;-)

br,
-manfred



Mon, 28 Mar 2005 15:00:19 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. VC6 optimizer bug with _com_raise_error (sample code)

2. Beta 2 optimizer bug (works in VC6 SP5)

3. Optimizer bug in beta 2 (works in VC6 SP5)

4. MS VC6/7/7.1 optimizer bug

5. VC++ Optimizer bug?

6. Where do I post optimizer bugs?

7. optimizer bug in VC7.1 final beta Visual Studio .Net 2003

8. 2 VC7 optimizer bugs

9. VC7 Compiler Optimizer Bug with /O2 /Ob1

10. VC7 optimizer bug

11. MC++ tail recursion optimizer bug in virtual function

12. Optimizer Bug?

 

 
Powered by phpBB® Forum Software