iis多进程下的全局变量_全局变量初始化顺序探究

2023-10-26

缘起

上一篇文章——《调试实战 —— dll 加载失败之全局变量初始化篇》中,跟大家分享了一个由于全局变量初始化顺序导致的 dll 加载失败的例子。感兴趣的小伙伴儿可以点击阅读。

虽然我们知道了是由于全局变量初始化顺序导致的问题,也给出了解决方案。但是有一点却没有刨根问底——为什么改变文件在工程文件中的顺序就可以改变全局变量初始化顺序?是怎么影响的呢?本篇文章力求解决这个问题。

了解 Build

我们可以简单的把整个编译过程分成三个步骤(当然实际还有其它步骤,我们一般不关心):预编译,编译,链接。

预编译: 处理宏,#include 展开等。

编译: 以编译单元为单位生成对应的 .obj 文件。

链接: 把生成的.obj 文件和必要的文件链接成最后的应用程序。

猜想

因为编译是把符号放到对应的 .obj 中,链接的时候才把对应的 .obj 文件链接成最后的应用程序。链接的时候应该是按照 .obj 文件出现的先后顺序依次把 .obj 中的符号放到对应的位置。

思路

对比观察调整顺序前和调整顺序后的编译参数,链接参数。因为猜测是链接导致的问题,我们主要关注链接参数。

编译过程初探

当我们在 vs 中执行 build 时的整个过程如下图(使用 process monitor 捕获的):

可以清晰的看到,vs 在内部会启动 msbuild.exe 执行后续的操作。msbuild.exe 会间接启动 cl.exe 进行编译,link.exe 进行链接。我们还发现黄色高亮部分的 Tracker.exe ,这个进程主要用来加速编译的。具体可以参考《Inside the Microsoft Build Engine Using MSBuild and Team Foundation Build》 这本书的介绍,简单截图如下:

简化编译过程

因为 vs 会通过 msbuild.exe 执行操作,我们可以直接使用 msbuild.exe 进行编译。msbuild 有一个选项 TrackFileAccess 可以用来控制是否使用 FileTracker。为 false 时,不启用 FileTracker

为了简化问题,我们直接使用 msbuild.exe -p:TrackFileAccess=false project_file_to_build.vcxproj 来编译。

我们发现,传递给 cl.exelink.exe 的参数都是文件。猜测,应该是把参数保存到文件中传递的。据观察,这些文件会在执行完后被清理。得想办法在这些文件被删除之前保存一份,各位小伙伴儿有什么好办法吗?

我们先看下这些参数文件是谁创建和删除的,什么时候删除的。创建很简单,肯定是 msbuild.exe。删除呢?是 cl.exe / link.exe 还是 msbuild.exe 呢?又是什么时候删除的呢?相信下图能很好的回答这些问题了。

我想到两个思路:

  1. 因为这些文件是 msbuild.exe 创建/删除的,可以在 msbuild.exe 中文件操作的地方加断点。
  2. 可以暂停 cl.exe/link.exe 的执行,拷贝我们需要的文件到桌面。

第一个思路相对来说比较复杂,今天我们尝试第二个思路。我们该如何暂停呢?请出 gflags.exe

中断 link.exe

我们可以在 gflags.exe 中进行如下设置,这样当 link.exe 启动时就会中断到 windbg.exe 中了。

断下来后,我们可以在 windbg 中输入 !peb 观察参数,里面包含了我们需要拷贝的文件路径。

有了文件路径,我们就可以手动复制对应的文件到桌面慢慢研究了。

对比链接参数

调整 Test1.cpp Test2.cpp.vcxproj 中的顺序,按上面的方法分别保存传递给 link.exe 的参数文件,对比如下图(格式有调整):

发现在两次链接过程中,Test1.obj Test2.obj 出现的顺序是不一样的。

结论

哪个源码文件在 .vcxproj 中先出现,其对应的 .obj 文件在传递给 link.exe 的参数文件(.rsp)中越靠前,会被优先处理。.obj 中包含的全局变量会被优先处理。当进程启动时,执行全局变量初始化的时候会按照先后顺序初始化。

总结

  • vs 内部会使用 msbuild.exe 编译,我们也可以直接使用 msbuild.exe 进行编译。
  • 使用 msbuild.exe -p:TrackFileAccess=false 可以在编译的过程中不启动 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?redirectedfrom=MSDN&view=vs-2019

http://www.cppblog.com/xlshcn/archive/2007/12/07/37088.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iis多进程下的全局变量_全局变量初始化顺序探究 的相关文章

随机推荐

  • leetcode622-设计循环队列

    本题重点 1 选择合适的数据结构 2 针对选择的数据结构判断 空 和 满 这两点是不分先后次序的 在思考时应该被综合起来 事实上 无论我们选择链表还是数组 最终都能实现题中描述的 循环队列 的功能 只不过选择不同结构时 我们面临和需要解决的
  • 不是一个PDF文件或该文件已损坏

    之前用公司电脑打开PDF文档的时候 出现了这样的一种现象 就是提示格式错误 不是一个PDF文件或该文件已被损坏 有三种解决方法 1 有可能是电脑上自带的PDF阅读软件版本太低 出现了不兼容的现象 换个最新的PDF阅读器吧 我用了福昕阅读器很
  • 【死磕NIO】— 探索 SocketChannel 的核心原理

    大家好 我是大明哥 一个专注于 死磕 Java 系列创作的程序员 死磕 Java 系列为作者 chenssy 倾情打造的 Java 系列文章 深入分析 Java 相关技术核心原理及源码 死磕 Java https www cmsblogs
  • oracle不小心将表update修改了如何回滚

    oracle提供了一种闪回的方法 可以将某个时间的数据给还原回来 SELECT FROM T DIS EVENT RELATION TYPE AS OF TIMESTAMP TO TIMESTAMP 2023 08 08 15 31 00
  • python opencv 在线读取网络图片图像资源

    opencv在线读取网络图片图像资源 照例打开opencv3 3 0 python3 6官方文档 https docs opencv org master d8 dfe classcv 1 1VideoCapture html 详解 官方文
  • Adam和AdamW的区别

    Adam 与 Adamw的区别 一句话版本 Adamw 即 Adam weight decate 效果与 Adam L2正则化相同 但是计算效率更高 因为L2正则化需要在loss中加入正则项 之后再算梯度 最后在反向传播 而Adamw直接将
  • python框架和模型库_一个pytorch库,拥有最先进的架构,预训练模型和实时更新结果...

    PytorchInsight This is a pytorch lib with state of the art architectures pretrained models and real time updated results
  • first season last episode,Rachel finds out Ross likes her,what would she do???

    Scene Central Perk the whole gang is there Ross is showing pictures of his new baby boy Ben to the group Ross And here s
  • Flex布局

    之前一直都是使用position来定位块的位置 现在新学了一个比较主流的flex来定位块的位置 感觉确实比之前的好多了 现在总结下大概的用法 flex是把一个div分成主轴和交叉轴 其中主轴方向的定位有三个 1 flex direction
  • [OpenAirInterface实战-13] :OAI 基站配置文件详解

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 120791987 目录 第1章 基站配
  • Java中为什么数组没有实现Iterable接口,但可以使用foreach语句遍历?

    本质是转成fori形式的循环 上界是数组的size 直接上代码 package com finchina public class TstMain1 public static void main String args int ints
  • 西门子dcs系统组态手册下载_什么是PCS?----西门子PCS7篇

    PCS 7 PCS7是西门子的DCS系统 基于过程自动化 从传感器 执行器到控制器 再到上位机 自下而上形成完整的TIA 全集成自动化 架构 主要包括Step7 CFC SFC Simatic Net和WinCC以及PDM等软件 组态对象选
  • 华为OD题目: 租车骑绿道

    package com darling boot order od od19 import com google common base Strings import java util 租车骑绿道 p 题目 部门组织绿岛骑行团建活动 租用
  • ArrayBlockingQueue

    在java多线程操作中 BlockingQueue
  • [系统安全] 十七.Windows PE病毒概念、分类及感染方式详解

    您可能之前看到过我写的类似文章 为什么还要重复撰写呢 只是想更好地帮助初学者了解病毒逆向分析和系统安全 更加成体系且不破坏之前的系列 因此 我重新开设了这个专栏 准备系统整理和深入学习系统安全 逆向分析和恶意代码检测 系统安全 系列文章会更
  • Intellij Idea插件开发-创建项目层级的右键菜单

    在使用Android Studio的过程中 发现自带的一些插件无法满足项目的实际需要 便着手自己开发对应的插件 下面是我开发插件过程中的一个记录 会持续和大家分享 分享一 创建Project右键菜单 1 按照项目向导一步一步创建一个Demo
  • 刷脸支付通过人脸识别就可以完成付款

    发展个人码质优价廉所以说 刷脸支付是建立在长达几年的技术积累和市场认可的基础上建立起来的产品 并非是一蹴而就的 刷脸支付的到来 让我们的支付交易手段迈入一个新的阶梯 也可以说是进入了支付的时代 刷脸支付成为新的支付趋势的原因 缓解对外部媒介
  • 最小二乘法

    首先给出公式 最小二乘法的公式 y a x b 其中式中N是数据点的个数 注意 以上两式具有相同的分母 指逐项加法计算 取和 x指对所有的x值求和 y指对所以的y值求和 x 2 指对所有x的平方求和 xy指对所有的积xy进行取和计算 应注意
  • java-es查询

    目录 1 检索ES数据库 2 检索下级数据 3 1 检索多个字段 匹配同一个值 3 2 must 3 3 should 3 3 1 should 一个key多个value 4 java中匹配ES中多个字段查询 为什么加上 keyword反而
  • iis多进程下的全局变量_全局变量初始化顺序探究

    缘起 上一篇文章 调试实战 dll 加载失败之全局变量初始化篇 中 跟大家分享了一个由于全局变量初始化顺序导致的 dll 加载失败的例子 感兴趣的小伙伴儿可以点击阅读 虽然我们知道了是由于全局变量初始化顺序导致的问题 也给出了解决方案 但是