VS2008在windows7上预编译头错误C1859错误

本文转载自:http://blog.csdn.net/jocklyhu/article/details/5663576


相关其他文章:

http://connect.microsoft.com/VisualStudio/feedback/details/597858/c1859-bug-in-windows-7-x64-is-still-there

http://support.microsoft.com/kb/976656                    (实际操作中按照这个链接的方法3重启计算机解决问题)


之前有人在win7 上遇到了类似的错误, Error      1     fatal error C1859: 'Debug/CppDllExport.pch' unexpected precompiled header error, simply rerunning the compiler might fix this problem f:/document/visual studio 2008/codefx/visual studio 2008/cppdllexport/cppdllexport.cpp   18    CppDllExport

 

这个错误一般出现在以下条件:

Visual C++ 编译器是在 win7 上被调用的;

预编译头(PCH) 被启用 (enable) ;

/analyze 被启用了,   这不是一个必须的条件 ,  但是增加了遇到问题的重现几率)

 

尽管错误提示建议道:  简单的重新编译吧 ,  但是这个情况可能好转不了.  事实上 ,  这个 简单 的错误起因是预编译头和 win7 的增强安全技术 .

 

Visual c++ 预编译头和 ASLR

预编译的头文件存储着编译在某时刻的状态 ”, 这个状态的信息可以被之后的编译器重用 .  之前的 15 ,  编译器都是把预编译头以文件放着 ,  再从虚拟内存里读取 , 这样有 99.999%的可靠并且效率也挺好的 . 不过这玩意也是架构上的一个痛点 .

 

因为 PCH文件本身包含着内部指针 , 它在被重新载入的时候 ,  必须是写入虚拟内存的时候那个相同的地址 .  所以如果 PCH被之后的编译器加载的时候指针会变得不一样或错误 . 复杂点说 , PCH  还包括多态对象和每个多态对象自包含的虚方法表指针 (virtual function table pointer –VFTP), 这个表指针 ,  指向了模块中的虚方法 .  这样子 ,  PCH 中的多态对象依赖于某个特殊模块的指针表时候 , 模块必须以创建 PCH 文件时候指针值载入.  如果模块以不同地址加载的话 , PCH中的 VFTP 指针   就不对了 .

 

说了这么长 , 简单说就是 ,  无论是 PCH还是模块 ,  都不能在编译器变动 . Visual C++编译器将在启动前检这 2个条件 , 要不然立刻就报这个错说一下地址空间布局随机化 (Address Space Layout Randomization (ASLR) .的一点算法 , ASLR可以通过随机进程的模块 , 来减少一些恶意攻击模块的影响 .  VISTA的时候 , VS2008通过  /dynamicbase:no  在编译前来绕过了这个东西 , 当然 ,  win7上这个情况变糟了点 .

 

所以一开始的想法是通过把编译模块地址放到一个安全的地方 ,(还是绕过 ASLR,  比如减少模块的重调用次数 ), 糟糕的是失败了,   模块地址还是会移动。   因为一些让人郁闷的因素,如 NativeDLL loader,进程创建顺序, devenv.exe条用 cl.exe等等,  错误很难调试,   就像蝴蝶效应,   牵一发而动全身。

 

解决方案

这个修复将于 VS2010 vs2008的补丁包里中出现,  你现在则可以这样弄:

禁用  /analyze (C++ => advanced => enable code analysis for C++)

清除项目。  (之前的预编译头都删了)

重启机器

禁用 PCH文件 (C++ => Precompiled headers => create/use pre-compiled headers)

 

 来源在这里

http://www.cnblogs.com/read-acquisitions-docs/archive/2009/12/02.html



你可能感兴趣的:(windows开发)