使遗留代码x64兼容时出现非法读/写错误

时间:2011-06-06 21:08:12

标签: c++ visual-studio-2010 64-bit unmanaged

我有以下MyType::Is_Inst ()函数,它在64位模式下返回时抛出无效的内存访问错误,但不是32位:

MyType MyType::Is_Inst () {
    unsigned char Bar=0;    
    MyType Foo={0};    
    return Foo;
    }

查看反汇编+步骤,程序在

行崩溃
mov  dword ptr [rax],ecx

...当程序基本上试图取消引用%rdx的原始值(从首次调用函数时),现在是%rax。但是,%rdx只是前一个函数调用遗留下来的垃圾。

我最后一次遇到这样的问题,是因为我错过了一些编译标志等。对于x64非托管c ++项目,我应该注意哪些设置?还有其他原因我可能会看到这种行为吗?

如果需要,我可以发布更多的反汇编。


MyType的类定义如下所示:

class __declspec(dllexport) MyType {
public:
    union {
        struct {
            unsigned int    Id     : 23;
            unsigned int    Flag   : 1;  
            unsigned int    Type   : 4;  
            unsigned int    Unused : 4;  /* 32 bits total */
            };

        unsigned int    All_Bits;          /* Full 32 bits of MyType */
        };

     /* There are some function definitions here, but no other 
        variables, aside from some statically defined ones. */
     };

更新:这是Is_Inst()反汇编的更简洁,优化的版本,它显示了问题。为简洁起见,我删除了之前的旧版本。

// MyType MyType::Is_Inst () {
// uchar Bar=0;
// MyType Foo={0};
   mov         dword ptr [rdx],0 /* %rdx is 0x17, from a prev fn call. */ 

// return Foo;
   mov         rax,rdx  
// }
   ret 

导致Is_Inst()被调用的代码:

...
for (Counter=0; Counter<N_Items; Counter++) {
    ...
    myOther32BitType = arrayOfMyOtherTypes [Counter]; /* Debugger shows this is ok. */ 

    if (myOther32BitType.8BitField==UNEQUAL_ENUM_VALUE) {
        /* Some stuff that doesn't happen. */
        }

    /* myOther32BitType.8BitField==0x17, so %rdx gets set to 0x17. */
    else if (strchr((char*)Uchar_Table_Of_Enum_Values, myOther32BitType.8BitField)) continue;

    /* %rdx gets set to 0x17 again. */
    else if (strchr((char*)Other_Uchar_Table_Of_Enum_Values,  myOther32BitType.8BitField)) continue;

    else if ( myOther32BitType.8BitField==EQUAL_ENUM_VALUE) {
        if (myType.Is_Inst ().All_Bits) { /* Is_Inst() called here. */
            return false;
            }
        ...
        }
    ...
    }

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

这看起来像VS2010中的same bug Qt people encountered。该报告链接到Microsoft Connect here。还有bug should be fixed in SP1。在SP1中修复了许多优化问题,因此我可能没有链接正确的(发现其他三个只是通过链接筛选)。

答案 2 :(得分:-1)

else if (strchr((char*)Other_Uchar_Table_Of_Enum_Values,  myOther32BitType.8BitField)) continue;

这看起来很可怕错误。您应该使用std::find

,而不是采用完全不必要的投射

事实上,您的整个代码看起来都充斥着C风格的不安全代码。内存管理对象在哪里?