forked from heroku/erlang-in-anger
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy path106-crash-dumps-ja.tex
205 lines (160 loc) · 17.3 KB
/
106-crash-dumps-ja.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
%\chapter{Reading Crash Dumps}
\chapter{クラッシュダンプを読む}
\label{chap:crash-dumps}
%Whenever an Erlang node crashes, it will generate a crash dump\footnote{If it isn't killed by the OS for violating ulimits while dumping or didn't segfault.}.
Erlangノードはクラッシュすると、クラッシュダンプを出力します。\footnote{ダンプ中にulimitsの制限を超えてOSに殺されたり、セグメンテーションフォールトしない限りは}
%The format is mostly documented in Erlang's official documentation\footnote{\href{http://www.erlang.org/doc/apps/erts/crash\_dump.html}{http://www.erlang.org/doc/apps/erts/crash\_dump.html}}, and anyone willing to dig deeper inside of it will likely be able to figure out what data means by looking at that documentation. There will be specific data that is hard to understand without also understanding the part of the VM they refer to, but that might be too complex for this document.
フォーマットについてはErlangのオフィシャルドキュメントにほとんど書かれており\footnote{\href{http://www.erlang.org/doc/apps/erts/crash\_dump.html}{http://www.erlang.org/doc/apps/erts/crash\_dump.html}}、深く掘り下げたい人は誰でもそのドキュメントを見ることで、データが意味していることを把握することができるでしょう。特定のデータについては更にVMの一部についても理解していないと理解することが難しいものがありますが、このドキュメントに載せるには複雑過ぎます。
%The crash dump is going to be named \filename{erl\_crash.dump} and be located wherever the Erlang process was running by default. This behaviour (and the file name) can be overridden by specifying the \command{ERL\_CRASH\_DUMP} environment variable\footnote{Heroku's Routing and Telemetry teams use the \otpapp{\href{https://github.com/heroku/heroku\_crashdumps}{heroku\_crashdumps}} app to set the path and name of the crash dumps. It can be added to a project to name the dumps by boot time and put them in a pre-set location}.
クラッシュダンプはデフォルトで\filename{erl\_crash.dump}という名前で、Erlangプロセスが動いている場所へ出力されます。この挙動(ファイル名も含めて)は\command{ERL\_CRASH\_DUMP}環境変数\footnote{Herokuのルーティングとテレメトリチームは\otpapp{\href{https://github.com/heroku/heroku\_crashdumps}{heroku\_crashdumps}}アプリケーションを使ってクラッシュダンプのパスと名前を設定しています。これをプロジェクトに追加して、起動時にダンプの名前をつけ、それらを事前に指定した場所に置くことができます。}を指定することで上書きできます。
%\section{General View}
\section{一般的な見方}
\label{sec:crashdump-general-view}
%Reading the crash dump will be useful to figure out possible reasons for a node to die \emph{a posteriori}. One way to get a quick look at things is to use recon's \app{erl\_crashdump\_analyzer.sh}\footnote{\href{https://github.com/ferd/recon/blob/master/script/erl\_crashdump\_analyzer.sh}{https://github.com/ferd/recon/blob/master/script/erl\_crashdump\_analyzer.sh}} and run it on a crash dump:
クラッシュダンプを読むことは\emph{事後に}ノードが死んだ可能性のある理由を理解するのに役立つことがあります。それらを素早く見るためにreconの\app{erl\_crashdump\_analyzer.sh}\footnote{\href{https://github.com/ferd/recon/blob/master/script/erl\_crashdump\_analyzer.sh}{https://github.com/ferd/recon/blob/master/script/erl\_crashdump\_analyzer.sh}}を使う方法があり、それをクラッシュダンプに対して実行します。
%% Show debugging here with output
\begin{VerbatimRaw}
$ ./recon/script/erl_crashdump_analyzer.sh erl_crash.dump
analyzing erl_crash.dump, generated on: Thu Apr 17 18:34:53 2014
Slogan: eheap_alloc: Cannot allocate 2733560184 bytes of memory
(of type "old_heap").
Memory:
===
processes: 2912 Mb
processes_used: 2912 Mb
system: 8167 Mb
atom: 0 Mb
atom_used: 0 Mb
binary: 3243 Mb
code: 11 Mb
ets: 4755 Mb
---
total: 11079 Mb
Different message queue lengths (5 largest different):
===
1 5010932
2 159
5 158
49 157
4 156
Error logger queue length:
===
0
File descriptors open:
===
UDP: 0
TCP: 19951
Files: 2
---
Total: 19953
Number of processes:
===
36496
Processes Heap+Stack memory sizes (words) used in the VM (5 largest
different):
===
1 284745853
1 5157867
1 4298223
2 196650
12 121536
Processes OldHeap memory sizes (words) used in the VM (5 largest
different):
===
3 318187
9 196650
14 121536
64 75113
15 46422
Process States when crashing (sum):
===
1 Garbing
74 Scheduled
36421 Waiting
\end{VerbatimRaw}
%This data dump won't point out a problem directly to your face, but will be a good clue as to where to look. For example, the node here ran out of memory and had 11079 Mb out of 15 Gb used (I know this because that's the max instance size we were using!) This can be a symptom of:
このデータダンプはあなたの目の前にある問題を直接指摘してはくれませんが、どこを見れば良いのかの良い手がかりとなります。例えば、ここではこのノードはメモリ不足となりましたが、15GBあるうちの11079MBを使用していました(我々が使っていた最大のインスタンスサイズだったので私はこれを覚えています!)。これは以下の事柄に対するひとつの症状となり得ます。
\begin{itemize*}
% \item memory fragmentation;
\item メモリフラグメンテーション;
% \item memory leaks in C code or drivers;
\item Cコードまたはドライバーのメモリリーク;
% \item lots of memory that got to be garbage-collected before generating the crash dump\footnote{Notably here is reference-counted binary memory, which sits in a global heap, but ends up being garbage-collected before generating the crash dump. The binary memory can therefore be underreported. See Chapter \ref{chap:memory-leaks} for more details}.
\item クラッシュダンプを生成する前にガベージコレクトされてしまった大量のメモリ\footnote{特にここではリファレンスカウントされたバイナリメモリです。これはグローバルのヒープ領域に格納されるますが、クラッシュダンプを生成する前にガベージコレクトされ消えます。従ってそのバイナリメモリは過小にレポートされます。より詳しくは\ref{chap:memory-leaks}を参照}.
\end{itemize*}
%More generally, look for anything surprising for memory there. Correlate it with the number of processes and the size of mailboxes. One may explain the other.
より一般的にメモリに関して驚くべきものを探すには、それをプロセスの数とメールボックスのサイズに相関させます。どちらか一方が他方を説明してくれるかもしれません。
%In this particular dump, one process had 5 million messages in its mailbox. That's telling. Either it doesn't match on all it can get, or it is getting overloaded. There are also dozens of processes with hundreds of messages queued up — this can point towards overload or contention. It's hard to have general advice for your generic crash dump, but there still are a few pointers to help figure things out.
この特定のダンプでは、1つのプロセスのメールボックスに5百万のメッセージが格納されていたと示されています。これは取得できるすべてのメッセージがパターンマッチしないか、過負荷になっています。そこには数百のメッセージをキューに溜めた数十のプロセスも存在しています。--- これは過負荷または競合を指すことがあります。あなたの一般的なクラッシュダンプについて一般的なアドバイスをすることは難しいですが、これらを理解するのに役立つ方法はまだいくつかあります。
%\section{Full Mailboxes}
\section{メールボックスがいっぱい}
\label{sec:crash-full-mailboxes}
%For loaded mailboxes, looking at large counters is the best way to do it. If there is one large mailbox, go investigate the process in the crash dump. Figure out if it's happening because it's not matching on some message, or overload. If you have a similar node running, you can log on it and go inspect it. If you find out many mailboxes are loaded, you may want to use recon's \app{queue\_fun.awk} to figure out what function they're running at the time of the crash:
いっぱいのメールボックスについては、大きなカウンターを見るのが最良の方法です。もし大きなメールボックスが1つある場合は、クラッシュダンプのそのプロセスについて調べてください。メッセージがパターンマッチしないか、過負荷のために発生しているかどうかを把握してください。もし同様のノードが動いているのなら、そこに接続して調査することができます。いっぱい溜まっているメールボックスがたくさんあると分かっている場合は、クラッシュ時に何の関数が動いていたか把握するためreconの\app{queue\_fun.awk}を使うことができます。
\begin{VerbatimText}
$ awk -v threshold=10000 -f queue_fun.awk /path/to/erl_crash.dump
MESSAGE QUEUE LENGTH: CURRENT FUNCTION
======================================
10641: io:wait_io_mon_reply/2
12646: io:wait_io_mon_reply/2
32991: io:wait_io_mon_reply/2
2183837: io:wait_io_mon_reply/2
730790: io:wait_io_mon_reply/2
80194: io:wait_io_mon_reply/2
...
\end{VerbatimText}
%This one will run over the crash dump and output all of the functions scheduled to run for processes with at least 10000 messages in their mailbox. In the case of this run, the script showed that the entire node was locking up waiting on IO for \function{io:format/2} calls, for example.
これはクラッシュダンプに対して実行され、メールボックスに少なくとも10000メッセージあるプロセスに対して実行がスケジュールされていた関数をすべて出力します。この実行の場合は、すべてのノードが\function{io:format/2}の呼び出しのためにIO待ちでロックしていたことをスクリプトが示していました。
%\section{Too Many (or too few) Processes}
\section{非常に多い(もしくは非常に少ない)プロセス}
%The process count is mostly useful when you know your node's usual average count\footnote{See subsection \ref{subsec:global-procs} for details}, in order to figure if it's abnormal or not.
正常かどうかを判別するためにプロセス数を数えることは、ノードの通常時のプロセス数を把握している場合にはとても有用です\footnote{詳細は \ref{subsec:global-procs} を参照のこと}。
%A count that is higher than normal may reveal a specific leak or overload, depending on applications.
アプリケーションによりますが、通常よりも多い場合には何かがリークしているか、過負荷かもしれません。
%If the process count is extremely low compared to usual, see if the node terminated with a slogan like:
プロセス数が通常時と比較して極めて少ない場合、ノードが下記のような出力をして(プロセスを)終了していないかを見てください。
\begin{Verbatim}
Kernel pid terminated (application_controller)
({application_terminated, <AppName>, shutdown})
\end{Verbatim}
%In such a case, the issue is that a specific application (\expression{<AppName>}) has reached its maximal restart frequency within its supervisors, and that prompted the node to shut down. Error logs that led to the cascading failure should be combed over to figure things out.
このような場合、そのアプリケーション(\expression{AppName})がスーパバイザ内で再起動制限に引っかかったため、ノードがシャットダウンを行ったことが原因です。一連の問題の原因を詳しく調べるにはエラーログが役に立ちます。
%\section{Too Many Ports}
\section{大量のポート数}
%Similarly to the process count, the port count is simple and mostly useful when you know your usual values\footnote{See subsection \ref{subsec:global-ports} for details}.
プロセス数のカウントと同様に、ポート数も通常時の数を把握している時にはシンプルでとても有用です\footnote{詳細は \ref{subsec:global-ports} を参照のこと}。
%A high count may be the result of overload, Denial of Service attacks, or plain old resource leaks. Looking at the type of port leaked (TCP, UDP, or files) can also help reveal if there was contention on specific resources, or if the code using them is just wrong.
ポート数が多い場合、DoS攻撃や使わなくなったリソースのリークなどに、過負荷になっている可能性があります。リークしているポートの種類(TCP, UTP, ファイル)を見てみることで、リソースの競合やそれらのリソースを使っているコードが間違っているかどうかが分かる可能性があります。
%\section{Can't Allocate Memory}
\section{メモリ割り当てができない}
%These are by far the most common types of crashes you are likely to see. There's so much to cover, that Chapter \ref{chap:memory-leaks} is dedicated to understanding them and doing the required debugging on live systems.
これらは、おそらくあなたが非常によく見る類のクラッシュです。カバーすべきことが多くあるため、\ref{chap:memory-leaks} 章ではその内容の理解と、稼働中のシステムでのデバッグで必要となることについてまとめています。
%In any case, the crash dump will help figure out what the problem was after the fact. The process mailboxes and individual heaps are usually good indicators of issues. If you're running out of memory without any mailbox being outrageously large, look at the processes heap and stack sizes as returned by the recon script.
いずれにせよ、クラッシュダンプは何が問題であったかを事後に把握するために役立ちます。プロセスのメッセージボックスと個々のヒープは通常、問題に対する良い指標です。メールボックスにメッセージが大量にあるわけではないのにメモリが不足している時には、recon スクリプトにより返されるプロセスヒープとスタックサイズを見てみてください。
%In case of large outliers at the top, you know some restricted set of processes may be eating up most of your node's memory. In case they're all more or less equal, see if the amount of memory reported sounds like a lot.
最初に大きな外れ値がある場合には、いくつかの特定プロセスによりノードのほとんどのメモリが食いつぶされているかもしれないとわかります。同等の量の場合、(スクリプトから)返されたメモリの量が多くないかを確認してください。
%If it looks more or less reasonable, head towards the "Memory" section of the dump and check if a type (ETS or Binary, for example) seems to be fairly large. They may point towards resource leaks you hadn't expected.
ある程度納得できる量であれば、ダンプの「メモリ」セクションでタイプ(ETSやバイナリーなど)が非常に大きくないかをチェックしてください。想定外のリソースのリークが見つかるかもしれません。
%\section{Exercises}
\section{演習}
%\subsection*{Review Questions}
\subsection*{復習問題}
\begin{enumerate}
%\item How can you choose where a crash dump will be generated?
\item クラッシュダンプが生成される場所をどのように指定しますか?
%\item What are common avenues to explore if the crash dump shows that the node ran out of memory?
\item クラッシュダンプがノードがメモリ不足で落ちていることを示している場合、通常どのように探しますか?
%\item What should you look for if the process count is suspiciously low?
\item プロセス数が疑わしいほど少ない場合、どこを見るべきでしょうか?
%\item If you find the node died with a process having a lot of memory, what could you do to find out which one it was?\end{enumerate}
\item ノードが大量のメモリを確保したプロセスとともに死んだことがわかる場合、それがどれであるか見つけるために何をすることができますか?\end{enumerate}
%\subsection*{Hands-On}
\subsection*{ハンズオン}
%Using the analysis of a crash dump in Section \ref{sec:crashdump-general-view}:
\ref{sec:crashdump-general-view}の章にあるクラッシュダンプの分析を使用します。
\begin{enumerate}
%\item What are specific outliers that could point to an issue?
\item 問題を指し示すことができる特定の異常値は何でしょうか?
%\item Does it look like repeated errors are the issue? If not, what could it be?
\item 繰り返されるエラーは問題のように見えますか?そうではない場合、それは何になるのでしょうか?
\end{enumerate}