pthread_cond_signal()中的分段错误

时间:2018-09-28 14:38:23

标签: c linux pthreads

首先让我提供一些背景知识。生产代码中有两个线程,并且通过等待和信号来完成同步。下面给出代码的基本结构。 main.c创建线程。 main.c还调用funca(),该信号通知另一个线程。互斥量和条件变量在a.c中声明和初始化。 a.c还具有funca()的定义和thread_func()的定义。 thread_func()等待条件,并在收到信号后解锁互斥锁并执行一些工作。

main.c

pthread_create(thread_id, thread_func)

funca();

a.c

pthread_mutex_t     renotify_signal_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t      renotify_signal_cond = PTHREAD_COND_INITIALIZER;

thread_func() {
        pthread_mutex_lock(&renotify_signal_mutex);
        pthread_cond_wait(&renotify_signal_cond, &renotify_signal_mutex);
        pthread_mutex_unlock(&renotify_signal_mutex);

        <<<<< Does some work here
}

funca() {

    pthread_mutex_lock(&renotify_signal_mutex);
    pthread_cond_signal(&renotify_signal_cond);
    pthread_mutex_unlock(&renotify_signal_mutex);

}

pthread_cond_siganl()中出现分段错误。在gdb中检查后,我可以看到条件变量绑定到的互斥锁已损坏,即该地址应为signal_mutex的地址,但实际上它指向的是无效内存。请参见下面的gdb输出:

(gdb) x/40 0x85084a0
0x85084a0 <renotify_signal_mutex>:      0x00000001      0x00000000      0x00003b1a      0x00000000
0x85084b0 <renotify_signal_mutex+16>:   0x00000002      0x00000000      0x00000000      0x00000000
0x85084c0 <renotify_signal_cond>:       0x00000001      0x00000008      0x00000004      0x00000000
0x85084d0 <renotify_signal_cond+16>:    0x00000004      0x00000000      0x00000003      0x00000000
0x85084e0 <renotify_signal_cond+32>:    0x0200a084      0x00005008      0x00000000      0x00000000
0x85084f0 <_breakpoint_target_>:        0x00000000      0x00000000      0x00000000      0x00000000
0x8508500 <bgp_asn_buffer>:     0x00000000      0x00000000      0x00000000      0x00000000
0x8508510 <bgp_asn_buffer+16>:  0x00000000      0x00000000      0x00000000      0x00000000
0x8508520 <bgp_asn_buffer+32>:  0x00000000      0x00000000      0x00000000      0x00000000
0x8508530 <bgp_asn_buffer+48>:  0x00000000      0x00000000      0x00000000      0x00000000
(gdb) p renotify_signal_cond
$51 = {
  __data = {
    __lock = 1,
    __futex = 8,
    __total_seq = 4,
    __wakeup_seq = 4,
    __woken_seq = 3,
    __mutex = 0x200a084,
    __nwaiters = 20488,
    __broadcast_seq = 0
  },
  __size = "\001\000\000\000\b\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\204\240\000\002\bP\000\000\000\000\000\000\000\000\000",
  __align = 34359738369
}
gdb) x 0x200a084
0x200a084:      Cannot access memory at address 0x200a084
(gdb)


(gdb) p &renotify_signal_mutex
$53 = (pthread_mutex_t *) 0x85084a0 <renotify_signal_mutex>

正如您在gdb输出中看到的那样,pthread_cond_t结构中的互斥锁字段指向无效内存,而不是指向renotify_signal_mutex。 __nwaiters = 20488也是错误的。

从内存转储中,我看不到任何内存覆盖的可能性。我也看不到使用未初始化的互斥锁/条件的任何可能,这可能导致此问题。有人可以帮我吗?

谢谢

2 个答案:

答案 0 :(得分:1)

在您的代码示例中,这可能是一个简化,但是pthread_create看起来不正确。 pthread_create的格式为:

int pthread_create( pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

这可能会损坏内存。另外,thread_func应该作为&thread_func传递给pthread_create。

答案 1 :(得分:0)

内存损坏的原因可能很多。

  • 由于任何其他变量,正在发生内存损坏。可能写数组超出范围或写到const字符串或类似的东西。有时堆栈跟踪未显示确切的损坏点。
  • 似乎在pthread_cond_wait()时发生了互斥体绑定。还有另一个线程使用相同的条件变量和不同的互斥锁。但是,此处无法访问互斥地址。因此,损坏的互斥锁不是全局变量。