Что делать с ошибочными POSIX API, которые пропускают память? - PullRequest
2 голосов
/ 24 января 2011

Отказ от ответственности: это для назначения, но назначение не требует, чтобы мы убрали утечки памяти. Я просто сохраняю анал.

Рассмотрим следующий метод:

//Prints the current user ID to the console.
void PrintUserId()
{
        std::cout << "Current User Id: " << cuserid(0) << std::endl;
}

Документы для cuserid состояния:

Если строка не является нулевым указателем, это должен быть массив, который может содержать как минимум символы L_cuserid; строка возвращается в этом массиве. В противном случае возвращается указатель на строку в статической области.

Но, по крайней мере, в моей системе рассматриваемая память не выделяется статически (или, по крайней мере, есть ошибки ...):

(Valgrind Output)
==4488== 160 (40 direct, 120 indirect) bytes in 1 blocks are definitely lost in loss record 11 of 11
==4488==    at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==4488==    by 0x4247A9C: nss_parse_service_list (nsswitch.c:622)
==4488==    by 0x4248216: __nss_database_lookup (nsswitch.c:164)
==4488==    by 0x402DEAB: ???
==4488==    by 0x402EB6C: ???
==4488==    by 0x41FE41C: getpwuid_r@@GLIBC_2.1.2 (getXXbyYY_r.c:253)
==4488==    by 0x41A2785: cuserid (cuserid.c:38)
==4488==    by 0x80495A3: PrintUserId() (in /home/bro4/Assignment1.bin)
==4488==    by 0x8049A11: ParentProcess() (in /home/bro4/Assignment1.bin)
==4488==    by 0x8049B53: main (in /home/bro4/Assignment1.bin)

Я просто застрял на этом?

Ответы [ 2 ]

3 голосов
/ 24 января 2011

Это может быть ложным срабатыванием.cuserid или его зависимости могут выделить буфер при первом вызове, а затем освободить или повторно использовать его при следующем вызове.Попробуйте вызвать это в цикле;Вы получаете несколько отчетов об утечках?

В вашем случае выделение выполняется nss_parse_service_list , частью внутреннего API nsswitch, который обрабатывает переключение между различными провайдерами аутентификации (unix / etc /passwd, LDAP и т. д.).Эта функция вызывается __ nss_database_lookup , которая вызывает ее как часть однократного процесса инициализации.Так что это на самом деле не утечка;это память, выделенная для хранения результатов анализа файла конфигурации (или, в данном случае, конфигурации по умолчанию).Это не будет освобождено, потому что это необходимо, пока программа не завершится;но он также не будет расти.

Поскольку это ложноположительный результат, вы можете подавить эти сообщения в valgrind.Нередко можно видеть предупреждения valgrind из системных библиотек - в разных библиотечных подпрограммах есть разовые распределения, подобные этим, а также низкоуровневые подпрограммы, выполняющие вещи, которые выглядят для valgrind как потенциальная проблема, хотя на самом деле они очень осторожныконтролируемый и правильный.Лучше всего их подавить - конечно же, после проверки того, что они на самом деле не ваша вина!

1 голос
/ 24 января 2011

Спецификация Single UNIX ®, версия 2 не гарантирует, что статические данные будут использоваться, а говорит, что они "могут быть статическими".

Если s нулевой указатель, это представление генерируется в области это может быть статичным (и, таким образом, перезаписывается последующими вызовами cuserid ()), адрес которого вернулся.

Справочная страница linux для cuserid () содержит два провокационных утверждения:

Функция cuserid была включена в версию POSIX 1988 года, но удалена из версии 1990 года.

и

Никто точно не знает, что делает cuserid () - избегайте этого в portable программы - вообще избегать - использовать вместо этого getpwuid (geteuid ()), если это это то, что ты означало. НЕ ИСПОЛЬЗУЙТЕ cuserid ().

Предполагая, что утверждение о том, что эта функция была удалена из POSIX более 20 лет назад, является верным, я бы сказал, что "НЕ ИСПОЛЬЗУЙТЕ cuserid ()" - очень хороший совет. В противном случае передайте указатель на cuserid и управляйте памятью самостоятельно.

...