除了 pthread_create 在 linux 上创建 linux 线程的方法

Posted

技术标签:

【中文标题】除了 pthread_create 在 linux 上创建 linux 线程的方法【英文标题】:Ways to create linux threads besides of pthread_create on linux 【发布时间】:2018-03-10 23:46:26 【问题描述】:

我拦截了pthread_create 调用来捕获所有线程之间的关系。但是我发现有些线程的创建没有记录,只拦截pthread_create。我还试图拦截posix_spawnposix_spawnpclone的通话。但是在我的实验中仍然有一些我不知道是谁创建它们的线程。那么还有没有其他方法可以在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 作业。我想观察所有线程和进程及其关系

谢谢。

【问题讨论】:

您是否正在考虑内部内核线程?因为否则 all 用户空间线程(和进程)的创建通过 Linux 中的 clone 调用。 @Chalex:通过显示一些MCVE 创建一个你不理解的线程,给出一个你声称的具体例子。我没有观察到这一点(例如,甚至here 线程也是由pthread_create 创建的)。所以编辑你的问题来改进它并激发它(即为什么你关心这些奇怪的线程?)。还要为您定义什么是线程,以及如何观察它(对我来说,线程是由pthread_create 创建的定义;调度程序关心任务,包括内核线程、进程...... .) @Someprogrammerdude:即使在今天,您也可以使用真正的forkvfork 系统调用来创建进程。如果libc 为它们使用clone(2) 系统调用,则其他一些代码(例如汇编代码,或与旧libc 静态链接的二进制文件)可以直接使用forkvfork 而无需clone @BasileStarynkevitch 好的,我告诉你,人们总是可以直接调用老式的系统调用,但是理智的人会这样做吗? :) 任何运行足够老的 Linux 可执行二进制文件的人都会使用fork 系统调用;例如我 15 年前编译并保持完整的一些 ELF 静态链接可执行文件 【参考方案1】:

(从评论移开)

LD_PRELOAD 技巧只是让您拦截对外部库的 C 调用 - 在这种特殊情况下,对 lptrhead(对于 pthread_create)和对 libc(对于 fork/clone)的调用;但是要创建线程,程序可以完全绕过它们并直接与内核对话,方法是使用 int 80h(在 x86 上)或 sysenter(在 amd64 上)调用此类系统调用(特别是 clone)。

直接的系统调用不容易被拦截,您通常需要内核本身的帮助 - 这通常通过 ptrace 接口发生 - 顺便说一下,strace 和调试器之类的东西是如何实现的。您应该特别查看PTRACE_O_TRACECLONEPTRACE_O_TRACEVFORKPTRACE_O_TRACEFORK 选项来跟踪新进程/线程的创建,或者直接查看PTRACE_SYSCALL 以阻止所有系统调用。

ptrace 的设置有点费力,我现在没有太多时间,但是 Internet 上有几个基本 pthread 循环的示例,您一定能够找到/适应您的目标.

【讨论】:

以上是关于除了 pthread_create 在 linux 上创建 linux 线程的方法的主要内容,如果未能解决你的问题,请参考以下文章

linux创建线程之pthread_create

[Linux] Linux下undefined reference to ‘pthread_create’问题解决

Linux进程创建过程详解

linux 内核 2.4.20 和 2.4.36 中的 pthread_create 差异

linux创建线程之pthread_create

Linux 中对 pthread_create 的未定义引用