【问题标题】:crash in __tcf_0在 __tcf_0 中崩溃
【发布时间】:2011-07-26 10:57:30
【问题描述】:

在我们的应用程序中,我们在执行后观察到崩溃。堆栈跟踪显示崩溃是因为 cpp 文件中存在全局变量。生成的 valgrind 报告显示了无效的 free/read/write 错误,这意味着它正在尝试删除不再有效的内存。

文件:crash.cpp

namespace abc
{
  MutexClass obj; //A is a class
  // remaining code

  ChildClass::ChildClass():Parent(obj){}

}

然后我们将给定的变量放在一个未命名的命名空间中,我们不再遇到崩溃并且 valgrind 不会报告无效的读/写/错误:

文件:nocrash.cpp

namespace
{
  MutexClass obj;
}

namespace abc
{
  // remaining code
  ChildClass::ChildClass():Parent(obj){}
}

以上示例是导致问题的类的精简版本。

我们不确定为什么将变量放在未命名的命名空间中会消除此问题。它会改变清理顺序吗?我们尝试编写简单的代码,但我们观察到的清理顺序对于这两种情况都是相同的。

Mutex 对象作为参数传递给基类构造函数。 Mutex 对象的唯一用途是在基类构造函数中使用。 Mutex 对象不会在代码中的其他任何地方使用。

崩溃的 valgrind 报告

================================================ ==

线程 1:

大小为 1 的读取无效

在 0x3A24C08260:pthread_mutex_destroy(在 /lib64/libpthread-2.5.so 中)

通过 0x5ABE3DD:osl_destroyMutex (libuno_sal.so.3)

通过 0xECD69D1: osl::Mutex::~Mutex() (mutex.hxx:65)

通过 0xEF207F5:__tcf_0 (Dispose.cpp:27)

通过 0x3A24033354:退出(在 /lib64/libc-2.5.so 中)

by 0x3A2401D97A:(在 main 下方)(在 /lib64/libc-2.5.so 中)

地址 0xeb6bb88 是一个大小为 40 的块内的 16 个字节,已释放

在 0x4A05B3E:空闲 (vg_replace_malloc.c:323)

通过 0x3A24033354:退出(在 /lib64/libc-2.5.so 中)

by 0x3A2401D97A:(在 main 下方)(在 /lib64/libc-2.5.so 中)

大小为 4 的无效写入

在 0x3A24C08272:pthread_mutex_destroy(在 /lib64/libpthread-2.5.so 中)

通过 0x5ABE3DD:osl_destroyMutex(在 libuno_sal.so.3 中)

通过 0xECD69D1: osl::Mutex::~Mutex() (mutex.hxx:65)

通过 0xEF207F5:__tcf_0 (Dispose.cpp:27)

通过 0x3A24033354:退出(在 /lib64/libc-2.5.so 中)

by 0x3A2401D97A:(在 main 下方)(在 /lib64/libc-2.5.so 中)

地址 0xeb6bb88 是一个大小为 40 的块内的 16 个字节,已释放

在 0x4A05B3E:空闲 (vg_replace_malloc.c:323)

通过 0x3A24033354:退出(在 /lib64/libc-2.5.so 中)

by 0x3A2401D97A:(在 main 下方)(在 /lib64/libc-2.5.so 中)

无效的 free()/delete/delete[]

在 0x4A05B3E:空闲 (vg_replace_malloc.c:323)

通过 0xECD69D1: osl::Mutex::~Mutex() (mutex.hxx:65)

通过 0xEF207F5:__tcf_0 (Dispose.cpp:27)

通过 0x3A24033354:退出(在 /lib64/libc-2.5.so 中)

by 0x3A2401D97A:(在 main 下方)(在 /lib64/libc-2.5.so 中)

地址 0xeb6bb78 是大小为 40 的块内的 0 个字节已释放

在 0x4A05B3E:空闲 (vg_replace_malloc.c:323)

通过 0x3A24033354:退出(在 /lib64/libc-2.5.so 中)

by 0x3A2401D97A:(在 main 下方)(在 /lib64/libc-2.5.so 中)

================================================ ==

Dispose.cpp :27 行定义了互斥变量。

我们将不胜感激有关此事的任何帮助

谢谢,

苏迪普

【问题讨论】:

  • 请发布一个最小的、独立的示例来展示您的问题。如果这真的不可能,那么至少发布一些包含问题部分的相关代码。
  • 您可能需要提供您正在使用的确切编译器/工具版本(看起来像 g++ 的某个版本)以及用于构建可执行文件的命令行。
  • 我已经编辑了我的帖子并添加了一些相关代码,希望对您有所帮助
  • 哇 - 这不是一大堆代码。由于这是运行时崩溃,因此可能需要更多关于运行时发生的事情的信息。如果您不愿意发布实际代码,为什么不至少发布堆栈跟踪和 valgrind 报告?

标签: c++


【解决方案1】:

检查您的其他文件。您可能在命名空间 abc 中有另一个名为 obj 的全局变量。更改为未命名的命名空间与 C 中的 static 具有相同的效果,这避免了名称冲突(如果这是可能的,任何其他不同于 abc 的命名空间也将停止该问题)。这种错误通常会导致链接错误,但有时也会发生奇怪的事情。

请注意,其他文件不会使用的全局变量应位于未命名的命名空间中,以避免名称冲突。

【讨论】:

  • 我检查了所有文件,同名文件不存在。我什至将 obj 重命名为一些奇怪的名称,这样它就不会与其他名称冲突,但我仍然遇到同样的崩溃。
【解决方案2】:

您向我们展示的代码没有问题。

也许问题出在 A 类上?

【讨论】:

    【解决方案3】:

    您的变量是否使用带下划线开头的名称?

    如果是这样的话,你发现问题很正常。

    带有初始下划线的全局名称是保留的,不应使用。在任何上下文中,也可以使用首字母下划线后跟大写字母的名称,或带有多个连续下划线的名称。

    这是一条规则,由于我不太了解的原因,许多程序员经常为了好玩而打破它......

    【讨论】:

      【解决方案4】:

      像您一样移动代码将重新排序 A 相对于同一翻译单元中的其他全局变量的构造和销毁。如果您之前创建了 A,它将在稍后被删除。 (后进先出原理)。其他对象现在可能能够依赖A。检查之前创建的对象之前A,现在之后A

      【讨论】:

      • 感谢您的回复,这个翻译单元中唯一存在的全局对象是 MutexClass obj
      猜你喜欢
      • 2021-05-14
      • 2022-11-02
      • 2014-03-12
      • 2020-02-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-28
      • 2011-06-15
      • 2016-12-18
      相关资源
      最近更新 更多