/proc/pid/cmdline
Linuxシステム(Ubuntu 16.04)では、さまざまなプロセスの値を解析していますが、ほとんどの項目がnullでエンコードされていることがわかりました。予想通り、少なくとも1つはスペースを区切り文字として使用しますが、これは予期しませんでした。
~からproc(5) のドキュメント私はこれが起こらなければならないという兆候を見ませんでした。場合によっては、空白をnullの代わりに区切り文字として使用する必要がありますか?では、この動作を説明する文書はどこにありますか?
行動
これは、Chromeブラウザプロセスの1つの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
少なくとも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で使用されていないNULLポインタと呼ばれる追加機能があります(しかし皮肉なことに、それでも自分のsetproctitle()
実装でそれを処理する必要があります)。
人々はより少ないコードでより良い結果を得ることができます。これ低レベルのシステムコールFreeBSD / TrueOSでパラメータデータが設定されると、ライブラリ関数はこの関数を呼び出して操作を実行します。この関数は、およびプロセスIDsysctl()
でアドレス指定された関数です。これCTL_KERN
KERN_PROC
KERN_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。