Я столкнулся с довольно неприятной проблемой: у меня есть программа, которая создает один поток в начале, этот поток запускает другие вещи во время своего выполнения (fork () сразу же, за которым следует execve ()).
Вот bt обоих потоков в точке, где моя программа достигла (я думаю) тупика:
Поток 2 (LWP 8839):
# 0 0x00007ffff6cdf736 в __libc_fork () по адресу ../sysdeps/nptl/fork.c:125
# 1 0x00007ffff6c8f8c0 в _IO_new_proc_open (fp = fp @ entry = 0x7ffff00031d0, command = command @ entry = 0x7ffff6c26e20 "ps -u brejon | grep \" cvc \ "
# 2 0x00007ffff6c8fbcc в _IO_new_popen (command = 0x7ffff6c26e20 "ps -u user
| grep \" cvc \ "| wc -l", mode = 0x42c7fd "r") на iopopen.c: 296
#3-4 ...
# 5 0x00007ffff74d9434 в start_thread (arg = 0x7ffff6c27700) в pthread_create.c: 333
# 6 0x00007ffff6d0fcfd в clone () по адресу ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
Поток 1 (LWP 8835):
# 0 __lll_lock_wait_private () в ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
# 1 0x00007ffff6ca0ad9 в malloc_atfork (sz = 140737337120848, caller =) на arena.c: 179
# 2 0x00007ffff6c8d875 в __GI__IO_file_doallocate (fp = 0x17a72230) в filedoalloc.c: 127
# 3 0x00007ffff6c9a964 в __GI__IO_doallocbuf (fp = fp @ entry = 0x17a72230) на genops.c: 398
# 4 0x00007ffff6c99de8 в _IO_new_file_overflow (f = 0x17a72230, ch = -1) в fileops.c: 820
# 5 0x00007ffff6c98f8a в _IO_new_file_xsputn (f = 0x17a72230, data = 0x17a16420, n = 682) на fileops.c: 1331
# 6 0x00007ffff6c6fcb2 в _IO_vfprintf_internal (s = 0x17a72230, format =, ap = ap @ entry = 0x7fffffffcf18) по адресу vfprintf.c: 1632
# 7 0x00007ffff6c76a97 в __fprintf (stream =, format =) в fprintf.c: 32
#8-11 ...
# 12 0x000000000042706e в main (argc = 3, argv = 0x7fffffffd698, envp = 0x7fffffffd6b8) в mains / ignore / .c: 146
Оба остаются здесь навсегда с glibc-2.17 и glibc-2.23
Приветствуется любая помощь: 'D
РЕДАКТИРОВАТЬ :
Вот минимальный пример:
1 #include <stdlib.h>
2 #include <pthread.h>
3 #include <unistd.h>
4
5 void * thread_handler(void * args)
6 {
7 char * argv[] = { "/usr/bin/ls" };
8 char * newargv[] = { "/usr/bin/ls", NULL };
9 char * newenviron[] = { NULL };
10 while (1) {
11 if (vfork() == 0) {
12 execve(argv[0], newargv, newenviron);
13 }
14 }
15
16 return 0;
17 }
18
19 int main(void)
20 {
21 pthread_t thread;
22 pthread_create(&thread, NULL, thread_handler, NULL);
23
24 int * dummy_alloc;
25
26 while (1) {
27 dummy_alloc = malloc(sizeof(int));
28 free(dummy_alloc);
29 }
30
31 return 0;
32 }
Среда: пользователь: тупик $ cat / etc / redhat-release
Версия 7.3 Scientific Linux (Азот)
пользователь: deadlock $ ldd --version
ldd (GNU libc) 2.17
РЕДАКТИРОВАТЬ 2: версия пакета rpm: glibc-2.17-196.el7.x86_64
Я не могу получить номера строк с помощью пакета rpm. Вот BT, использующий glibc из дистрибутива: решено с помощью debuginfo.
(gdb) поток применить все bt
Тема 2 (Тема 0x7ffff77fb700 (LWP 59753)):
# 0 vfork () в ../sysdeps/unix/sysv/linux/x86_64/vfork.S:44
# 1 0x000000000040074e в thread_handler (args = 0x0) в deadlock.c: 11
# 2 0x00007ffff7bc6e25 в start_thread (arg = 0x7ffff77fb700) в pthread_create.c: 308
# 3 0x00007ffff78f434d в clone () в ../sysdeps/unix/sysv/linux/x86_64/clone.S:113
Тема 1 (Тема 0x7ffff7fba740 (LWP 59746)):
# 0 0x00007ffff7878226 в _int_free (av = 0x7ffff7bb8760, p = 0x602240, have_lock = 0) на malloc.c: 3927
# 1 0x00000000004007aa в main () в deadlock.c: 28
fork
, но в вашем примере используетсяvfork
, поэтому он не репрезентативен. Какая у вас среда? Интересно, на какой именно блокировке блокируется__libc_fork
(т.е. что находится в строке 125?). Всего две темы? Что-нибудь, использующее потоки C ++? Или звонитfflush (NULL)
? Мы, безусловно, исправили некоторые ошибки в этой области на протяжении многих лет. - person Florian Weimer   schedule 23.10.2017nptl/sysdeps
очистки, поэтому в нем нетsysdeps/nptl/fork.c
файла. Вам действительно нужно предоставить точную информацию о вашей среде, чтобы мы могли разобраться в обратной трассировке. - person Florian Weimer   schedule 23.10.2017fork()
как безопасное для асинхронных сигналов, что является гораздо более строгим, чем просто безопасное для многопоточности. Это не проблема POSIX. - person Andrew Henle   schedule 23.10.2017