Ошибка сегментации в pthread_cond_signal () - PullRequest
0 голосов
/ 28 сентября 2018

Во-первых, позвольте мне представить некоторые сведения.В производственном коде есть два потока, и синхронизация выполняется через ожидание и сигнал.Базовая структура кода приведена ниже.main.c создайте тему.main.c также вызывает funca (), которая сигнализирует другому потоку.Переменная мьютекса и условия объявляется и инициализируется в acac, также имеет определение funca () и определение thread_func ().thread_func () ожидает условия и, получив сигнал, разблокирует мьютекс и выполняет некоторую работу.

main.c

pthread_create(thread_id, thread_func)

funca();

ac

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 голосов
/ 01 октября 2018

Может быть много причин для повреждения памяти.

  • Повреждение памяти происходит из-за любой другой переменной.Возможно, запись массива выходит из-под контроля или запись в константную строку или что-то подобное.Иногда трассировка стека не показывает точную точку повреждения.
  • Кажется, что привязка мьютекса происходит во время pthread_cond_wait ().Есть другой поток, использующий ту же переменную условия с другим мьютексом.Но здесь адрес мьютекса не доступен.Итак, поврежденный мьютекс не является глобальной переменной.
0 голосов
/ 28 сентября 2018

Это может быть упрощением в вашем примере кода, но 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...