【问题标题】:Why my app crashes on Win XP unless i install VS2005 runtime?为什么我的应用程序在 Win XP 上崩溃,除非我安装 VS2005 运行时?
【发布时间】:2011-11-08 04:23:14
【问题描述】:

我正在尝试调查为什么我用 VC 2008 编写的应用程序会在 bare Windows XP 上崩溃,并显示 c0000005。它适用于任何 Windows vista 和 7。在 XP 上,它会在没有其他信息的情况下崩溃。以下是我头疼几天的细节和结果,一个接一个地排除了原因。详情如下:

  • 我有带有 iexplore 6 的 XP Mode 的 Win7 Ultimate,大概没有任何补丁。

  • 我只安装我的程序而不是其他任何东西,因为它应该是安装和运行的东西,不需要额外的包。

  • 我的应用已编译入 VC2008 运行时(使用 /MT,而不是 /MD 编译器开关)

  • 我使用的是 firebird 嵌入式,它需要 VC2005 (已编辑,我之前写过 VC2008) 库,所以我把它们放在我的应用程序中工作目录

  • 当我在这台 XP Mode 机器上安装 VC++ 2008 时,它不再崩溃,因此无法以这种方式调试

  • 我已将此错误的发生范围缩小到 VC2005 运行时 - 在我安装它之后,我的应用程序立即停止崩溃。但我不知道什么可以使用它的组件。在 VC2008 IDE 下运行发行版时,没有任何显示正在加载任何 vc2005 库(奇怪,如果我自己这么说的话)。

我的应用程序的链接器的依赖项列出了这些(我只添加了前两个,其余的由 VisualStudio 提供):jpeg.lib、gdiplus.lib、kernel32.lib、user32.lib、gdi32.lib、winspool.lib、 comdlg32.lib, advapi32.lib, shell32.lib, ole32.lib, oleaut32.lib, uuid.lib, odbc32.lib, odbccp32.lib, comctl32.lib, %(AdditionalDependencies)

我也在使用 IBPP firebird 接口,它动态加载这些,因此它们存在于我的应用程序的目录中(它们需要 msvc?80.dlls): fbembed.dll、ib_util.dll、icudt30.dll、icuin30.dll、icuuc30.dll、msvcp80.dll、msvcr80.dll

请告知为什么 vc2005 运行时可以作为我的应用程序在裸机 Win XP 上不崩溃的补救措施。或者我如何在目标机器上不安装 vc 2008 的情况下调试那个。我开始责怪 windows xp 的组件。最终,我希望我的应用不需要任何额外的包,例如 VC2008 或 2005,尤其是当我的应用的任何组件都不需要后者时。

【问题讨论】:

    标签: visual-c++ access-violation


    【解决方案1】:

    我也在使用 IBPP firebird 接口... msvcp80.dll, msvcr80.dll

    答案就在您的问题中,这些 DLL 是 VS2005 运行时支持 DLL。它们不能存储在您的 exe 目录中,它们必须在并行缓存中注册。这通常不会导致 AV,但如果代码不检查 LoadLibrary() 的返回值,这也不是不可能的。您可以为他们下载安装程序from Microsoft。它与 Windows XP 没有任何关系,您只是碰巧尝试在已安装 DLL 的机器上运行该程序。例如在开发机器上很常见。

    如果您不想依赖它们,那么您将不得不重建那些需要它的 DLL。这是个好主意,依赖多个版本的 CRT 是非常不健康的。

    如果您想知道为什么必须处理这个问题:Microsoft 试图将 DLL Hell 置于开发人员的膝上而不是用户的膝上。他们已经撤回了这一点,VS2010 再次使其成为用户问题。我想那是班加罗尔的一场盛大派对。

    【讨论】:

    • 感谢您的回答。请详细说明您所写的这种不健康状况——在我的一个项目中,我同时使用了用 VC2008 构建的 oracle OCI 和用 VC2005 构建的 firebird 库。 (顺便说一句,这两个 VC2005 库与一些清单一起包含在 Firebird 嵌入式包中,从技术上讲,不是我将它们放在我的 exe 目录中)。我是否理解我应该关心各种数据库提供商使用的 dll 是如何构建的?对此无能为力,我真的不想重建他们的客户端 dll...在这种情况下可能发生的最糟糕的情况是什么?
    • 崩溃或内存泄漏。就像一个返回 std::string 的 api 函数。在一个 CRT 中分配,在另一个中释放。这取决于 Windows 版本。设计一个不存在这个问题的 API 必须小心谨慎。基本规则是它不能分配必须由调用者删除或释放的对象或内存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多