首先让我提供一些背景知识。生产代码中有两个线程,并且通过等待和信号来完成同步。下面给出代码的基本结构。 main.c创建线程。 main.c还调用funca(),该信号通知另一个线程。互斥量和条件变量在a.c中声明和初始化。 a.c还具有funca()的定义和thread_func()的定义。 thread_func()等待条件,并在收到信号后解锁互斥锁并执行一些工作。
pthread_create(thread_id, thread_func)
funca();
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也是错误的。
从内存转储中,我看不到任何内存覆盖的可能性。我也看不到使用未初始化的互斥锁/条件的任何可能,这可能导致此问题。有人可以帮我吗?
谢谢
答案 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)
内存损坏的原因可能很多。