fork系统调用导致分段错误

时间:2010-06-04 07:03:31

标签: c multithreading solaris

我编写了一个多线程程序,该线程的实现方式是分叉子进程,并通过这个子进程加载了几个模块。

在我一次测试期间,我发现进程(在solaris平台上运行)中止了一次,并且它产生了一个分段错误。在浏览转储文件时,我非常震惊地看到solaris中的fork()系统调用导致了这种分段错误。

下面是fork()abort时的堆栈跟踪:

(l@5) stopped in (unknown) at 0xfe524970
0xfe524970:     <bad address 0xfe524970>
(/opt/SUNWspro/bin/../WS6U2/bin/sparcv9/dbx) where
  [1] 0xfe524970(0xfe524970, 0x0, 0xffffffff, 0x1, 0x0, 0x0), at 0xfe52496f
  [2] run_prefork(0xfecc04b8, 0xfecc04d0, 0x242f4, 0xfea5d3c8, 0x0, 0x0), at 0xfec97ce8
  [3] _ti_fork1(0x1, 0x1ab18, 0x0, 0x0, 0x0, 0x0), at 0xfea5d3c8
  [4] _ti_fork(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfea5d50c

有人能描述为什么solaris中的fork()系统调用会导致这种行为吗?

3 个答案:

答案 0 :(得分:1)

增加:

可能的情况可能是(让我们以C ++为例):

  • 在主题A中创建对象
  • 线程B调用一个调用fork()
  • 的方法
  • 线程A删除对象,而线程B仍然在运行fork()
  • 之前
  • 在实际调用fork()
  • 期间,内存地址无效

根据时间安排,这或多或少可能发生。也许你可以通过引入一些睡眠来强制执行这种情况......(如果你觉得这可能就是这种情况)

另一个问题可能是某些硬件缺陷。我会让一个工具检查RAM运行,看看是否有问题,然后再进一步查看。如果是这种情况,请告诉我们。

另一种可能性是系统代码中的一个错误,它无法解释为什么有时它不起作用。对我来说,问题似乎不太可能。

PS地址at 0xfe52496f是奇数/不是四的倍数,这对于优化程序来说并不常见。这也暗示了缺陷RAM的方向......我希望我错了,另一方面,如果我是对的,你知道该怎么做......

答案 1 :(得分:1)

混合叉子和线程通常是不明智的。这是因为分叉进程只有一个线程,即调用fork的线程。新进程中不存在所有其他线程,这意味着任何共享内存资源都处于未知状态。另一个线程可以持有互斥锁,但永远不会释放它等。有一些机制可以缓解这种情况,例如pthread_atfork,但作为一般规则,你应该只在工作时尽快调用exec有多个线程。您是在父进程或新子进程中进行分类吗?

答案 2 :(得分:0)

我认为您的堆栈或堆栈指针可能在您调用fork时已损坏。在您调用fork()之前,或者您已经实际用完了堆栈空间并且堆栈指针只是处于该限制之下。

调用其他函数或在调用alloca之前将memsetfork该区域分配给适当的内存为0将显示是否属于这种情况,因为错误会提前出现。

如果你在一个进程的非主线程中分叉(我不熟悉Solaris的线程模型,所以我可能会大肆吹嘘)你也可能会以某种方式指定/分配这个线程(一个调用fork)堆栈的方式,以防止在fork之后新进程可以访问它。

这是可重复的吗?它是否一直发生?