- clone() и malloc(), Вова, 14:59 , 11-Янв-12 (1)
так в чём проблема-то? Какие дедлоки? Все потоки крутятся, ничего не залочено.
- clone() и malloc(), nikolayshm, 16:09 , 11-Янв-12 (4)
> так в чём проблема-то? Какие дедлоки? Все потоки крутятся, ничего не залочено. Только что скомпилировал код на CentOS 4.4 / 5 / 5.6 Все версии выдали: *** glibc detected *** *** glibc detected *** ./a.out: double free or corruption (fasttop): 0x00002af4240008c0 *** В некоторых случаях появлялся deadlock и процессы просто висели в ожидании. gdb показал что ожидание внутри free.
- clone() и malloc(), me, 17:10 , 11-Янв-12 (7)
>> так в чём проблема-то? Какие дедлоки? Все потоки крутятся, ничего не залочено. > Только что скомпилировал код на CentOS 4.4 / 5 / 5.6 > Все версии выдали: > *** glibc detected *** *** glibc detected *** ./a.out: double free or > corruption (fasttop): 0x00002af4240008c0 *** ну это логично вполне, он-же CLONE_VM делает и никак это не лечит. > В некоторых случаях появлялся deadlock и процессы просто висели в ожидании. gdb > показал что ожидание внутри free. это больша на багу glibc похоже, хотя с таким кодом я не удивлён.
- clone() и malloc(), nikolayshm, 17:52 , 11-Янв-12 (8)
>>> так в чём проблема-то? Какие дедлоки? Все потоки крутятся, ничего не залочено. >> Только что скомпилировал код на CentOS 4.4 / 5 / 5.6 >> Все версии выдали: >> *** glibc detected *** *** glibc detected *** ./a.out: double free or >> corruption (fasttop): 0x00002af4240008c0 *** > ну это логично вполне, он-же CLONE_VM делает и никак это не лечит. С одной стороны это логично, и это тоже первое о чем я подумал. Но тот же pthread_create тоже использует CLONE_VM и проблем никаких. Да и malloc использует внутреннюю блокировку, что бы быть thread-safe, непонятно почему эта блокировка не спасает. Если обернуть внешний вызов malloc/free в mutex то проблема исчезает. >> В некоторых случаях появлялся deadlock и процессы просто висели в ожидании. gdb >> показал что ожидание внутри free. > это больша на багу glibc похоже, хотя с таким кодом я не > удивлён.
Про код опишите, пожалуйста, что именно в нем плохо? Специально синтетический тест на конкуренцию malloc/free.
- clone() и malloc(), me, 19:30 , 11-Янв-12 (9)
>>>> так в чём проблема-то? Какие дедлоки? Все потоки крутятся, ничего не залочено. >>> Только что скомпилировал код на CentOS 4.4 / 5 / 5.6 >>> Все версии выдали: >>> *** glibc detected *** *** glibc detected *** ./a.out: double free or >>> corruption (fasttop): 0x00002af4240008c0 *** >> ну это логично вполне, он-же CLONE_VM делает и никак это не лечит. > С одной стороны это логично, и это тоже первое о чем я > подумал. Но тот же pthread_create тоже использует CLONE_VM и проблем никаких. так вы-ж его не иначе с -pthread собираете? :) > Да и malloc использует внутреннюю блокировку, что бы быть thread-safe, без флага pthread? или с флагом но без pthread_create? серьезно? :) > непонятно почему > эта блокировка не спасает. > Если обернуть внешний вызов malloc/free в mutex то проблема исчезает. >>> В некоторых случаях появлялся deadlock и процессы просто висели в ожидании. gdb >>> показал что ожидание внутри free. >> это больша на багу glibc похоже, хотя с таким кодом я не >> удивлён. > Про код опишите, пожалуйста, что именно в нем плохо? Специально синтетический тест > на конкуренцию malloc/free. вы думаете он знает зачем его создали? :) ему вообщем плевать, он и malloc/malloc и free/free - поконкурирует на раз. И если там есть бага - легко поймает. Вы хотели багу рэйса - вы поймали багу рэйса (возможно, требует проверки все-же). Вы удивлены? Вас не Вова зовут?(шучу) :)
- clone() и malloc(), nikolayshm, 21:12 , 11-Янв-12 (10)
>[оверквотинг удален] >>>> Только что скомпилировал код на CentOS 4.4 / 5 / 5.6 >>>> Все версии выдали: >>>> *** glibc detected *** *** glibc detected *** ./a.out: double free or >>>> corruption (fasttop): 0x00002af4240008c0 *** >>> ну это логично вполне, он-же CLONE_VM делает и никак это не лечит. >> С одной стороны это логично, и это тоже первое о чем я >> подумал. Но тот же pthread_create тоже использует CLONE_VM и проблем никаких. > так вы-ж его не иначе с -pthread собираете? :) >> Да и malloc использует внутреннюю блокировку, что бы быть thread-safe, > без флага pthread? или с флагом но без pthread_create? серьезно? :) Я собирал и без -pthread и с ней. добавлял -D_REENTRANT - все без результатно. но... по вашему "намеку" попробовал добавить в код pthread_create(), который создает тред и сразу его закрывает. все заработало. Очевидно что pthread_create что то проинициализировал. Я смотрел его код, но инициализацией связанных с памятью или локами не нашел (кроме стека). Спасибо Вам за помощь. Если возможно, подскажите, что именно инициализирует pthread_create()? что бы не использовать его как "хак".
- clone() и malloc(), me, 23:11 , 11-Янв-12 (11)
>[оверквотинг удален] >>> подумал. Но тот же pthread_create тоже использует CLONE_VM и проблем никаких. >> так вы-ж его не иначе с -pthread собираете? :) >>> Да и malloc использует внутреннюю блокировку, что бы быть thread-safe, >> без флага pthread? или с флагом но без pthread_create? серьезно? :) > Я собирал и без -pthread и с ней. добавлял -D_REENTRANT - все > без результатно. > но... по вашему "намеку" попробовал добавить в код pthread_create(), который создает тред > и сразу его закрывает. все заработало. > Очевидно что pthread_create что то проинициализировал. Я смотрел его код, но инициализацией > связанных с памятью или локами не нашел (кроме стека).не, я имел ввиду pthread_create для создания потока вместо clone. Вы показали ваш собственный фокус. (весьма занятный, кстати. но я-бы не рассчитывал, что этот код будет работать всегда) > Спасибо Вам за помощь. незачто и судя по-тому, что вы хотели clone() "потому что при смерти треда (seg fault) завершается сразу все приложение." - вы еще не пробовали посылать sigsegv ни одному из ваших "работающих" клонов. SIGSEGV, кстати, маскируется и обрабатывается. > Если возможно, подскажите, что именно инициализирует pthread_create()? что бы не использовать > его как "хак". это "хак" и я-бы его не использовал.
- clone() и malloc(), nikolayshm, 00:29 , 12-Янв-12 (12)
> незачто и судя по-тому, что вы хотели clone() "потому что при смерти > треда (seg fault) завершается сразу все приложение." - вы еще не > пробовали посылать sigsegv ни одному из ваших "работающих" клонов. SIGSEGV, кстати, > маскируется и обрабатывается.Этот момент я хорошо тестировал. SIGSEGV вызывал разными способами. В случае с клонами (с указанными флагами) SIGSEGV ловится слоном, вызывается exit() и клон умирает. Родитель обрабатывает waitpid и продолжает работать. В случае с тредами (pthread_create или флаг CLONE_THREAD) SIGSEGV тоже ловится, но ловит его родитель и продолжать работать не может. Умирает родитель и умирают все поражденные треды.
- clone() и malloc(), pavlinux, 18:49 , 14-Янв-12 (13)
Блин, вы С учить будете? А то glibc, треды... придумали тоже... :)У Вас указатель *stack ВСЕ ВРЕМЯ указывает на один и тот же сегмент, над которым затем трахаются по 10 копий malloc и free!!! Да, на уровне ядра есть блокировки, собственно благодаря которым вы и получаете SIGSEGV, а не смерть всего компа. Ниже я показал, что надо юзать указатель на указатель (можно массив указателей)
- clone() и malloc(), nikolayshm, 20:04 , 14-Янв-12 (15)
> Блин, вы С учить будете? А то glibc, треды... придумали тоже... :) Буду рад, если Вы подскажите что почитать для получения новых знаний. > У Вас указатель *stack ВСЕ ВРЕМЯ указывает на один и тот же > сегмент, > над которым затем трахаются по 10 копий malloc и free!!! Мой код: for (i=0; i<10; i++) { void *stack = malloc(STACK_SIZE); } переменной stack присывается новое значение, так что *stack никак не может указывать на одинаковый сегмент памяти. > Ниже я показал, что надо юзать указатель на указатель (можно массив указателей)
Кусок Вашего кода: stack = malloc(STACK_SIZE); for (i = 0; i < 10; i++) { *stack = (void *)(STACK_SIZE + (char *)stack); clone(func, stack, FLAGS, NULL); Вы выделили память размером STACK_SIZE, затем в первый байт записали ссылку на конец выделенной памяти передали в clone ссылку на выделенную память. У доке четко написано: The child_stack argument specifies the location of the stack used by the child process. ... The calling process must therefore set up memory space for the child stack and pass a pointer to this space to clone(). В переводе это означает что передавать нужно ссылку на память, а не ссылку на ссылку на память. Даже, если предположить что нужно передавать последнее, то Ваш код все равно не работает так как во все 10 клонов он передаст один и тот же указатель. P.S. Ваш код я скомпилировал и запустил, как результат: kernel: a.out[28746]: segfault at 0000000000000000 rip 0000000000000000 rsp 00002b18a9b79008 error 14
- clone() и malloc(), pavlinux, 00:59 , 15-Янв-12 (16)
>[оверквотинг удален] > В переводе это означает что передавать нужно ссылку на память, > а не ссылку на ссылку на память.Чуток не правильно понимаешь свойства работы с указателем на указатель. Ну на, в твоем виде #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sched.h> #include <signal.h> #define STACK_SIZE (1024*1024) #define FLAGS (CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_SYSVSEM|SIGCHLD)
int func(void *p) { while (1) { p = (char *)malloc(6); memcpy(p, "12345\0", 6); free(p); } } int main() { int i; void **stack; for (i = 0; i < 10; i++) { stack = (void **)malloc(STACK_SIZE); clone(func, stack, FLAGS, NULL); } sleep(10); return 0; }
- clone() и malloc(), nikolayshm, 04:02 , 15-Янв-12 (18)
>>[оверквотинг удален] >> В переводе это означает что передавать нужно ссылку на память, >> а не ссылку на ссылку на память. > Чуток не правильно понимаешь свойства работы с указателем на указатель. > Ну на, в твоем виде С Вашего позволения, тоже перейду на "ты". Объясни, мне пожалуйста, что я неправильно понимаю. Можно ссылкой в ман, гугл или куда угодно. Что касается кода, правильно ли я понял фразу "Ну на, в твоем виде" - означает, что 2 кода которые ты привел они идентичны, только "вид" разный? Для наглядности: первый: void **stack; for (i = 0; i < 10; i++) { stack = (void **)malloc(STACK_SIZE); clone(func, stack, FLAGS, NULL); }
второй:
void **stack; stack = malloc(STACK_SIZE); for (i = 0; i < 10; i++) { *stack = (void *)(STACK_SIZE + (char *)stack); clone(func, stack, FLAGS, NULL); }
- clone() и malloc(), pavlinux, 14:50 , 15-Янв-12 (20)
>>>[оверквотинг удален] Короче не ..би моск
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;int func(void *ptr) { char *msg = (char *) ptr; while (1) { pthread_mutex_lock(&lock); msg = malloc( 6); strncpy(msg, "12345\0", 6); free(msg); pthread_mutex_unlock(&lock); } return 0; }
Кстати, размер стека лучше узнавать у getrlimit(RLIMIT_STACK, rlim) ...
- clone() и malloc(), pavlinux, 16:26 , 11-Янв-12 (5)
int func(void *p) { while (1) { p = (char *)malloc(6); memcpy(p, "12345\0", 6); free(p); } }#define STACK_SIZE (1024*1024) #define FLAGS (CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_SYSVSEM|SIGCHLD) int main() { int i; void **stack; stack = malloc(STACK_SIZE); for (i = 0; i < 10; i++) { *stack = (void *)(STACK_SIZE + (char *)stack); clone(func, stack, FLAGS, NULL); } sleep(10000); return 0; }
Криво, ибо пример такой. Давай реальную задачу.
- clone() и malloc(), svn, 03:19 , 15-Янв-12 (17)
> При этом когда они начиют конкурировать между собой, возникает deadlock в функциях > malloc()/free() Конечно возникает. Потому что память одного процесса неожиданно редактирует другой процесс. Если какой-то поток вызывает SIGSEGV - значит вся память испорчена. Общая, всего процесса!! Ничего хорошего в работе программы с испорченной памятью не может быть.
- clone() и malloc(), nikolayshm, 04:08 , 15-Янв-12 (19)
>> При этом когда они начиют конкурировать между собой, возникает deadlock в функциях >> malloc()/free() > Конечно возникает. Потому что память одного процесса неожиданно редактирует другой процесс. Так вопрос-то был соответствующий - почему так. malloc/free они ведь thread-safe :) > Если какой-то поток вызывает SIGSEGV - значит вся память испорчена. Общая, всего > процесса!! Кстати, это неправильное утверждение. SIGSEGV is the signal sent to a process when it makes an invalid memory reference, or segmentation fault.
|