c - 你应该释放传递给 prctl() 的内存吗?

标签 c linux

我正在使用 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);

我的问题是我是否应该在 prctl() 调用之后立即释放 char *threadName

prcrl() 是否获取字符串参数的安全副本,允许我随时释放所提供的变量?

使用 valgrind 进行的内存测试在我执行 free 时没有突出显示任何问题。我担心会导致难以追踪的并发/内存问题。

编辑:我不相信建议的问题 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 (since Linux 2.6.9)

Set the name of the calling thread, using the value in the location pointed to by (char *) arg2. The name can be up to 16 bytes long, including the terminating null byte. (If the length of the string, including the terminating null byte, exceeds 16 bytes, the string is silently truncated.) This is the same attribute that can be set via pthread_setname_np(3) and retrieved using pthread_getname_np(3). The attribute is likewise accessible via /proc/self/task/[tid]/comm, where tid is the name of the calling thread.

这里的关键是声明“该属性同样可以通过 /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/

相关文章:

c - 在 C 中构造 tm 转换的纪元时间

c++ - 从 64x64 位乘法中获得前 64 位的合理便携方式?

在C中将int转换为ASCII字符

c# - 如何在 Linux 中使用 Mono P/Invoke getaddrinfo

C++:平台相关类型 - 最佳模式

python - 如何编写一个用 python 调用自身的 bash 脚本?

c - 忽略 while 循环中的第二次运行,C

c - dlclose 被隐式调用

linux - 从 header 计算 linux 核心文件大小

linux - 在 Linux : writing into a FIFO