2017-06-06 12 views
0

にマルチスレッドの下で、ユーザ・スタックの最下部を取得するにはどのように私は、64ビットLinux上でユーザスタック情報を取得したいと思います。 私は、ユーザースタックの最初のスタックポインタの場所を示すmm-> start_stackを知っています。のLinux

しかし、pthreadなどのマルチスレッドアプリケーションでは、同じ構造体task_structを使用しているため、mm-> start_stackはすべてのスレッドで同じ値になります。

そして、私はmm-> mmap-> vm_startとmm-> mmap-> vm_endを使ってメモリレイアウトを知っていますが、これらのmmap領域がスタックかどうかは分かりません。

私はPMAPのプロセスIDとstraceのこれらの下でメモリレイアウトを確認しました。

mm-> start_stackのようにすべてのスレッドをユーザースタック位置に取得する方法を教えてください。

sudo pmap 24074 
24074: ./a.out 
0000000000400000  4K r-x-- a.out 
0000000000600000  4K r---- a.out 
0000000000601000  4K rw--- a.out 
0000000000602000 132K rw--- [ anon ] 
00007ffff5fee000  4K ----- [ anon ] 
00007ffff5fef000 8192K rw--- [ anon ] <==== Thread Stack 
00007ffff67ef000  4K ----- [ anon ] 
00007ffff67f0000 8192K rw--- [ anon ] <==== Thread Stack 
00007ffff6ff0000  4K ----- [ anon ] 
00007ffff6ff1000 8192K rw--- [ anon ] <==== Thread Stack 
00007ffff77f1000 1792K r-x-- libc-2.23.so 
00007ffff79b1000 2044K ----- libc-2.23.so 
00007ffff7bb0000  16K r---- libc-2.23.so 
00007ffff7bb4000  8K rw--- libc-2.23.so 
00007ffff7bb6000  16K rw--- [ anon ] 
00007ffff7bba000  96K r-x-- libpthread-2.23.so 
00007ffff7bd2000 2044K ----- libpthread-2.23.so 
00007ffff7dd1000  4K r---- libpthread-2.23.so 
00007ffff7dd2000  4K rw--- libpthread-2.23.so 
00007ffff7dd3000  16K rw--- [ anon ] 
00007ffff7dd7000 152K r-x-- ld-2.23.so 
00007ffff7fda000  12K rw--- [ anon ] 
00007ffff7ff6000  8K rw--- [ anon ] 
00007ffff7ff8000  8K r---- [ anon ] 
00007ffff7ffa000  8K r-x-- [ anon ] 
00007ffff7ffc000  4K r---- ld-2.23.so 
00007ffff7ffd000  4K rw--- ld-2.23.so 
00007ffff7ffe000  4K rw--- [ anon ] 
00007ffffffde000 132K rw--- [ stack ] 
ffffffffff600000  4K r-x-- [ anon ] 
total   31108K 

straceのは、あなたの質問は完全に明確に定義されていません

clone(child_stack=0x7ffff77efff0,flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7ffff77f09d0, tls=0x7ffff77f0700, child_tidptr=0x7ffff77f09d0) = 24075 

clone(pid: 24074 child_stack=0x7ffff6feeff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7ffff6fef9d0, tls=0x7ffff6fef700, child_tidptr=0x7ffff6fef9d0) = 24076 

clone(child_stack=0x7ffff67edff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7ffff67ee9d0, tls=0x7ffff67ee700, child_tidptr=0x7ffff67ee9d0) = 24077 
+1

'mm-> start_stackは同じ構造体task_structを使用しているため、すべてのスレッドで同じ値です。 ' - 部分的に間違っています:Linuxではすべてのスレッドが**独自の**' task_struct'を使用します。しかし、おそらく 'mm'は同じプロセスのスレッド間で共有されます。 – Tsyvarev

+0

ありがとうございます。あなたは絶対に正しいです... – ouiouiouioui

答えて

0

結果。技術的には、ユーザーがpthreadを使用してスレッドを作成し、別のものに新しいスレッドspを切り換えることができます。したがって、pthread_createによって作成されたスタックは、必ずしもプロセスによって使用されるスタックであるとは限りません。地獄、プロセスはさらにmunmapそれは...

ただし、次のように、特定の瞬間(例えばシステムコール)で、ユーザーのスタックにアクセスすることができます可能性があります

task_pt_regs(task)->sp 

をしかし、にしてくださいそれがユーザー空間に常にあるとは限りませんので、検証してください。ユーザーはそれを完全に制御できます。

0

ほとんどのシステムは、実行中のスレッドからpthread_attr_t構造体を初期化するためにpthread_getattr_np(Linux)またはpthread_attr_get_np(NetBSD)または同様の手段を提供します。あなたがそれをやったら

、あなたは、例えば使用することができます最下位アドレスとサイズを取得するためのpthread_attr_getstackaddrpthread_attr_getstacksize。スタックの「底」は、スタックの成長の方向に応じて、前者または両方の合計です。

警告の小さな注意:多くのシステムがこの機能を提供していますが、プログラムの初期/メインスレッドで動作する場合と動作しない場合があります。あなたはこれを既に扱っているLinux特有の方法を見つけました。