我使用prctl()在c中更改pthreads线程名:

  // Set our thread name to assist with debugging a running process
  char *threadName = calloc(16, sizeof(char));
  sprintf(threadName, "My Own Thread");
  prctl(PR_SET_NAME, threadName);

我的问题是,我是否应该在接到char *threadName电话后立即释放prctl()
prcrl()是否获得字符串参数的安全副本,允许我随时释放所提供的变量?
使用valgrind进行的内存测试在我空闲时没有突出显示任何问题。我担心的是很难跟踪并发/内存问题。
编辑:我不认为建议的问题Can calloc ever safely be used without free?回答了这里关于系统/内核功能的具体问题,特别是prctl()要求调用方不释放提供的内存。

最佳答案

我找不到任何文档,明确地表明将一个字符串传递给prctl( PR_SET_NAME, name )是安全的(它可能在某个地方很好地存在)。
对手册页、glibc源代码和linux内核源代码的检查表明,在调用prctl()之后释放内存是安全的。
Linux prctl() man pagePR_SET_NAME声明:
pr_set_name(从Linux 2.6.9开始)
使用
(char *) arg2指向的位置。名字可以是
16字节长,包括终止的空字节。(如果
字符串的长度,包括终止的空字节,
超过16字节,字符串将被自动截断。)这是
可通过pthread_setname_np(3)设置的相同属性
并使用pthread_getname_np(3)检索。属性是
同样可通过/proc/self/task/[tid]/comm访问,其中tid
是调用线程的名称。
这里的关键是语句“属性同样可以通过/proc/self/task/[tid]/comm”访问。这意味着必须将提供的字符串复制到内核空间。“在( char * ) arg2所指的位置使用值”这句话显然看起来很混乱,也不清楚,让传递给prctl()的字符串有可能被直接使用。但是要“通过/proc/...访问”,需要在内核空间中创建一个副本。
glibc source有点难理解。我无法确定在进程调用prctl()时执行的实际代码,但我发现的是直接将指针传递到内核的系统调用。
Linux kernel source is pretty clear。当字符串从用户空间复制到内核空间时:

case PR_SET_NAME:
    comm[sizeof(me->comm) - 1] = 0;
    if (strncpy_from_user(comm, (char __user *)arg2,
                  sizeof(me->comm) - 1) < 0)
        return -EFAULT;
    set_task_comm(me, comm);
    proc_comm_connector(me);
    break;

一个确定的测试是调用prctl()来设置名称,然后修改传递给prctl()的字符串。如果线程的名称没有更改,则必须复制。

关于c - 您是否应该释放传递给prctl()的内存?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56837861/

10-15 15:01