gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 05:19:47 29 4
gpt4 key购买 nike

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

它发生在全局析构函数执行时。通常这是一个“double-free”错误,但我也看到了其他事情: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
  • 确保所有声明都来自 header /在定义 header 的地方包含 header

关于c++ - 执行静态对象的析构函数时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40984290/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com