행동

행동

/proc/pid/cmdlineLinux 시스템(Ubuntu 16.04)에서 여러 프로세스의 값을 구문 분석하고 있는데 대부분의 항목이 null로 인코딩되어 있는 것을 발견했습니다.예상대로, 적어도 하나는 공백을 구분 기호로 사용하는데, 이는 예상하지 못했습니다.

~에서proc(5)에 대한 문서나는 이것이 일어나야 한다는 어떤 징후도 보지 못했습니다. 어떤 경우에는 공백이 null 대신 구분 기호로 사용되어야 합니까? 그렇다면 이 동작을 설명하는 문서는 어디에서 찾을 수 있습니까?


행동

이것은 Chrome 브라우저 프로세스 중 하나에 대한 cmdline을 캡처하려고 할 때 표시되는 내용입니다(공백 문자는 값을 구분하는 데 사용됩니다).

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

나는 이와 같은 것을 보고 싶습니다(구분 기호로 null 값). 이것이 내가 가진 것입니다.하다시스템의 다른 프로세스에서 보기:

 ~$ cat /proc/354/cmdline
vmware-vmblock-fuse/run/vmblock-fuse-orw,subtype=vmware-vmblock,default_permissions,allow_other,dev,suid

답변1

적어도 하나는 공백을 구분 기호로 사용합니다.

잘못된.

FreeBSD/TrueOS에서 의사 파일의 끝을 보면 Chromium과 정확히 동일한 동작이 나타날 수 있습니다 .␀-종료. 이것은모두 논쟁이다.

Chromium은 a 이후의 매개변수를 재정의 fork()하므로 의 출력에서 ​​흥미로운 내용을 볼 수 있습니다 ps. setproctitle()라이브러리 기능을 사용하고 있습니다 . 이것은 BSD C 라이브러리의 일부입니다. GNU C 라이브러리의 일부가 아닙니다. GNU C 플랫폼에서 Chromium은 다음을 사용합니다.자신 setproctitle()데이터를 직접 덮어씁니다 argv.

setproctitle()실제로 이 도구는 여러 매개변수 문자열 설정을 허용하지 않으므로 해당 작업에 적합한 도구가 아닙니다. 형식화된 "제목"을 0번째 인수로 설정하고 인수 개수를 1로 설정합니다. 모든 것은 라이브러리 기능을 통해 매개변수로 구성됩니다.

이것이 유일한 문제는 아닙니다 setproctitle(). FreeBSD/OpenBSD/NetBSD C 라이브러리 버전에는 이전 BSD 프로그램에서 직접 상속된 임의의 2KiB 제한도 있습니다 sendmail(FreeBSD의 경우 라이브러리 함수는 원래 해당 프로그램에서 추출되었습니다). 이는 Chromium의 명령줄에서 매우 일반적입니다. 도착하다. Chromium 자체 버전과 FreeBSD/OpenBSD/NetBSD C 라이브러리 버전에는 모두 형식 문자열이 Chromium에서 사용하지 않는 널 포인터라는 추가 기능이 있습니다(그러나 아이러니하게도 setproctitle()여전히 자체 구현에서 이를 처리해야 합니다).

사람들은 더 적은 코드로 더 나은 결과를 얻을 수 있습니다. 이것낮은 수준의 시스템 호출FreeBSD/TrueOS에서 매개변수 데이터가 구성되면 라이브러리 함수는 이 함수를 호출하여 작업을 수행합니다. 이 함수 는 , 및 프로세스 ID sysctl()로 주소가 지정된 함수입니다. 이것CTL_KERNKERN_PROCKERN_PROC_ARGS할 수 있는␀로 끝나는 여러 문자열을 허용합니다. 나는 setprocargv()이것을 사용하기 위해 내 도구 세트에 대한 매우 간단한 함수를 작성했습니다.

외부
공백
proargv를 설정(
    size_t 인수,
    상수 문자 * argv[]
){
#if 정의됨(__FreeBSD__) ||정의됨(__DragonFly__)
    표준::문자열 s;
    for (size_t c(0); c < argc; ++c) {
        if (!argv[c]) 인터럽트;
        s += 인수[c];
        s += '\0';
    }
    const int oid[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, getpid() };
    sysctl(oid, oid 크기/sizeof *oid, 0, 0, s.data(), s.length());
#elif 정의(__OpenBSD__) …

(OpenBSD/NetBSD는 응용 프로그램 메모리의 구조를 사용하여 FreeBSD/TrueOS에서 했던 이전 방식으로 작업을 수행 ps_strings하지만 sysctl()여전히 구조의 위치를 ​​찾는 데 사용되는 기본 시스템 호출입니다.)

% /package/admin/nosh/command/exec 포그라운드 일시 중지\;true&
[1]30318
% hexdump -C /proc/30318/cmdline
00000000 66 6f 72 65 67 72 6f 75 6e 64 00 70 61 75 73 65 |전망.일시 중지|
00000010 00 3b 00 74 72 75 65 00 |.;.true.|
00000018
% hexdump -C /proc/30319/cmdline
00000000 70 61 75 73 65 00 | |
00000006
%

setproctitle()작업 도구가 잘못되었기 때문에 ,Chromium은 새로운 argv회원을 확보하고 ␠로 구분된 긴 문자열을 구축합니다., 단일 인수로 에 전달됩니다 setproctitle().

  for (size_t i = 1; i < command_line->argv().size(); ++i) {
    if (!title.empty())
      제목 += "";
    제목 += command_line->argv()[i];
  }
  // 위에서 직접 '-'를 추가하면 argv[0] 앞에 추가하는 것이 비활성화됩니다.
  setproctitle(have_argv0 ? "-%s" : "%s", title.c_str());

보시다시피 크롬이미새 매개변수 벡터는 ␀로 끝나는 일련의 문자열로 제공됩니다. 이를 모두 문자열로 압축해야 하는 중간 라이브러리 계층에 전달합니다. 여기서 실제 시스템 호출 수준은 여전히 ​​␀로 끝나는 문자열의 인수 벡터에서 작동합니다.

따라서 여러분이 보고 있는 동작은 Chromium이 변경된 매개변수 벡터를 시스템에 제공한다는 것입니다.별도의 매개변수로.

아마도 Chromium 작성자가 비슷한 것을 채택하도록 설득할 수 있을 것입니다 setprocargv(). ☺

추가 읽기

  • 피터 웸(1995-12-16).setproctitle. FreeBSD 라이브러리 함수 매뉴얼. 무료 BSD.

관련 정보