2011-06-25 12 views
3

CLONE_VMでclone()を呼び出して2つのプロセッサ間でglibc/syscallsを複数回呼び出すと、プログラムがクラッシュすることがあります。LinuxでCLONE_SETTLSを使う方法

CLONE_VMを使うつもりなら、CLONE_SETTLSも指定する必要があります。

私の新しいクローンのTLSストレージの準備方法と、実際にCLONE_SETTLSを使用してclone()コールを実行する方法を教えてもらえますか?

+0

'CLONE_VM'は' CLONE_SETTLS'を必要としません。 'vfork()'は 'CLONE_SETTLS'なしで' CLONE_VM'を使います。 – ninjalj

+1

vforkは、データを変更しない他のプロセスに依存し、理論的には直ちにexecを呼び出す必要があります。 - この場合、両方のプロセスはデータを変更し、glibc/syscallsを作成します。彼らはTLSが正しく動作することを必要とするいくつかのコールを同時に行うまで、すべてはうまく動作します。 – Jufe

答えて

1

私はこの「コンパイル中」(ここではwooden swordsはありません)だけを見てきたので、塩の粒で次のことを実行してください。

Glibc/NPTLは、多くのスレッド状態を格納するためにTLSを使用します。 TLSはスレッド単位でstruct pthread pdpdを意味する可能性があり、を意味するpthread記述子)は、__pthread_create_2_1()から呼び出されるallocate_stack()のスレッドローカルスタックに割り当てられます。 x86ので

struct pthreadの最初のメンバーは、struct user_descを指すべき、void *tcbある(そのエントリの数は、おそらく私のシステム上のglibcは、その内部TLSのための6を使用して、アーキテクチャ間、およびおそらくカーネルバージョン間で変化します)。このtcbは、引数としてdo_clone()に渡されます。

これらの関数を見ると、glibcにはTLSに関する多くの情報が格納されていることがわかります。スレッドローカルスタックに関する情報、このプログラムに複数のスレッドがあるかどうか、堅牢なmutexesリスト、スレッド開始ルーチン、 、pthread属性フラグ、スケジューリング方針、...

要約すると、実際のスレッドで取り除くことができれば、ずっと簡単になります。

0

cloneを最初に呼び出してからpthread_createを呼び出す方法もあります。 この方法では、スレッドライブラリを使用して正しいTLS(スレッドのスタック上にあります)を取得しています。

例コード:pthread_create

int tmp_run(void *arg) { 
    void *ret; 
    pthread_t thread; 
    // now call the wanted function 
    pthread_create(&thread, NULL, run, arg); 
    pthread_join(thread, &ret); 
    return (long) ret; 
} 

int main(...) { 
    ... 
    int clone_pid = clone (tmp_run, stack, flags arg); 
    ... 
} 

ルックスレッドをより細かく制御属性場合(スタック位置など)が必要です。

関連する問題