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

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

私の日垞業務は䞻に゜フトりェア システムの導入です。぀たり、次のような質問に答えるのに倚くの時間を費やしおいたす。

  • 開発者はこの゜フトりェアを動䜜させおいたすが、私の堎合は動䜜させおいたせん。なぜ
  • 昚日はこの゜フトりェアは動䜜したしたが、今日は動䜜したせん。なぜ

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

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

straceずは䜕ですか?

ストラス —は「システムコヌルトレヌス」のためのツヌルです。元々は 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 のようなものです。昔は、゜フトりェアはそれが実行されるハヌドりェアに盎接アクセスしおいたした。たずえば、画面に䜕かを衚瀺する必芁がある堎合、ビデオ デバむスのポヌトやメモリ マップ レゞスタを操䜜したす。マルチタスク コンピュヌタ システムが普及するず、さたざたなアプリケヌションがハヌドりェアを奪い合うようになり、混乱が生じたした。 1 ぀のアプリケヌションにバグがあるず、システム党䜓ではなくずも、他のアプリケヌションがダりンする可胜性がありたす。その埌、CPU に特暩モヌド (たたは「リング保護」) が登堎したした。カヌネルは最も特暩を持぀ようになりたした。぀たり、ハヌドりェアぞの完党なアクセス暩を取埗し、システム コヌルを通じおハヌドりェアず察話するためにカヌネルにアクセスを芁求する必芁のある、暩限の䜎いアプリケヌションが生成されたした。

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

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

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

  • コン゜ヌル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 䜎レベルのメモリ怜出や動的ラむブラリマッピングなどの機胜がありたす。実際、デバッグ時には、出力 ストラス 最埌から読むのが良いでしょう。䞋蚘に電話がかかっおきたす 曞きたす、゚ラヌメッセヌゞが衚瀺されたす。䞊を芋るず、最初の゚ラヌのあるシステムコヌルがわかりたす。 開く、゚ラヌが発生したす ゚ノ゚ント 「ファむルたたはディレクトリが芋぀かりたせん」開こうずしおいたす config.json は、。ここに構成ファむルを眮く必芁がありたす。

これは単なる䟋ですが、私は90の確率で ストラス、これより難しいこずは䜕もありたせん。以䞋は完党なステップバむステップのデバッグ ガむドです。

  • プログラムからの曖昧なシステム゚ラヌメッセヌゞにむラむラ
  • プログラムを再起動する ストラス
  • トレヌス結果で゚ラヌメッセヌゞを芋぀ける
  • 最初の倱敗したシステムコヌルに到達するたで、さらに䞊に進みたす

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

ヒント

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

男はあなたの友達です

倚くの*nixシステムでは、カヌネルぞのシステムコヌルの完党なリストは、以䞋を実行するこずで取埗できたす。 man システムコヌル。次のようなものが芋られたす ブレヌキ(2)を実行するこずでより倚くの情報を埗るこずができたす。 男2BRK.

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

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

ストラス 広範な出力が生成される可胜性があるため、トレヌス結果を別々のファむルに保存するず䟿利な堎合がありたす (䞊蚘の䟋のように)。たた、プログラムの出力ず出力を混同しないようにするのにも圹立ちたす ストラス コン゜ヌルで。

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

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

- ファむルや゜ケットなどの远跡が容易になりたす。

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

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

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

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

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

ルヌトアクセスが必芁になる堎合がありたす。

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

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

゚ラヌが子プロセスにあるず思われる堎合は、挔算子を䜿甚したす。 -fこれにより、トレヌスが可胜になりたす。この方法の欠点は、結論があなたをさらに混乱させるだけだずいうこずです。い぀ ストラス 単䞀のプロセスたたはスレッドをトレヌスするず、呌び出しむベントの単䞀のフロヌが衚瀺されたす。耇数のプロセスを䞀床にトレヌスするず、メッセヌゞによっお通話の開始が䞭断されるこずがありたす。 、その埌、他の実行ブランチぞの呌び出しが続き、最初のブランチの終了が行われたす。 <
 foocall が再開されたした>。たたは、挔算子を䜿甚しおすべおのトレヌス結果を別のファむルに分割するこずもできたす。 -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 で䜕をどのように行うかを少しでも理解しおいれば、システム コヌル トレヌスの結果を理解しやすくなりたす。䟋えば、ネットワヌクシステムぞの呌び出しのデバッグに問題がある堎合は、同じ叀兞的な 「ネットワヌクプログラミングガむド」Bij著.

より耇雑なデバッグの䟋

すでに述べたように、この簡単なデバッグの䟋は、私が䜜業する際に䞻に察凊しなければならない䟋です。 ストラス。ただし、実際の調査が必芁になる堎合もあるため、ここではもう少し耇雑なデバッグの実際の䟋を瀺したす。

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

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

では、 bcron 特定のファむルを曞き蟌もうずしたが、うたくいかなかったが、その理由を認めようずしない。開梱しおみたしょう ストラス:

# 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 ぀ありたす。 開く 䞀番䞊に ゜ケット 途䞭で。 開く ファむルを開くが 閉じるその埌、再び閉じおいるこずが衚瀺されたす。 (Rake: ファむル蚘述子は、開いたり閉じたりするずきに再利甚できたす。) ゜ケット 最埌のものなのでぎったりです 読んだそしお、bcrontab は゜ケットを介しお䜕かず連携するこずがわかりたした。次の行は、ファむル蚘述子が UNIXドメむン゜ケット 途䞭で /var/run/bcron-spool.

そこで、私たちは、 UNIX゜ケット 反察偎に。この目的には、いく぀かの巧劙なトリックがあり、どちらもサヌバヌの展開のデバッグに圹立ちたす。 1぀目は netstat たたはそれ以降 ss (゜ケットステヌタス)。どちらのコマンドもシステムのアクティブなネットワヌク接続を衚瀺し、オペレヌタ -l リスニング゜ケットずオペレヌタを蚘述する -p ゜ケットにクラむアントずしお接続されおいるプログラムを衚瀺したす。 (他にも䟿利なオプションはたくさんありたすが、このタスクにはこれら 2 ぀で十分です。)

# 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 を゜ケットずしお䜿甚しおいたす。)

同じ情報を芋぀けるのに本圓に䟿利な2番目のツヌルは lsof。システム䞊で開いおいるすべおのファむル (たたはファむル蚘述子) を䞀芧衚瀺したす。たたは、特定のファむルに関する情報を取埗するこずもできたす。

# 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/トレヌス -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/スプヌル.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/spool/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/spool/cron/tmp/。シンプルなコマンド chown cron /var/spool/cron/tmp/ 䜜る予定です bcron 正垞に動䜜したす。これが問題でない堎合、次に疑われるのは SE カヌネル セキュリティ モゞュヌルです。Linux たたはAppArmorなので、カヌネルメッセヌゞログを確認したす。 dmesg.)

合蚈で

初心者にずっお、システム コヌル トレヌスの出力は圧倒的なものになる可胜性がありたすが、䞀般的なデプロむメントの問題党䜓をデバッグするための簡単な方法であるこずを瀺せたず思いたす。マルチプロセスのデバッグを想像しおみおください bcronステップバむステップのデバッガヌを䜿甚したす。

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

出所 habr.com

DDoS 保護機胜を備えた信頌性の高いサむト甚ホスティング、VPS VDS サヌバヌを賌入する 🔥 DDoS攻撃察策付きの信頌性の高いりェブサむトホスティング、VPS/VDSサヌバヌを賌入したしょう | ProHoster