您的位置:首页 > 编程语言 > C语言/C++

Visual C++ 在windows 7 上预编译头错误unexpected precompiled header error, simply rerunning the compiler migh

2016-07-19 10:06 281 查看
之前有人在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的补丁包里中出现, 你现在则可以这样弄:

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

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

l 重启机器

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

 

多谢

Mark Roberts

Visual C++ Compiler Team

 

 

来源在这里
http://blogs.msdn.com/vcblog/archive/2009/11/12/visual-c-precompiled-header-errors-on-windows-7.aspx
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: