• 记一次问题排查心得


    记一次问题排查心得

    平时程序运行的好好的,昨天收到一则用户上报,在xp系统下面,程序启动后弹出“应用程序正常初始化(0xc0150002)失败,请单击确定,终止应用程序”.

    遇到这个问题后,在自己的XP虚拟机里面调用一把,果然也出现这个问题,接下来记录解决这个问题的全过程。

    定位问题

    测试同事平时也测过XP系统,但在某些XP系统上面无法启动,考虑可能是某些XP系统上面没有安装对应的VC运行库导致的,于是乎在本机上面分别下载各种版本(05,08,10)的VC运行库,因为我们的开发环境是VS2010,所以最高支持到10即可。

    然后就是各种安装、卸载、检测组合情况,最后发现,只有在同时安装05和08的redist才能正常运行,因此,推测出程序中使用了用05和08的VS版本编译出来的库。考虑到现在程序中大部分的库都是自己写的组件,这样的问题只有可能发生在引用到的第三方库上面去。

    由于临近发布,想要在不改变程序的基础上解决问题,最快的方法是拷贝05和08中某些影响到程序正常启动的dll,

    • 通过depends工具查看exe所依赖的dll,将缺失的dll从外部拷贝进去,发现不行

      1. 微软原版系统安装好后,是不会自带VC++运行库和.Net Framework的
      2. LoadLibrary加载dll,如果指定dll给了完整路径,则只会在指定路径下面去寻找,如果没有给完整路径,只给了名称,则依次从应用程序exe当前目录,系统目录(system32),环境变量Path中去寻找dll,找到则加载到内存,没找到则报错。
    • 通过安装卸载05和08的redist安装程序,对比WIndows目录下面WinSxs目录的变化情况,猜测05和08安装后具体安装了哪些dll文件,将这些缺失的dll文件手动拷贝进程序当前目录下,发现还是不行

      1. 通过这种方法的尝试,我知道了VC运行库不仅仅是一些dll,还有配合这些dll一起使用的mainfest,如果仅仅是拷贝dll到应用程序当前目录的话,是不能解决问题的,详细见mainfest文件参考.
    • 因为知道如何让程序正常启动,考虑从正常启动的角度去查看在启动过程中加载的dll,由于是在虚拟机里面,因此如何调试在虚拟机里面的程序,就成了下一步的问题

      1. 如何在VS中远程调试虚拟机中的程序,参考链接 VS2010远程调试
      2. 通过查看正常情况下的启动,没发现什么异常。通过查看异常情况下的启动,发现程序在加载libcurl.dll时就报错退出了,错误情况,可以参考 LdrpWalkImportDescriptor错误解决,在这里面学到一招,可以通过直接查看dll的二进制源码,以Hex进制查看,搜索VC关键字得知该dll是由哪个版本的编译出来的,如果当前系统没有对应版本的运行库,那就会启动失败。

    解决问题

    经过种种尝试后,决定在不改变exe的情况下,只能重新编译curl库,为了保证上线的正确性,重新编译curl库需要的源码版本需要和当前使用的curl库源码版本一致,所使用的编译选项也要一致,编译curl参考网上现有教程,如何在Windows平台下面编译libcurl库

    Manifest

    以下内容来自 What is a Manifest(in Windows)

    Mainfest文件可以嵌入Exe或者Dll,也可以以独立文件存在,当为独立文件存在时,命名必须为应用程序的名字,后缀为.manifest.被dll文件或者其他库使用的manifest通常被称为assembly manifests,被嵌入dll中的manifest用来指定dll中调用dll运行时的指定版本依赖.
    Mainfest中可以指定程序需要的运行级别(requestedExecutionLevel),指定窗口公用组件版本(Microsoft.Windows.Common-Controls)

  • 相关阅读:
    严蔚敏数据结构习题3.14
    Effective C++ Item 34 Differentiate between inheritance of interface and inheritance of implementation
    Effective C++ Item 33 Avoid hiding inherited names
    Effective C++ Item 19 Treat class design as type design
    Effective C++ Item 18 Make interfaces easy to use correctly and hard to use incorrectly
    Effective C++ Item 17 Store newed objects in smart pointer in standalone statements
    Effective C++ Item 16 Use the same form in corresponding uses of new and delete
    Effective C++ Item 15 Provide access to raw resources in resource-managing classes
    Effective C++ Item 14 Think carefully about copying behavior in resource-managing classe
    Effective C++ Item 13 Use object to manage resources
  • 原文地址:https://www.cnblogs.com/cherishui/p/7089523.html
Copyright © 2020-2023  润新知