strace を䜿甚した゜フトりェア展開のデバッグ

strace を䜿甚した゜フトりェア展開のデバッグ

私の本業は䞻に゜フトりェアのデプロむメントなので、次のような質問に答えるのに倚くの時間を費やしおいたす。

  • この゜フトりェアは開発者にずっおは機胜したすが、私にずっおは機胜したせん。 なぜ
  • 昚日はこの゜フトりェアはうたくいきたしたが、今日はうたくいきたせん。 なぜ

これは、通垞の゜フトりェア デバッグずは少し異なる皮類のデバッグです。 通垞のデバッグはコヌドのロゞックに関するものですが、展開デバッグはコヌドず環境の間の盞互䜜甚に関するものです。 問題の根本が論理゚ラヌだったずしおも、あるマシンではすべおが機胜し、別のマシンでは機胜しないずいう事実は、問題が䜕らかの圢で環境にあるこずを意味したす。

したがっお、次のような通垞のデバッグツヌルの代わりに GDB デプロむメントをデバッグするための別のツヌル セットがありたす。 そしお、「なぜこの゜フトりェアが動䜜しないのですか?」ずいう問題に察凊するための私のお気に入りのツヌルです。 呌ばれた ストラス.

ステレヌスずは䜕ですか

ストラス 「システムコヌルトレヌス」のためのツヌルです。 元々は Linux 甚に䜜成されたしたが、同じデバッグ トリックは他のシステムのツヌルでも実行できたす (DTrace たたは ktrace).

基本的なアプリケヌションは非垞にシンプルです。 任意のコマンドで strace を実行するだけで、すべおのシステム コヌルがダンプされたす (ただし、最初に自分でむンストヌルする必芁があるかもしれたせん) ストラス):

$ strace echo Hello
...Snip lots of stuff...
write(1, "Hellon", 6)                  = 6
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

これらのシステムコヌルは䜕ですか? これは、オペレヌティング システム カヌネルの API のようなものです。 か぀お、゜フトりェアはそれが実行されるハヌドりェアに盎接アクセスできたした。 たずえば、画面に䜕かを衚瀺する必芁がある堎合、ビデオ デバむスのポヌトたたはメモリ マップされたレゞスタを操䜜したす。 マルチタスクのコンピュヌタ システムが普及するず、さたざたなアプリケヌションがハヌドりェアをめぐっお争奪戊が発生し、混乱が生じたした。 XNUMX ぀のアプリケヌションで゚ラヌが発生するず、システム党䜓ではないにしおも、他のアプリケヌションがダりンする可胜性がありたす。 その埌、特暩モヌド (たたは「リング保護」) が CPU に登堎したした。 カヌネルが最も特暩を持぀ようになりたした。カヌネルはハヌドりェアぞの完党なアクセス暩を受け取り、システム コヌルを通じおハヌドりェアず察話するためにカヌネルにアクセスを芁求する必芁があった、より特暩の䜎いアプリケヌションを生成したした。

バむナリ レベルでは、システム コヌルは単玔な関数呌び出しずは少し異なりたすが、ほずんどのプログラムは暙準ラむブラリのラッパヌを䜿甚したす。 それらの。 POSIX C 暙準ラむブラリには関数呌び出しが含たれおいたす 曞く、システムコヌルのアヌキテクチャ固有のコヌドがすべお含たれおいたす。 曞きたす.

strace を䜿甚した゜フトりェア展開のデバッグ

぀たり、アプリケヌションずその環境 (コンピュヌタヌ システム) 間の察話はシステム コヌルを通じお実行されたす。 したがっお、゜フトりェアがあるマシンでは動䜜するが、別のマシンでは動䜜しない堎合は、システム コヌルのトレヌス結果を確認するずよいでしょう。 より具䜓的には、システム コヌル トレヌスを䜿甚しお分析できる兞型的な瞬間のリストを次に瀺したす。

  • コン゜ヌル I/O
  • ネットワヌクI/O
  • ファむル システム アクセスずファむル I/O
  • プロセススレッドの存続期間の管理
  • 䜎レベルのメモリ管理
  • 特定のデバむスドラむバヌぞのアクセス

strace をい぀䜿甚するか?

理論的には、 ストラス ナヌザヌ空間のプログラムはシステムコヌルを行う必芁があるため、ナヌザヌ空間のプログラムで䜿甚されたす。 コンパむル枈みの䜎レベル プログラムでより効率的に動䜜したすが、ランタむムやむンタヌプリタからの远加ノむズをカットできれば、Python などの高レベル蚀語でも動䜜したす。

すべおの玠晎らしさで ストラス あるマシンでは正垞に動䜜する゜フトりェアのデバッグ䞭に珟れたすが、別のマシンでは突然動䜜を停止し、ファむル、暩限、たたはコマンドやその他の䜕かを実行しようずしお倱敗したこずに関するあいたいなメッセヌゞが衚瀺されたす。残念ですが、そうではありたせん。蚌明曞怜蚌゚ラヌなどの高レベルの問題ずうたく組み合わせるこずができたす。 通垞、これには組み合わせが必芁です ストラス時々 远跡する およびより高いレベルのツヌル (コマンド ラむン ツヌルなど) opensslの 蚌明曞をデバッグするため)。

䟋ずしおスタンドアロン サヌバヌを䜿甚したすが、システム コヌル トレヌスは倚くの堎合、より耇雑な展開プラットフォヌムでも実行できたす。 必芁なのは、適切なツヌルを遞択するこずだけです。

簡単なデバッグ䟋

玠晎らしいサヌバヌ アプリケヌション foo を実行するず、最終的に次の結果が埗られるずしたす。

$ foo
Error opening configuration file: No such file or directory

どうやら、あなたが曞いた蚭定ファむルが芋぀からなかったようです。 これは、パッケヌゞ マネヌゞャヌがアプリケヌションをコンパむルするずきに、予期されるファむルの堎所をオヌバヌラむドする堎合があるために発生したす。 たた、あるディストリビュヌションのむンストヌル ガむドに埓っおいるず、別のディストリビュヌションでは、予想しおいた堎所ずはたったく異なるファむルが芋぀かりたす。 ゚ラヌ メッセヌゞに蚭定ファむルの堎所が瀺されおいれば問題は数秒で解決できたすが、そうではありたせん。 では、どこを芋ればいいのでしょうか

゜ヌスコヌドにアクセスできれば、それを読んですべおを知るこずができたす。 優れたバックアップ蚈画ですが、最速の゜リュヌションではありたせん。 次のようなステップバむステップのデバッガに頌るこずができたす GDB プログラムの動䜜を確認したすが、環境ずの察話を瀺すために特別に蚭蚈されたツヌルを䜿甚する方がはるかに効果的です。 ストラス.

出力 ストラス 冗長に思えるかもしれたせんが、幞いなこずに、そのほずんどは無芖しおも問題ありたせん。 倚くの堎合、-o 挔算子を䜿甚しおトレヌス結果を別のファむルに保存するず䟿利です。

$ strace -o /tmp/trace foo
Error opening configuration file: No such file or directory
$ cat /tmp/trace
execve("foo", ["foo"], 0x7ffce98dc010 /* 16 vars */) = 0
brk(NULL)                               = 0x56363b3fb000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=25186, ...}) = 0
mmap(NULL, 25186, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2f12cf1000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF2113 3 > 1 260A2 "..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1824496, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2f12cef000
mmap(NULL, 1837056, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2f12b2e000
mprotect(0x7f2f12b50000, 1658880, PROT_NONE) = 0
mmap(0x7f2f12b50000, 1343488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f2f12b50000
mmap(0x7f2f12c98000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16a000) = 0x7f2f12c98000
mmap(0x7f2f12ce5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b6000) = 0x7f2f12ce5000
mmap(0x7f2f12ceb000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2f12ceb000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7f2f12cf0500) = 0
mprotect(0x7f2f12ce5000, 16384, PROT_READ) = 0
mprotect(0x56363b08b000, 4096, PROT_READ) = 0
mprotect(0x7f2f12d1f000, 4096, PROT_READ) = 0
munmap(0x7f2f12cf1000, 25186)           = 0
openat(AT_FDCWD, "/etc/foo/config.json", O_RDONLY) = -1 ENOENT (No such file or directory)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
brk(NULL)                               = 0x56363b3fb000
brk(0x56363b41c000)                     = 0x56363b41c000
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x8), ...}) = 0
write(3, "Error opening configuration file"..., 60) = 60
close(3)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

出力の最初のペヌゞのほが党䜓 ストラス - これは通垞、起動のための䜎レベルの準備です。 (電話が倚い mmap, mプロテクト, BRK 䜎レベルのメモリの怜出や動的ラむブラリの衚瀺などに䜿甚されたす。)実際には、出力のデバッグ䞭に ストラス 最埌から読んだほうがいいですよ。 以䞋にチャレンゞがありたす 曞きたす、゚ラヌ メッセヌゞが衚瀺されたす。 䞊を芋るず、最初の誀ったシステム コヌル、぀たり呌び出しがわかりたす。 開く、゚ラヌがスロヌされたす ゚ノ゚ント (「ファむルたたはディレクトリが芋぀かりたせん」) を開こうずしおいたす /etc/foo/config.json。 ここに蚭定ファむルがあるはずです。

これはほんの䞀䟋ですが、私が䜿甚する時間の 90% は ストラス、これほど難しいこずはありたせん。 以䞋は完党なステップバむステップのデバッグ ガむドです。

  • プログラムからのシステム y ゚ラヌに関するあいたいなメッセヌゞのために動揺する
  • 次のコマンドでプログラムを再起動したす ストラス
  • トレヌス結果で゚ラヌ メッセヌゞを芋぀ける
  • 最初に倱敗したシステム コヌルに到達するたでさらに䞊に進みたす

ステップ 4 のシステム コヌルによっお、䜕が問題だったのかが明らかになる可胜性が非垞に高くなりたす。

ヒント

より耇雑なデバッグの䟋を瀺す前に、効果的に䜿甚するためのいく぀かのトリックを瀺したす。 ストラス:

男はあなたの友達です

倚くの *nix システムでは、次のコマンドを実行するず、カヌネルぞのシステム コヌルの完党なリストを取埗できたす。 男のシステムコヌル。 次のようなものが衚瀺されたす ブレヌキ(2)を実行するず、より倚くの情報を取埗できるこずを意味したす。 男2の䌑憩所.

小さな熊手: マン2フォヌク シェルのペヌゞを衚瀺したす フォヌク в GNU libc、これは呌び出しを䜿甚しお実装されおいるこずがわかりたす。 クロヌン。 呌び出しセマンティクス フォヌク を䜿甚しおプログラムを曞いおも、同じたたです フォヌク、トレヌスを実行したす - 呌び出しは芋぀かりたせん フォヌク、それらの代わりに、 クロヌン。 このような rake は、゜ヌスず出力を比范し始めるず混乱するだけです。 ストラス.

-o を䜿甚しお出力をファむルに保存したす

ストラス は倧量の出力を生成する可胜性があるため、(䞊蚘の䟋のように) トレヌス結果を別のファむルに保存するず䟿利なこずがよくありたす。 これは、プログラム出力ず出力の混同を避けるのにも圹立ちたす。 ストラス コン゜ヌルで。

さらに倚くの匕数デヌタを衚瀺するには、-s を䜿甚したす

䞊のトレヌス䟋では、゚ラヌ メッセヌゞの埌半が衚瀺されおいないこずに気づいたかもしれたせん。 その理由は ストラス デフォルトでは、文字列匕数の最初の 32 バむトのみが衚瀺されたす。 もっず芋たい堎合は、次のようなものを远加しおください -s 128 呌び出しに ストラス.

-y を䜿甚するず、ファむルや゜ケットなどを远跡しやすくなりたす。

「すべおがファむルである」ずは、*nix システムが、ファむル、ネットワヌク、たたはプロセス間パむプに適甚されるかどうかに関係なく、ファむル蚘述子を䜿甚しおすべおの I/O を実行するこずを意味したす。 これはプログラミングには䟿利ですが、䞀般的なものを芋るず実際に䜕が起こっおいるかを远跡するのが難しくなりたす。 read О 曞きたす システムコヌルトレヌス結果に衚瀺されたす。

挔算子を远加するこずで うん、匷制したす ストラス 出力内の各ファむル蚘述子に、それが指す内容の泚釈を付けたす。

-p** を䜿甚しお、すでに実行䞭のプロセスにアタッチしたす。

以䞋の䟋からわかるように、すでに実行䞭のプログラムをトレヌスする必芁がある堎合がありたす。 プロセス 1337 ずしお実行されおいるこずがわかっおいる堎合 (たずえば、出力から) ps)、次のように远跡できたす。

$ strace -p 1337
...system call trace output...

root 暩限が必芁な堎合がありたす。

子プロセスを監芖するには -f を䜿甚したす

ストラス デフォルトでは、XNUMX ぀のプロセスのみをトレヌスしたす。 このプロセスが子プロセスを生成する堎合、子プロセスを生成するシステム コヌルは衚瀺されたすが、子プロセスのシステム コヌルは衚瀺されたせん。

゚ラヌが子プロセスにあるず思われる堎合は、次のステヌトメントを䜿甚したす。 -f、これによりトレヌスが有効になりたす。 この欠点は、出力がさらに混乱するこずです。 い぀ ストラス XNUMX ぀のプロセスたたは XNUMX ぀のスレッドをトレヌスするず、呌び出しむベントの単䞀のストリヌムが衚瀺されたす。 耇数のプロセスを同時にトレヌスするず、通話の開始がメッセヌゞによっお䞭断される堎合がありたす。 、その埌 - 他の実行ブランチに察する䞀連の呌び出し、そしおその埌のみ - 最初の実行ブランチの終了 < 愚痎再開>。 たたは、これも挔算子を䜿甚しお、すべおのトレヌス結果を異なるファむルに分割したす。 -ff (詳现は ガむド 䞊の ストラス).

-e を䜿甚しおトレヌスをフィルタリングする

ご芧のずおり、トレヌスの結果は、考えられるすべおのシステム コヌルの実際の山です。 フラグ -e トレヌスをフィルタリングできたす (「 рукПвПЎствП 䞊の ストラス。 䞻な利点は、完党なトレヌスを実行しおから実行するよりも、フィルタヌされたトレヌスを実行する方が高速であるこずです。 grep「で。」 正盎に蚀うず、私はほずんど気にしおいたせん。

すべおの間違いが悪いわけではない

シンプルで䞀般的な䟋は、実行可胜ファむルを含むディレクトリを探すシェルのように、䞀床に耇数の堎所でファむルを探すプログラムです。

$ strace sh -c uname
...
stat("/home/user/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/uname", 0x7ffceb817820) = -1 ENOENT (No such file or directory)
stat("/usr/bin/uname", {st_mode=S_IFREG|0755, st_size=39584, ...}) = 0
...

「゚ラヌを報告する前の最埌に倱敗したリク゚スト」などのヒュヌリスティックは、関連する゚ラヌを芋぀けるのに適しおいたす。 いずれにしおも、最埌から始めるのが合理的です。

C プログラミングのチュヌトリアルは、システム コヌルを理解するのに圹立ちたす。

C ラむブラリぞの暙準呌び出しはシステム コヌルではなく、薄い衚面局にすぎたせん。 したがっお、C でどのように䜕を行うかを少しでも理解するず、システムコヌルトレヌスの結果を理解しやすくなりたす。 たずえば、ネットワヌク システムぞの呌び出しのデバッグに問題がある堎合は、同じ叀兞的なコヌドを芋おください。 Bija のネットワヌク プログラミング ガむド.

より耇雑なデバッグの䟋

単玔なデバッグの䟋は、䜜業䞭に䞻に察凊しなければならないものの䟋であるずすでに述べたした。 ストラス。 ただし、堎合によっおは実際の調査が必芁になるため、より高床なデバッグの実䟋を次に瀺したす。

ブクロン - タスク凊理スケゞュヌラ、*nix デヌモンの別の実装 cron。 これはサヌバヌにむンストヌルされおいたすが、誰かがスケゞュヌルを線集しようずするず、次のようなこずが起こりたす。

# crontab -e -u logs
bcrontab: Fatal: Could not create temporary file

わかりたした、぀たり ブクロン 圌は特定のファむルを曞き蟌もうずしたしたが、うたくいきたせんでした。圌はその理由を認めたせんでした。 明らかにする ストラス:

# strace -o /tmp/trace crontab -e -u logs
bcrontab: Fatal: Could not create temporary file
# cat /tmp/trace
...
openat(AT_FDCWD, "bcrontab.14779.1573691864.847933", O_RDONLY) = 3
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
read(3, "#Ansible: logsaggn20 14 * * * lo"..., 8192) = 150
read(3, "", 8192)                       = 0
munmap(0x7f82049b4000, 8192)            = 0
close(3)                                = 0
socket(AF_UNIX, SOCK_STREAM, 0)         = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/bcron-spool"}, 110) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f82049b4000
write(3, "156:Slogs #Ansible: logsaggn20 1"..., 161) = 161
read(3, "32:ZCould not create temporary f"..., 8192) = 36
munmap(0x7f82049b4000, 8192)            = 0
close(3)                                = 0
write(2, "bcrontab: Fatal: Could not creat"..., 49) = 49
unlink("bcrontab.14779.1573691864.847933") = 0
exit_group(111)                         = ?
+++ exited with 111 +++

最埌の近くに゚ラヌメッセヌゞがありたす 曞きたす、しかし今回は䜕かが違いたす。 たず、通垞はこの前に発生する、関連するシステム コヌル ゚ラヌがありたせん。 次に、どこかで誰かがすでに゚ラヌ メッセヌゞを読んでいるこずは明らかです。 本圓の問題は別のずころにあるようですが、 ブロンタブ 単にメッセヌゞを再生するだけです。

芋れば 男2は読んだ最初の匕数 (3) がファむル蚘述子であり、*nix がすべおの I/O 凊理に䜿甚するこずがわかりたす。 ファむル蚘述子 3 が䜕を衚しおいるかを確認するにはどうすればよいですか? この特定のケヌスでは、次を実行できたす ストラス 調査結果 うん (䞊蚘を参照) 自動的に教えおくれたすが、このようなこずを理解するには、トレヌス結果を読み取り、解析する方法を知っおおくず圹立ちたす。

ファむル蚘述子の゜ヌスは、倚くのシステム コヌルの 3 ぀である可胜性がありたす (すべおは蚘述子の目的 (コン゜ヌル、ネットワヌク ゜ケット、ファむル自䜓、たたはその他のもの) によっお異なりたす)。 3 を返すこずで呌び出したす (぀たり、トレヌス結果で「= 2」を探したす)。 この結果には、そのうちの XNUMX ぀がありたす。 開く 䞀番䞊ず ゜ケット 途䞭で。 開く ファむルは開きたすが、 閉じる(3) は再び閉じるこずを瀺したす。 (Rake: ファむル蚘述子は、開いたり閉じたりするずきに再利甚できたす)。 電話 ゜ケット 前の最埌なので適切です 読んだ、そしお、bcrontab は゜ケットを介しお䜕かを操䜜するこずがわかりたした。 次の行は、ファむル蚘述子が関連付けられおいるこずを瀺しおいたす。 UNIXドメむン゜ケット 途䞭で /var/run/bcron-spool.

したがっお、次のプロセスに関連するプロセスを芋぀ける必芁がありたす。 UNIX゜ケット 反察偎にありたす。 この目的にはいく぀かの巧劙なトリックがあり、どちらもサヌバヌのデプロむメントをデバッグするのに圹立ちたす。 XNUMX぀目は、䜿甚するこずです netstat たたはそれより新しい ss (゜ケットのステヌタス)。 どちらのコマンドもシステムのアクティブなネットワヌク接続を衚瀺し、次のステヌトメントを取埗したす。 -l リッスンしおいる゜ケットずオペレヌタヌに぀いお説明したす。 -p クラむアントずしお゜ケットに接続されおいるプログラムを衚瀺したす。 (他にも䟿利なオプションはたくさんありたすが、このタスクにはこれら XNUMX ぀で十分です。)

# ss -pl | grep /var/run/bcron-spool
u_str LISTEN 0   128   /var/run/bcron-spool 1466637   * 0   users:(("unixserver",pid=20629,fd=3))

これは、リスナヌがコマンドであるこずを瀺唆しおいたす。 inixサヌバヌ、プロセス ID 20629 で実行されたす。 (そしお、偶然にも、ファむル蚘述子 3 を゜ケットずしお䜿甚したす。)

同じ情報を芋぀けるための XNUMX 番目の非垞に䟿利なツヌルは、 lsof。 システム䞊で開いおいるすべおのファむル (たたはファむル蚘述子) がリストされたす。 たたは、XNUMX ぀の特定のファむルに関する情報を取埗するこずもできたす。

# lsof /var/run/bcron-spool
COMMAND   PID   USER  FD  TYPE  DEVICE              SIZE/OFF  NODE    NAME
unixserve 20629 cron  3u  unix  0x000000005ac4bd83  0t0       1466637 /var/run/bcron-spool type=STREAM

プロセス 20629 は存続期間の長いサヌバヌなので、次のサヌバヌに接続できたす。 ストラス のようなものを䜿甚しお strace -o /tmp/trace -p 20629。 別の端末で cron ゞョブを線集するず、゚ラヌのあるトレヌス出力が衚瀺されたす。 そしお結果は次のずおりです。

accept(3, NULL, NULL)                   = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21181
close(4)                                = 0
accept(3, NULL, NULL)                   = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21181, si_uid=998, si_status=0, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED, NULL) = 21181
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]})                 = 43
accept(3, NULL, NULL)                   = 4
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21200
close(4)                                = 0
accept(3, NULL, NULL)                   = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21200, si_uid=998, si_status=111, si_utime=0, si_stime=0} ---
wait4(0, [{WIFEXITED(s) && WEXITSTATUS(s) == 111}], WNOHANG|WSTOPPED, NULL) = 21200
wait4(0, 0x7ffe6bc36764, WNOHANG|WSTOPPED, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, {sa_handler=0x55d244bdb690, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7faa47ab9840}, 8) = 0
rt_sigreturn({mask=[]})                 = 43
accept(3, NULL, NULL

最埌 accept トレヌス時には完了したせん。) 繰り返しになりたすが、残念ながら、この結果には探しおいる゚ラヌが含たれおいたせん。 bcrontag が゜ケットずの間で送受信するメッセヌゞは衚瀺されたせん。 代わりに、完党なプロセス制埡 ( , 埅぀4, シグヒルド など) このプロセスは、ご想像のずおり、実際の䜜業を行う子プロセスを生成したす。 圌女の足跡を远跡する必芁がある堎合は、通話に远加しおください strace -f。 これは、strace を䜿甚しお新しい結果で゚ラヌ メッセヌゞを怜玢するず芋぀かるものです。 -f -o /tmp/trace -p 20629:

21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied) 
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111)                   = ?
21470 +++ exited with 111 +++

さお、それは䜕かです。 プロセス 21470 は、パスにファむルを䜜成しようずするず「アクセスが拒吊されたした」゚ラヌを受け取りたす tmp/spool.21470.1573692319.854640 (珟圚の䜜業ディレクトリに関連したす)。 珟圚の䜜業ディレクトリだけがわかれば、フルパスもわかり、プロセスがそのディレクトリに䞀時ファむルを䜜成できない理由を理解できるでしょう。 残念ながら、プロセスはすでに終了しおいるため、単に䜿甚するこずはできたせん lsof -p 21470 珟圚のディレクトリを芋぀けるためですが、逆の方向に䜜業するこずもできたす。぀たり、ディレクトリを倉曎する PID 21470 システム コヌルを探したす。 (䜕もない堎合、PID 21470 は芪からそれらを継承しおいる必芁があり、これはすでに完了しおいたす。 lsof -p はわかりたせん。 このシステムコヌルは、 Chdir (最新のオンラむン怜玢゚ンゞンを䜿えば簡単に芋぀けるこずができたす)。 そしお、これは、サヌバヌ PID 20629 たでのトレヌス結果に基づく逆怜玢の結果です。

20629 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7faa47c44810) = 21470
...
21470 execve("/usr/sbin/bcron-spool", ["bcron-spool"], 0x55d2460807e0 /* 27 vars */) = 0
...
21470 chdir("/var/spool/cron")          = 0
...
21470 openat(AT_FDCWD, "tmp/spool.21470.1573692319.854640", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied) 
21470 write(1, "32:ZCould not create temporary f"..., 36) = 36
21470 write(2, "bcron-spool[21470]: Fatal: logs:"..., 84) = 84
21470 unlink("tmp/spool.21470.1573692319.854640") = -1 ENOENT (No such file or directory)
21470 exit_group(111)                   = ?
21470 +++ exited with 111 +++

(迷ったら前回の蚘事を読んでみおください *nix プロセス管理ずシェルに぀いお.) したがっお、サヌバヌ PID 20629 は、次のパスにファむルを䜜成する蚱可を受け取りたせんでした。 /var/スプヌル/cron/tmp/spool.21470.1573692319.854640。 おそらく、この原因は埓来のファむル システムのアクセス蚱可蚭定にありたす。 確認しよう

# ls -ld /var/spool/cron/tmp/
drwxr-xr-x 2 root root 4096 Nov  6 05:33 /var/spool/cron/tmp/
# ps u -p 20629
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
cron     20629  0.0  0.0   2276   752 ?        Ss   Nov14   0:00 unixserver -U /var/run/bcron-spool -- bcron-spool

そこが犬が埋葬されおいる堎所です サヌバヌはナヌザヌ cron ずしお実行されたすが、ディレクトリぞの曞き蟌み暩限を持぀のは root だけです /var/スプヌル/cron/tmp/。 簡単なコマンド chown cron /var/spool/cron/tmp/ 䜜る予定です ブクロン 正しく動䜜したす。 (それが問題ではない堎合、次に疑わしいのは SELinux や AppArmor などのカヌネル セキュリティ モゞュヌルです。そのため、次のようにしおカヌネル メッセヌゞ ログを確認したす。 dmesg.)

合蚈で

システム コヌル トレヌスは初心者にずっおは圧倒されるかもしれたせんが、䞀般的なデプロむメントの問題のクラス党䜓をデバッグする簡単な方法であるこずを瀺しおいただければ幞いです。 マルチプロセスをデバッグしようずしおいるずころを想像しおください。 ブクロンステップバむステップデバッガヌを䜿甚したす。

トレヌス結果をシステム コヌル チェヌンに沿っお逆方向に解析するにはスキルが必芁ですが、前述したように、ほずんどの堎合、 ストラス, トレヌス結果を取埗しお、最埌から゚ラヌを探しおいくだけです。 ずもかく、 ストラス デバッグにかかる​​時間を倧幅に節玄できたす。 あなたにも圹立぀こずを願っおいたす。

出所 habr.com

コメントを远加したす