来自死亡多线程进程的核心转储

发布于 2024-10-17 10:15:24 字数 1571 浏览 8 评论 0原文

我的多线程应用程序(C++、SunOS)与共享库动态链接。程序中有多个线程,其中一些来自库。其中一个线程调用 exit() ,并导致从共享库中的另一个线程生成核心转储:

(dbx) where
  [1] 0x0(0xbeee0b30, 0x0, 0x0, 0x1c00, 0x1, 0xbeee0b50), at 0x0
  [2] STLCollectionWrapper<std::vector<SM_Timer*,std::allocator<SM_Timer*> > >::empty(0xbeee0b30, 0x0, 0x0, 0x1c00, 0xbca12200, 0x0), at 0xbee04690
  [3] GenPtrSortVec<SM_Timer,std::less<SM_Timer>,std::allocator<SM_Timer> >::isEmpty(0xbeee0b30, 0x0, 0x0, 0x0, 0x4fb0e0, 0xbd436b90), at 0xbee04424
  [4] sm_tmr_process(0x341000, 0x8e400, 0xbeeba00f, 0x1c00, 0x1, 0xbeee0800), at 0xbee03968
  [5] sm_nm_process_timeouts(0xbc67bf94, 0xbc67bf98, 0xbd4c3800, 0x0, 0xbca12200, 0xbee830f0), at 0xbee813dc
  [6] TimerThreadObject::poll(0x0, 0xbc67c000, 0x0, 0x0, 0xbedf1530, 0x1), at 0xbedf15f4
(dbx) thread
current thread ($thread) is t@null
(dbx) lwps
  l@1 LWP suspended in __SLIP.FINAL__A()
  l@3 LWP suspended in find_composition_start()
o>l@6 signal SIGSEGV in 0x0()

堆栈帧 6-4 来自 libA,帧 3-2 来自 libB。框架 1 必须是从 C++ 标准库(/usr/lib/libCstd.so.1?)调用的。如您所见,此调用失败。

在第 4 帧,代码调用 GenPtrSortVec 类型的全局对象的 isEmpty() 方法。该对象位于定义方法 sm_tmr_process() 的同一模块的堆栈中。随后在第 2 帧,代码调用了 STL 向量对象的 empty() 方法。该向量是 GenPtrSortVec 类的一个字段。

关于此问题,我有以下问题:

  1. 为什么第一帧的地址为 0x0?

  2. 是在取消程序中的所有线程之前,libCstd 是否可能已从垂死的进程中卸载?请注意,libCstd 会作为动态依赖项自动加载到进程中。

还有两个关于退出进程的问题:

  1. 在取消所有线程并销毁全局/静态对象之前,自动加载的共享库是否可能已被自动卸载?

  2. 是否有可能在取消所有线程之前全局或静态对象已被销毁?

My multithread application (C++, SunOS) is dynamically linked with shared libraries. There are several threads in the program, some of them are from the libraries. One of such threads calls exit() and it results in generating core dump from another thread in shared library:

(dbx) where
  [1] 0x0(0xbeee0b30, 0x0, 0x0, 0x1c00, 0x1, 0xbeee0b50), at 0x0
  [2] STLCollectionWrapper<std::vector<SM_Timer*,std::allocator<SM_Timer*> > >::empty(0xbeee0b30, 0x0, 0x0, 0x1c00, 0xbca12200, 0x0), at 0xbee04690
  [3] GenPtrSortVec<SM_Timer,std::less<SM_Timer>,std::allocator<SM_Timer> >::isEmpty(0xbeee0b30, 0x0, 0x0, 0x0, 0x4fb0e0, 0xbd436b90), at 0xbee04424
  [4] sm_tmr_process(0x341000, 0x8e400, 0xbeeba00f, 0x1c00, 0x1, 0xbeee0800), at 0xbee03968
  [5] sm_nm_process_timeouts(0xbc67bf94, 0xbc67bf98, 0xbd4c3800, 0x0, 0xbca12200, 0xbee830f0), at 0xbee813dc
  [6] TimerThreadObject::poll(0x0, 0xbc67c000, 0x0, 0x0, 0xbedf1530, 0x1), at 0xbedf15f4
(dbx) thread
current thread ($thread) is t@null
(dbx) lwps
  l@1 LWP suspended in __SLIP.FINAL__A()
  l@3 LWP suspended in find_composition_start()
o>l@6 signal SIGSEGV in 0x0()

The stack frames 6-4 are from libA, frames 3-2 from libB. Frame 1 must have been called from C++ standard library (/usr/lib/libCstd.so.1?). As you see, this call failed.

At frame 4 the code called isEmpty() method of global object of type GenPtrSortVec. This object is located in the stack in the same module where the method sm_tmr_process() is defined. Later at frame 2 the code called empty() method of STL vector object. This vector is a field of GenPtrSortVec class.

I have the following questions regarding this issue:

  1. Why the first frame has address 0x0?

  2. Is it possible that libCstd had been unloaded from the dying process prior to cancelling all threads in the program? Note that libCstd was automatically loaded into the process as a dynamic dependency.

And two more questions about exiting from the process:

  1. Is it possible that automatically loaded shared libraries had been automatically unloaded prior to cancelling all threads and destroying the global/static objects?

  2. Is it possible that global or static objects had been destroyed prior to cancelling all threads?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

葬花如无物 2024-10-24 10:15:24

1.1 - 可能是空指针调用(参见 Jörgen)

1.2 - 否

2.1 - 否

2.2 - 可能

1.2/2.1:当程序加载到内存中时,会加载共享库。然后,动态链接器将扫描所有外部引用并修复它们。这就是动态链接的过程。这不会被撤消,即操作系统不会卸载以这种方式加载的库。一旦程序终止,整个进程映像就会被丢弃。

2.2 - 这取决于您的应用程序。全局/共享对象的初始化可能会出现问题 - 请参阅静态初始化惨败。这同样适用于破坏。两种情况下的顺序都是由实现定义的。

1.1 - possibly a null pointer call (see Jörgen)

1.2 - no

2.1 - no

2.2 - possibly

1.2/2.1: Shared libraries are loaded when the program is loaded in memory. The dynamic linker will then scan through all external references and fix them up. This is the process of dynamic linking. This won't be undone, i.e. no library loaded this way will be unloaded by the OS. The whole process image is trashed once the program terminates.

2.2 - that depends on your application. Initialization of global/shared objects can be problematic - see the static initialization fiasco. The same applies for destruction. The order in both cases is implementation defined.

小傻瓜 2024-10-24 10:15:24

答案 1:您可能调用了 NULL 函数指针。可能不是直接的,而是间接的。您是否可以用零覆盖对象的 vtable,然后调用其虚拟方法?

Answer to 1: You probably called a NULL function pointer. Possibly not directly, but indirectly. Could you have overwritten the vtable of an object with zeros, and then called on of its virtual methods?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文