带有 clone() 和 printf 的段错误 [英] segfault with clone() and printf

查看:40
本文介绍了带有 clone() 和 printf 的段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对Linux 3.10.0-327.3.1.el7.x86_64中的线程实现 clone()的方式进行实验

我正在运行这段代码,并偶尔出现段错误.我知道如果使用 CLONE_THREAD ,那么无法检查线程是否完成,但是为什么 printf 会引起问题? Pthread 库如何处理此问题?没有 printf ,就不会有段错误.

  #define STACK_SIZE(1ULL<< 22)//4MBint tmp = 10;int threadfunc(无效* ptr){printf(我在这里\ n");tmp ++;返回0;}int main(){char * child_stack = malloc(STACK_SIZE);int child_pid = clone(& threadfunc,child_stack +(STACK_SIZE)-1,CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD,NULL);printf("my pid:%d \ n",getpid());printf("child pid:%d \ n",child_pid);printf("tmp is:%d \ n",val);返回0;} 

解决方案

printf 函数无法理解它是否在 clone 中被调用任务;它是围绕glibc pthread库设计的.

您正在做的事情类似于用异步信号中断 printf ,然后从信号中重新输入 printf .

库如何处理此问题的原因是,它使用 clone 作为更复杂的线程实现的一部分,该实现​​以线程身份修饰"克隆的任务.此线程标识允许 printf 将流操作周围的互斥锁锁定.

什么是线程标识?这意味着C库中与线程相关的函数可以某种方式查询什么线程在叫我?".获取ID,该ID映射到线程描述符结构.单独的 clone 函数不会设置此身份.

I'm trying to experiment with how clone() is implemented for threads in Linux 3.10.0-327.3.1.el7.x86_64

I'm running this piece of code and having occasional segfaults. I know if I use CLONE_THREAD then there's no way to check if the thread finished, but why does printf cause problems? How does the Pthread library handle this issue? Without the printfs there's no segfault.

#define STACK_SIZE (1ULL<<22) //4MB

int tmp = 10;

int threadfunc(void *ptr)
{
    printf("i'm here\n");
    tmp++;
    return 0;
}

int main()
{
    char *child_stack = malloc(STACK_SIZE);
    int child_pid = clone(&threadfunc, child_stack+(STACK_SIZE)-1, CLONE_THREAD|CLONE_SIGHAND|CLONE_VM|CLONE_FS|CLONE_FILES|SIGCHLD, NULL);

    printf("my pid: %d\n", getpid());
    printf("child pid: %d\n", child_pid);
    printf("tmp is: %d\n", val);

    return 0;
}

解决方案

The printf function doesn't understand that it's being called in a clone task; it is designed around the glibc pthread library.

What you're doing is similar to interrupting a printf with an asynchronous signal, and re-entering printf from the signal.

How the library handles the issue is that it uses clone as part of a more complicated implementation of threads, which "dresses up" the cloned task with a thread identity. This thread identity allows printf to lock a mutex around the stream operation.

What is the thread identity? What it means is that a thread-related function in the C library can inquire, in some way, "what thread is calling me?" to obtain an ID, which maps to a thread descriptor structure. The clone function alone won't set up this identity.

这篇关于带有 clone() 和 printf 的段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆