linux 上 pthread_create 之外创建 linux 线程的方法
Ways to create linux threads besides of pthread_create on linux
我拦截了 pthread_create
调用以捕获所有线程之间的关系。但是我发现有些线程的创建只用拦截pthread_create
并没有被记录下来。我还试图拦截 posix_spawn
posix_spawnp
和 clone
调用。但是在我的实验中仍然有一些我不知道是谁创建的线程运行。那么还有其他方法可以在 linux 上创建线程吗?
更具体地说,
我用LD_PRELOAD拦截了pthread_create
调用,代码片段如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg){
static void *handle = NULL;
static P_CREATE old_create=NULL;
if( !handle )
{
handle = dlopen("libpthread.so.0", RTLD_LAZY);
old_create = (P_CREATE)dlsym(handle, "pthread_create");
}
pthread_t tmp=pthread_self();
//print pthread_t pid
int result=old_create(thread,attr,start_routine,(void *)temp);
//print thread pid
return result;
}
就这样,我捕获了所有的线程创建过程。 clone
也是如此。但实际上 clone
并没有被应用程序调用。有时,我得到一个父子线程对,之前没有打印父线程。所以不知道有没有其他方法可以创建这个父线程
更具体地说,上层应用是JVM1.7上的Mapreduce作业。我想观察所有线程和进程及其关系
谢谢。
(从评论中移出)
LD_PRELOAD
技巧只是让您拦截对外部库的 C 调用 - 在这种特殊情况下为 lptrhead
(对于 pthread_create
)和 libc
(对于 fork
/clone
);但是要创建线程,程序可以完全绕过它们并直接与内核对话,方法是使用 int 80h
(在 x86 上)或 sysenter
(在 amd64 上)调用此类系统调用(特别是 clone
) .
直接的系统调用不能那么容易被拦截,你通常需要内核本身的帮助——这通常是通过 ptrace
接口发生的——顺便说一下,这就是 strace
和调试器之类的东西的实现方式.您应该特别查看 PTRACE_O_TRACECLONE
、PTRACE_O_TRACEVFORK
和 PTRACE_O_TRACEFORK
选项以跟踪新 processes/threads 的创建,或直接 PTRACE_SYSCALL
以阻止所有系统调用。
ptrace
的设置有点费力,我现在没有太多时间,但是网上有几个基本pthread循环的例子,你一定可以find/adapt 到你的 objective.
我拦截了 pthread_create
调用以捕获所有线程之间的关系。但是我发现有些线程的创建只用拦截pthread_create
并没有被记录下来。我还试图拦截 posix_spawn
posix_spawnp
和 clone
调用。但是在我的实验中仍然有一些我不知道是谁创建的线程运行。那么还有其他方法可以在 linux 上创建线程吗?
更具体地说,
我用LD_PRELOAD拦截了pthread_create
调用,代码片段如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg){
static void *handle = NULL;
static P_CREATE old_create=NULL;
if( !handle )
{
handle = dlopen("libpthread.so.0", RTLD_LAZY);
old_create = (P_CREATE)dlsym(handle, "pthread_create");
}
pthread_t tmp=pthread_self();
//print pthread_t pid
int result=old_create(thread,attr,start_routine,(void *)temp);
//print thread pid
return result;
}
就这样,我捕获了所有的线程创建过程。 clone
也是如此。但实际上 clone
并没有被应用程序调用。有时,我得到一个父子线程对,之前没有打印父线程。所以不知道有没有其他方法可以创建这个父线程
更具体地说,上层应用是JVM1.7上的Mapreduce作业。我想观察所有线程和进程及其关系
谢谢。
(从评论中移出)
LD_PRELOAD
技巧只是让您拦截对外部库的 C 调用 - 在这种特殊情况下为 lptrhead
(对于 pthread_create
)和 libc
(对于 fork
/clone
);但是要创建线程,程序可以完全绕过它们并直接与内核对话,方法是使用 int 80h
(在 x86 上)或 sysenter
(在 amd64 上)调用此类系统调用(特别是 clone
) .
直接的系统调用不能那么容易被拦截,你通常需要内核本身的帮助——这通常是通过 ptrace
接口发生的——顺便说一下,这就是 strace
和调试器之类的东西的实现方式.您应该特别查看 PTRACE_O_TRACECLONE
、PTRACE_O_TRACEVFORK
和 PTRACE_O_TRACEFORK
选项以跟踪新 processes/threads 的创建,或直接 PTRACE_SYSCALL
以阻止所有系统调用。
ptrace
的设置有点费力,我现在没有太多时间,但是网上有几个基本pthread循环的例子,你一定可以find/adapt 到你的 objective.