执行静态对象的析构函数时崩溃

2023-12-30

有一个微妙的错误在我们的软件中不会以可预测的方式显现出来。

当全局析构函数执行时会发生这种情况。通常这是一个“双重释放”错误,但我也看到过其他事情:NULL-ptr 取消引用、对未分配任何内容的地址的 ptr 取消引用、访问未对齐(因为指针有垃圾值)、与损坏的堆栈......这样的例子不胜枚举。


这些神秘且难以重现的错误的原因:微妙地违反了“单一定义规则”。

一点背景...

因为我还很小,所以这个软件是使用以下链接链接的-zmuldefs链接器标志,指示链接器忽略如下情况。然后它被迫选择它遇到的第一个定义(当然链接器警告也被忽略):

$ cat /tmp/file1.cc
int x;
int main( int argc, char *argv[] ) { return x; }

$ cat /tmp/file2.cc
double x = 3.14159265358979;

$ gcc /tmp/file{2,1}.cc -o /tmp/test
/tmp/ccuTgbRy.o:(.bss+0x0): multiple definition of 'x'
/tmp/cchvHEav.o:(.data+0x0): first defined here
/usr/bin/ld: Warning: size of symbol 'x' changed from 8 in /tmp/ccYCIypE.o to 4 in /tmp/ccuTgbRy.o
collect2: error: ld returned 1 exit status

$ gcc /tmp/file{2,1}.cc -Wl,-zmuldefs -o /tmp/test
/usr/bin/ld: Warning: size of symbol 'x' changed from 8 in /tmp/ccWaeBBi.o to 4 in /tmp/ccSc9IiE.o

$ /tmp/test; echo $?
68

这与问题有什么关系

我遇到过四种基本情况会出现此问题:

$ cat /tmp/file1.cc
double x;  // (1) If file2.cc is linked first it may end up on
           // a dword boundary causing misaligned accesses
           // when used as a double.

std::string mystring; // (2) If file2.cc is linked first, the actual size
                      // of the object is sizeof(char*) so
                      // std::string::string() will clobber memory
                      // after the pointer.

std::string another; // (3)
                     // file1.cc is compiled with -fPIC & put into a
                     // shared library
                     // file2.cc is NOT compiled with -fPIC & is put
                     // into an executable
                     // 
                     // This will cause a very subtle problem: the two
                     // strings share the same piece of memory, but
                     // the constructor will execute once during the executable's
                     // _init() and once for each shared library with its own
                     // variable "another" when their _init() executes.
                     // The destructor will also execute multiple times

$ cat /tmp/file2.cc
int x;
char *mystring;       // (4) Modifying through this ptr will cause undefined
                      // behavior when the other file's "mystring" is used
std::string another;

导致大小或对齐方式更改的变量应报告为链接器警告,因此有人可能倾向于通过重命名有问题的变量(或其他变量)来解决问题。

但是,在以下情况下无法看出问题是否存在:

  • 对象大小相同(x 定义为 float/int & sizeof(float) == sizeof(int))
  • 违规变量(具有相同的大小和类型)存在于多个库和/或可执行文件中

确保您消除所有这些问题的唯一解决方案:

  • 摆脱-zmuldefs
  • 确保所有声明都来自标头/包含定义它的标头
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

执行静态对象的析构函数时崩溃 的相关文章

随机推荐

  • WordPress:更改管理子菜单顺序

    我已经创建并注册了一个管理页面作为 帖子 管理菜单下的子菜单 但问题是它出现在 wp 子菜单的末尾 即 标签 之后 如何更改此自定义管理页面子菜单条目的顺序以使其显示在 添加新项 之后 我正在使用此功能在 edit php 帖子菜单 下注册
  • postgresql连接2个表

    我有2个表tab1和tab2 tab2 tab1 id 引用tab1 id tab2 与 tab1 id 具有不同的值 我需要一个将 tab1 与 tab2 中的操作列连接起来的连接 以及 id 的最新值 tab1 id user file
  • Jquery 自动加载 gif 并在提交点击时禁用按钮

    是否可以自动显示 隐藏 ajax 加载 gif 并同时禁用 启用提交按钮 当提交按钮是样式化的而不是输入类型 提交时 目前 在提交时我这样做 save button id click function if save button id h
  • 运行时错误:对象不支持属性或方法

    我需要在一个相当大的项目中使用 jQuery 创建一个对话框 在某些地方 这个项目使用的 jquery 版本与我最近在窗口中使用的版本不同 我的代码如下所示 在 ascx 页面上
  • Autofac - 注册所有 Windows 窗体

    有没有办法让 Autofac 自动注册我的程序集中的所有 Windows 窗体 此功能很可能类似于 Autofac MVC 支持注册所有控制器的能力 现在 我这样做 foreach var type in Assembly GetExecu
  • 是否可以滚动 Treeview 的列内容,而不是 Tkinter 中的列窗口?

    我有一个带有 Treeview 小部件和一列的窗口 如果我添加足够的节点以使节点的文本超出窗口的宽度 则除非我更改 否则将无法水平滚动列宽使其比窗宽 这就是我的意思 我应该能够水平滚动 这样我就可以适应节点的文本 但水平滚动条被禁用 但是
  • 否定内部词法分析器和解析器规则

    否定元字符如何 在 ANTLR 的词法分析器和解析器规则中使用吗 否定可以发生在内部词法分析器和解析器规则 https stackoverflow com questions 4297770 practical difference bet
  • 如何存储不同类型的文档

    我有一个使用 SQL SERVER 2008 的网站 它允许用户上传 excel word txt pdf 媒体文件和其他格式的文件 就像Rapishare Megaupload 将它们存储到 SQL SERVER 中的最佳方法是什么 FI
  • Android Webview 锚链接(跳转链接)不起作用

    我的 Android 应用程序中有一个 WebView 它使用 loadDataWithBaseURL 方法加载 HTML 字符串 问题是本地锚链接 a href link 无法正常工作 单击链接时 它会突出显示 但不会滚动到相应的锚点 如
  • PyLucene 索引器和检索器示例

    我是 Lucene 的新手 我想用Python 3编写PyLucene 6 5的示例代码 我改变了this http graus co blog pylucene 4 0 in 60 seconds tutorial 该版本的示例代码 但是
  • 如何在 android 中配置 java.util.logging.logger 以使用放置在 sdcard 上的日志记录属性文件?

    我一直在尝试使用 java util logging logger 将内容记录到 SD 卡上的文件中 现在 我希望记录器使用我将在 sdcard 上提供的日志记录配置 属性文件 我一直在尝试的一种方法是 我一直在尝试使用 logmanage
  • HandleBars .Net If 比较

    我使用 Handlebars NET 作为我的邮件模板 因此我在服务器端宽度 ASP NET MVC 上生成模板 我需要这样的比较 但这不起作用 我能做些什么 Product ProdType is a enum property if P
  • eli5:具有两个标签的 show_weights()

    我想eli5 http eli5 readthedocs io en latest autodocs eli5 html eli5 show prediction为了了解术语对某些类别的预测的贡献 您可以运行这个脚本 import nump
  • 为什么在 [ x"$VAR" = x"VALUE" ] 中使用“x”?

    我可以在 unix shell 脚本中看到使用了以下构造 x VAR x VALUE 代替 VAR VALUE Why 因为如果变量之一为空 shell 并不总是完全表现良好 考虑如果 VAR为空 空并且 VALUE是 foo 你的两个结构
  • PHP header(): 302 暂时移动错误 [重复]

    这个问题在这里已经有答案了 在我的 web 应用程序中 我打开了一个模式 在该模式中 我正在另一个页面 ajax php 中使用 ajax 处理一些数据 在 ajax php 中完成处理后 我执行以下操作 header location b
  • 如何在 modelica 中进行局部敏感性分析

    我想在 Dymola 中进行局部敏感性分析 以评估影响建筑物 多户住宅 能耗的不同参数 谁能给我一些建议 如何在 Dymola Modelica 软件中做到这一点 您可以将模型导出为 FMU 然后按照多种不同路径之一使用 FMU 进行敏感性
  • 如何使用 xargs 将特定文件从一个目录移动到另一个目录?

    假设我输入这个命令 find etc info name c xargs I grep l importantFile 现在我拥有了所有我感兴趣的文件 这些文件具有后缀 c 和关键字 importantFile 如何将其移动到我当前的目录之
  • 我应该使用哪个 CMS 来管理没有编程经验的小型网站? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 CMS 系统来管理一个简单的小型网站 该网站将使用纯 HTML 和一些 JavaScript 可能是原型库 制作 我之所以
  • 如何配置 nginx.ingress.kubernetes.io/rewrite-target 和 spec.rules.http.paths.path 以满足以下 URI 模式

    我该如何配置nginx ingress kubernetes io rewrite target and spec rules http paths path满足以下 URI 模式 aa bb aa coolapp aa bb aa coo
  • 执行静态对象的析构函数时崩溃

    有一个微妙的错误在我们的软件中不会以可预测的方式显现出来 当全局析构函数执行时会发生这种情况 通常这是一个 双重释放 错误 但我也看到过其他事情 NULL ptr 取消引用 对未分配任何内容的地址的 ptr 取消引用 访问未对齐 因为指针有