Я не могу найти никакой документации, явно заявляющей, что безопасно освобождать строку, переданную в prctl( PR_SET_NAME, name )
(она может где-то вполне существовать).
Изучение man-страницы, источника glibc и источника ядра Linux показывает, что можно безопасно освободить память после вызова prctl()
.
Страница man Linux prctl()
утверждает это для 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 немного сложен для понимания. Я не смог окончательно найти реальный код, который выполняется, когда ваш процесс вызывает prctl()
, но я обнаружил, что это системные вызовы, которые напрямую передают указатель ядру.
Исходный код ядра Linux довольно ясен . поскольку строка копируется из пространства пользователя в пространство ядра:
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()
. Если имя потока не изменяется, значит, копия была сделана.