2010-07-23 1 views
0

Я хочу использовать клон для регистрации текущего состояния моей программы. В нем много циклов, и я хочу отслеживать процесс без печати состояния в каждой итерации цикла.using clone(): segmentation fault

Вот почему я создал это доказательство правильности концепции:

#include <iostream> 
#include <cstdlib> 

unsigned int i; 

int log(void*) { 
    std::cout << "LOGGING START" << std::endl; 
    while(true) { 
    sleep(1); 
    std::cout << i << std::endl; 
    } 
} 

int main() { 
    void **child_stack = (void**)malloc(16384); 
    i = 0; 

    std::clog << "calling clone" << std::endl; 
    clone(log, child_stack, CLONE_VM | CLONE_FILES, NULL); 
    std::clog << "done" << std::endl; 

    while(true) { 
    ++i; 
    } 

    return 0; 
} 

Когда я запускаю его без GDB он падает с ошибкой сегментации на клоне(), но он отлично работает, если я использую GDB. Зачем?

Считаете ли вы, что это хорошая практика или я рано или поздно столкнулся с трудностями? И есть ли лучший способ достичь этого?

Приветствия,

Manuel

ответ

1

стек аргумент clone простой void*. Кроме того, стек растет на большинстве архитектур, поэтому указатель стека должен указывать на конец выделенной памяти.

В любом случае, вы не должны использовать clone напрямую, если вам не нужно избегать любых зависимостей от внешних библиотек. Вместо этого используйте библиотеку pthreads. Он обеспечивает гораздо более простой (и безопасный) API.

+0

pthreads также более портативен; 'clone' является специфичным для Linux. –

+0

Хорошо, но тогда мне нужно было бы создать мьютекс и заблокировать его в начале итерации цикла for и разблокировать его в конце? Если это так, я думаю, что это повредит производительности. – Manuel

+0

Я попытался использовать это, но performace действительно сильно пробивает. Есть ли другое решение? – Manuel

0

На процессорах Intel аргумент child_stack должен указывать на вершину стека, а не на дно.

В любом случае, я думаю, что использование clone - это не очень хорошая идея. Существует три способа вызова clone, в зависимости от архивирования, все плохо документированы. Я бы предложил использовать библиотеку pthreads (или, поскольку мы находимся на C++, Boost.Threads).