__attribute__((constructor)) 调用顺序混乱

2024-03-11

答案here https://stackoverflow.com/questions/8433484/c-static-initialization-vs-attribute-constructor表明 __attribute__((constructor)) 未被调用after静态初始化,按声明顺序调用。

那么,如果不能保证所有数据初始化时都会调用它,那么它的目的是什么呢?我们也可以将 ((constructor)) 代码放在 Foo 构造函数中。

我正在寻找一种方法,在共享库中拥有将在初始化所有静态数据并调用静态构造函数后执行的代码。我看到人们推荐 __attribute__((constructor)) 作为 DllMain 的替代品;我们可以看到这是错误的,因为一些静态数据可能仍未初始化。

当然,在单个文件(编译单元)中我们可以安排静态数据。但在典型的程序中会有很多文件。有没有一种方法可以保证在共享库中的所有其他静态变量初始化后,一个文件中的 ((constructor)) 一定会被调用?

如果我将带有静态初始化(构造函数、对象等)的文件放在 gcc 命令行的末尾:

g++ -shared -fPIC source1.o source2.o MyLastInitChance.o

该文件的静态构造函数是否保证最后被调用?我进行了实验,当我更改源文件的顺序时,printfs 的顺序也会更改;但它是否在某处指定并保证在编译系统/计算机之间相同?

例如引用一段话:

在链接时,gcc 驱动程序将 crtbegin.o 紧接在所有内容之前 可重定位文件和 crtend.o 在所有之后立即 可重定位文件。© http://l4u-00.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node4.html

根据我的理解,上面的引用意味着传递给链接器的 .o 文件的顺序定义了静态初始化的顺序。我对么?

另一个有趣的可能解决方案可能是编写一个调整静态初始化的 GCC 插件(例如,将代码添加到 .ctors 部分等)。但这只是一个想法,也许有人可以扩展。

另一种可能的解决方案是呈现 https://bugzilla.mozilla.org/show_bug.cgi?id=606137这里。简而言之,可以使用外部构建后工具对可执行文件(库)中的 .ctors 条目重新排序。但我不是 ELF 格式的专家;我想知道这是否可能并且足够容易以这种方式调整 .so 文件。

我感兴趣的是解决一个特定的问题,或者证明它是不可能解决的(至少为什么上面的解决方案不起作用)。


您可以尝试使用链接描述文件ld。您可以阅读更多相关内容here http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_toc.html,但我想你正在寻找的是

.ctors : { *(SORT(.ctors)) MyLastInitChance.o(SORT(.ctors)) }
.dtors : { *(SORT(.dtors)) MyLastInitChance.o(SORT(.dtors)) }

in SECTIONS{...}堵塞。那应该重新安排.ctorsso 文件提供的部分将调用它的构造函数作为最后一个。显然,如果您发现自己需要更先进的解决方案,也可以使用;)

提示:编写自己的链接脚本很乏味。使用ld's --verbose打印出使用的链接脚本并修改它的选项。然后使用添加链接脚本-T switch.

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

__attribute__((constructor)) 调用顺序混乱 的相关文章

  • 为什么使用数组索引循环数组比指针访问慢?

    我正在读Kochan的书 Programming in C 在第 14 页的 指针和数组 部分中 264 他说 一般来说 索引数组的过程比执行索引过程花费更多的时间 访问指针内容的过程 其实这也是主要原因之一 为什么使用指针来访问数组的元素
  • 如何转发声明要在 unique_ptr 的标准容器中使用的类

    在智能指针的标准容器中使用它时 是否可以避免完整的类定义可见 例如 我无法编译以下内容 include
  • 打印 STDOUT/STDERR 并将它们写入 Bash 中的文件?

    有没有办法让 Bash 将 STDOUT STDERR 重定向到文件 但仍然将它们打印到终端 这会将 STDOUT 和 STDERR 重定向到同一个文件 some command 2 gt 1 tee file log Example to
  • EULA 接受 Bash 脚本

    我有一个尝试安装垃圾箱的脚本 除了 bin 在 more 中打开 EULA 之外 一切正常 在脚本再次开始并自行完成安装之前 您必须手动 ctrl c 退出此 more 实例 因为这更多的是逃离 shell 所以脚本在打开后不知道要运行什么
  • Monitor.Pulse & Wait - 意外行为

    http www codeproject com Articles 28785 Thread synchronization Wait and Pulse demystified http www codeproject com Artic
  • 为什么 ObservableCollection 有两个集合构造函数?

    The 可观察集合 T https msdn microsoft com en us library ms668604类有两个构造函数 可以在其中传递项目集合 一个构造函数接受一个IEnumerable T 另一个List T 鉴于List
  • UI 线程正在阻塞调用 COM 对象的后台线程

    我正在开发一个通过第三方 COM 库与外部设备通信的应用程序 我试图让与设备的所有通信都通过后台线程 以防止通信问题搞砸我的应用程序 并消除在 UI 线程中进行通信所引入的一些其他复杂性 问题是 每当发生导致主 UI 线程阻塞的情况 即调用
  • 使用左连接获得不适当的输出

    我正在尝试获取变体列表 并且对于每个变体都获取所有subvariants list无论子变体属于何处 特别的Test say 100 这是示例数据 Id TestId SourceSubVariantId TargetSubVariantI
  • 在 Linux 服务器上创建和编辑 MS-Word 文档?

    希望开发处理文档的服务器端应用程序 源文档大多是MS Word 2003 2007 即MS版本的Docx 希望服务器应用程序能够在linux或windows上运行 想知道在linux下读写MS Word文件最好的工具或库是什么 兼容性是最重
  • 如何将输出重定向到 boost 日志?

    我有一个使用boost log的C 程序 我加载了用户提供的动态链接库 我想将 stderr 重定向到 boost 日志 以便用户的库随时执行以下操作 std cerr lt lt Some stuff 它产生相同的结果 BOOST LOG
  • WCF 服务中的缓冲区大小

    我们有一个 WCF 服务 它执行某些存储过程并将结果返回给 silverlight 客户端 某些存储过程最多返回 80K 行 下面给出的是 web config 中服务的设置
  • 快速将文本附加到文本框

    我有一个BackgroundWorker正在发布消息的线程 使用BeginInvoke在 GUI 中的文本框中 方法 write debug text 在文本框中显示文本使用AppendText并将文本写入Console 外观上是这样的Ba
  • 如何解决 boost::multi precision::cpp_dec_float 除法错误

    除以boost multiprecision cpp dec float有某种舍入误差 如下 include
  • C中使用JNI从对象获取对象

    public class Student private People people private Result result private int amount 这是 Java 中类的示例 在C中 我试图获取 学生 中的 人 但失败了
  • NSubstitute - 测试特定的 linq 表达式

    我在当前正在开发的 MVC 3 应用程序中使用存储库模式 我的存储库界面如下所示 public interface IRepository
  • 调用泛型类的方法

    这是上下文 我尝试编写一个映射器来动态地将域模型对象转换为 ViewModel 对象 我遇到的问题是 当我尝试通过反射调用泛型类的方法时 出现此错误 System InvalidOperationException 无法对 Contains
  • 从数据库配置中的连接字符串中删除 SSIS 密码

    我有一个 SSIS 包 它使用 SQL 服务器中的 SSIS 配置表来检索 OLE DB 连接管理器的连接字符串属性 问题是我还需要相同的连接字符串来调用使用实体框架的程序集 我尝试访问连接管理器连接字符串属性 但 SSIS 总是删除密码
  • Selenium - 模式对话框存在 - 如何接受信息?

    我有以下问题 在页面上提交一些日期后 我有一个如图所示的模式对话框 我想单击 ENTER 来浏览该模式 但它不起作用 我有以下代码 driver FindElement By CssSelector input submit Click A
  • 推断“x => { throw .. }”的 Lambda 与重载方法中的 Func 匹配吗?

    我不明白为什么 C 最终在以下 LINQPad 代码中执行不正确的扩展方法 void Main Actual Sync Action Expected Sync Action Run x gt x Dump Actual Async Tas
  • DbContext.SaveChangesAsync 异常处理

    当搭建新的脚手架时ApiController通过 Visual Studio 2013 中的异步操作和实体框架支持 某些方法可以包装DbContext SaveChangesAsync https msdn microsoft com en

随机推荐

  • 如何用Java解析ini文件? [复制]

    这个问题在这里已经有答案了 这是一个示例 ini 文件 link 1 alias My Link 1 link https www yandex ru link 2 alias My Link 2 link https mail ru li
  • Python中的变量插值[重复]

    这个问题在这里已经有答案了 可能的重复 在Python中打印变量的非Pythonic方式 https stackoverflow com questions 3534803 unpythonic way of printing variab
  • kafka 是否有默认的 Web UI [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有几个关于卡夫卡的问题 1 Kafka 有默认的 Web UI 吗 2 我们如何优雅地关闭独立的kafka服务器 kafka控制台
  • 如何在悬停图像时向下滚动?

    我想当悬停图像时 它会向下滚动到图像的末尾 我有两个问题 当用户将鼠标悬停在图像上时如何滚动到图像的末尾 目前 我开始将鼠标悬停在图像上 它没有滚动到图像的末尾 如何控制鼠标悬停在图像上时滚动的速度 My code body margin
  • 用户未定义:Nodejs/Express + Passport

    我的问题非常类似于这个问题 https stackoverflow com questions 16434893 node express passport req user undefined然而答案似乎对我不起作用 我看到用户也从未选择
  • ASC2.0 和帧元标记

    显然 新的 ActionScript Compiler 2 0 不再支持旧的 frame 元标记 该元标记允许您将预加载器添加到纯 ActionScript 项目中 我已经验证了这个 IntelliJ 切换 首选 ActionScript
  • Eclipse DDMS 窗口不显示任何内容 +android

    在模拟器中运行我的应用程序时 我的 Eclipse DDms 窗口未显示任何内容 空 logcat 空文件浏览 等 有时 如果我重新启动 Eclipse 它会起作用 但并非总是如此 为什么要这样挂 即使我多次遇到同样的问题 我用来做的是转到
  • Blazor Timer 调用异步 API 任务来更新 UI

    我正在 Blazor 服务器端页面中设置计时器 目标是每 x 秒调用一次 API 并根据返回值更新 UI 我得到这个代码 private string Time get set protected override void OnIniti
  • Firefox 在 FF2 中加载 Google Analytics 时出现“加载脚本错误”

    我正在开发的项目使用 window onerror 事件处理程序来报告用户问题 我注意到有一个用户似乎无法加载 Google Analytics 脚本 我们的网站没有看到很多流量 所以我不确定这种情况有多普遍 但到目前为止 它似乎只影响了一
  • 如何从 Spark 堆中删除/处置广播变量?

    要广播变量以使变量在集群上每个节点的内存中只出现一次 可以执行以下操作 val myVarBroadcasted sc broadcast myVar 然后在 RDD 转换中检索它 如下所示 myRdd map blar gt val my
  • Javascript中的累积分布函数

    我正在寻找一种在 Javascript 中计算累积分布函数的方法 有没有实现这个的类 您有想法让它发挥作用吗 它不需要 100 准确 但我需要对其值有一个很好的了解 http en wikipedia org wiki Cumulative
  • 如何将视图放入 Bundle

    我将动态创建的 EditText 添加到布局 onClick 按钮方法 当我旋转屏幕时 添加的编辑文本消失 如何将它们添加到捆绑包中以将它们放入 onSavedInstanceState 方法中 或者 还有其他方法可以做到这一点吗 我知道我
  • 使用 dplyr 中转换后的数据替换 SQL 数据库表

    我经常在 dplyr 中转换数据时替换数据 尤其是在处理大型数据集时 当我使用 SQL 支持的数据集时 我不知道如何优雅地做到这一点 至少不是使用 SQLite 我在 dplyr DB vignettes 或 SO 中找不到任何关于这个目标
  • 将 CameraX 捕获的 ImageProxy 转换为位图

    我正在使用 CameraX 并且很难将捕获的 ImageProxy 转换为位图 经过搜索和尝试 我制定了解决方案 后来我发现这不是最佳的 所以我改变了设计 这迫使我放弃了工作时间 由于我 或其他人 将来可能需要它 我决定在这里发布一个问题并
  • 有效的不可变对象有意义吗?

    在书里Java 并发实践 http jcip net 它解释了 有效不可变 对象与可变对象并发方面的优势 但它并没有解释 有效地不可变 对象将提供什么优势really不可变的对象 我不明白 你不能吗always在您决定安全地发布 有效不可变
  • Rails ActiveRecord:使用 LEFT JOIN 而不是 INNER JOIN 进行连接

    我有这个代码 User find all limit gt 10 joins gt user points select gt users count user points id group gt user points user id
  • 具有依赖项初始化错误的自定义包:ModuleNotFoundError 或 ImportError

    我正在创建一个具有以下结构的自定义包 test package README md setup py my package my package py init py tests tests py 我的包依赖于 pygdbmi 因此我将其添
  • 在 Windows 上设置 Apache 虚拟主机

    如何在 Windows 上为多个域名设置虚拟主机 我将把它用于我自己的测试项目 我需要设置三个项目 目前我正在使用 xampplite 作为可移植的 Apache www foo bar com http www foo bar com g
  • 使用 Spring Profiles 运行 gradle 任务(集成测试)

    需要通过 gradle 使用 spring 配置文件运行测试 gradle clean build 我添加了任务 task beforeTest doLast System setProperty spring profiles activ
  • __attribute__((constructor)) 调用顺序混乱

    答案here https stackoverflow com questions 8433484 c static initialization vs attribute constructor表明 attribute constructo