Estou analisando o /proc/pid/cmdline
valor de vários processos em meu sistema Linux (Ubuntu 16.04) e descobri que, embora a maioria das entradas seja codificada com nulo, como esperado , pelo menos uma usa espaços para delimitadores que considero inesperados.
Na documentação do proc(5) , não vejo nenhuma indicação de que isso deveria estar acontecendo. Existem casos em que devo esperar espaços como delimitadores em vez de valores nulos? Em caso afirmativo, onde posso encontrar documentação que descreva o comportamento?
Comportamento
Isso é o que vejo quando tento cat o cmdline para um dos processos do navegador chromium (observe que o caractere de espaço é usado para delimitar os valores):
user@host:~$ cat /proc/2721/cmdline
/usr/lib/chromium-browser/chromium-browser --type=gpu-process --field-trial-handle=2073283832741738928,4790986738309707242,131072 --gpu-preferences=GAAAAAAAAAAAAQAAAQAAAAAAAAAAAGAA --gpu-vendor-id=0x15ad --gpu-device-id=0x0405 --gpu-driver-vendor=Mesa --gpu-driver-version=17.2.8 --gpu-driver-date --service-request-channel-token=3778166CAD6E96F44A7268DF1AB1DD53
Eu esperaria ver algo assim (valores nulos como delimitador), que é o que vejo de outros processos no sistema:
~$ cat /proc/354/cmdline
vmware-vmblock-fuse/run/vmblock-fuse-orw,subtype=vmware-vmblock,default_permissions,allow_other,dev,suid
Incorreta.
Se você olhar o final do pseudo-arquivo no FreeBSD/TrueOS, onde você pode encontrar exatamente o mesmo comportamento com o Chromium, você encontrará um arquivo
␀
. Este é terminado em ␀. É tudo um único argumento .O Chromium está substituindo seus argumentos após um
fork()
, para fornecer algo interessante para observar na saída deps
. Ele está usando asetproctitle()
função de biblioteca. Isso faz parte das bibliotecas BSD C. Não faz parte da biblioteca GNU C. Nas plataformas GNU C, o Chromium usa umsetproctitle()
próprio que sobrescreve osargv
dados diretamente.setproctitle()
não é de fato a ferramenta certa para este trabalho, porque não permite definir mais de uma string de argumento. Ele define o "título" formatado como o 0º argumento e define a contagem de argumentos como 1. Tudo é empacotado por meio da função de biblioteca como um único argumento.Este não é o único problema com
setproctitle()
. A versão da biblioteca FreeBSD/OpenBSD/NetBSD C também possui uma limitação arbitrária de 2KiB, herdada diretamente do antigosendmail
programa BSD (do qual a função da biblioteca foi originalmente levantada no caso do FreeBSD), que é muito curta para o que o Chromium geralmente define linhas de comando para. E tanto a versão do Chromium quanto a da biblioteca FreeBSD/OpenBSD/NetBSD C têm funcionalidade extra, da string de formato sendo um ponteiro nulo, que o Chromium não usa (mas, ironicamente, tem que lidar em sua própriasetproctitle()
implementação).Pode-se fazer muito melhor com menos código. A chamada do sistema subjacente no FreeBSD/TrueOS que a função da biblioteca chama para fazer o trabalho depois de ter construído os dados do argumento, é a
sysctl()
função, levandoCTL_KERN
,KERN_PROC
,KERN_PROC_ARGS
e um ID de processo como o endereço. Isso pode aceitar várias strings terminadas em ␀. Escrevi umasetprocargv()
função bastante simples para meus conjuntos de ferramentas que emprega isso.(OpenBSD/NetBSD faz as coisas da maneira antiga que o FreeBSD/TrueOS costumava fazer, com uma
ps_strings
estrutura na memória do aplicativo, mas aindasysctl()
é a chamada de sistema subjacente usada para encontrar a localização dessa estrutura.)Como
setproctitle()
é a ferramenta errada para o trabalho, o Chromium está pegando os novosargv
membros e construindo uma única string longa delimitada por ␠ deles , para ser passada como um único argumento parasetproctitle()
.Como você pode ver, o próprio Chromium já tem o novo vetor de argumento como uma série de strings terminadas em ␀. Ele está passando por uma camada de biblioteca intermediária que precisa de todos eles agrupados em uma string, onde o nível de chamada do sistema real, no entanto, opera em termos de um vetor de argumento de strings terminadas em ␀.
Daí o comportamento que você está testemunhando, onde o Chromium está apresentando seus vetores de argumento alterados para o sistema como um único argumento .
Talvez você possa persuadir os escritores do Chromium a adotar algo como
setprocargv()
. ☺Leitura adicional
setproctitle
. Manual de Funções da Biblioteca FreeBSD . FreeBSD.