我使用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 page为PR_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/