在国内可以做国外的网站吗,长沙哪个网站建设最好,电脑设计长春什么公司比较好,合肥百度推广优化排名缘起 我在上一篇文章——《调试实战 —— dll 加载失败之全局变量初始化篇》中#xff0c;跟大家分享了一个由于全局变量初始化顺序导致的 dll 加载失败的例子。感兴趣的小伙伴儿可以点击阅读。虽然我们知道了是由于全局变量初始化顺序导致的问题#xff0c;也给出了解决方案… 缘起 我在上一篇文章——《调试实战 —— dll 加载失败之全局变量初始化篇》中跟大家分享了一个由于全局变量初始化顺序导致的 dll 加载失败的例子。感兴趣的小伙伴儿可以点击阅读。虽然我们知道了是由于全局变量初始化顺序导致的问题也给出了解决方案。但是有一点却没有刨根问底——为什么改变文件在工程文件中的顺序就可以改变全局变量初始化顺序是怎么影响的呢本篇文章力求解决这个问题。了解 Build 我们可以简单的把整个构建过程分成三个步骤当然实际还有其它步骤我们一般不关心预编译编译链接。预编译 处理宏#include 展开等。编译 以编译单元为单位生成对应的 .obj 文件。链接 把生成的.obj 文件和必要的文件链接成最后的应用程序。猜想 因为编译是把符号放到对应的 .obj 中链接的时候才把对应的 .obj 文件链接成最后的应用程序。链接的时候应该是按照 .obj 文件出现的先后顺序依次把 .obj 中的符号放到对应的位置。思路 对比观察调整顺序前和调整顺序后的编译参数链接参数。因为猜测是链接导致的问题我们主要关注链接参数。编译过程初探 当我们在 vs 中执行 build 时的整个过程如下图使用 process monitor 捕获的vs-msbuild-cl-link可以清晰的看到vs 在内部会启动 msbuild.exe 执行后续的操作。msbuild.exe 会间接启动 cl.exe 进行编译link.exe 进行链接。我们还发现黄色高亮部分的 Tracker.exe 这个进程主要用来加速编译的。具体可以参考《Inside the Microsoft Build Engine Using MSBuild and Team Foundation Build》 这本书的介绍简单截图如下filetracker-introduce简化编译过程 因为 vs 会通过 msbuild.exe 执行操作我们可以直接使用 msbuild.exe 进行构建。msbuild 有一个选项 TrackFileAccess 可以用来控制是否使用 FileTracker。为 false 时不启用 FileTracker。为了简化问题我们直接执行 msbuild.exe -p:TrackFileAccessfalse project_file_to_build.vcxproj 。msbuild-cl-link-param我们发现传递给 cl.exe 和 link.exe 的参数都是文件。猜测应该是把参数保存到文件中传递的。据观察这些文件会在执行完后被清理。得想办法在这些文件被删除之前保存一份各位小伙伴儿有什么好办法吗我们先看下这些参数文件是谁创建和删除的什么时候删除的。创建很简单肯定是 msbuild.exe。删除呢是 cl.exe / link.exe 还是 msbuild.exe 呢又是什么时候删除的呢相信下图能很好的回答这些问题了。msbuild-remove-param-file我想到两个思路因为这些文件是 msbuild.exe 创建/删除的可以在 msbuild.exe 中文件操作的地方加断点。可以暂停 cl.exe/link.exe 的执行拷贝我们需要的文件到桌面。第一个思路相对来说比较复杂今天我们尝试第二个思路。我们该如何暂停呢请出 gflags.exe。中断 link.exe 我们可以在 gflags.exe 中进行如下设置这样当 link.exe 启动时就会中断到 windbg.exe 中了。gflags-set-debug-link断下来后我们可以在 windbg 中输入 !peb 观察参数里面包含了我们需要拷贝的文件路径。windbg-command-line有了文件路径我们就可以手动复制对应的文件到桌面慢慢研究了。对比链接参数 调整 Test1.cpp Test2.cpp 在 .vcxproj 中的顺序按上面的方法分别保存传递给 link.exe 的参数文件对比如下图格式有调整obj-link-order发现在两次链接过程中Test1.obj Test2.obj 出现的顺序是不一样的。结论 哪个源码文件在 .vcxproj 中先出现其对应的 .obj 文件在传递给 link.exe 的参数文件.rsp中越靠前会被优先处理。.obj 中包含的全局变量会被优先处理。当进程启动时执行全局变量初始化的时候会按照先后顺序初始化。总结 vs 内部会使用 msbuild.exe 编译我们也可以直接使用 msbuild.exe 进行编译。使用 msbuild.exe -p:TrackFileAccessfalse 可以在编译的过程中不启动 Tracker.exe对我们调查问题有帮助。我们可以在一个进程启动时就中断到调试器可以使用 gflags.exe 帮我们实现这一点。!peb 可以查看启动参数环境变量等信息。.vcxproj 中文件的顺序会影响最后链接时的顺序。参考资料 《Inside the Microsoft Build Engine Using MSBuild and Team Foundation Build》https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?redirectedfromMSDNviewvs-2019http://www.cppblog.com/xlshcn/archive/2007/12/07/37088.html需要你的