Merge the following changes in the English version:

hackers.sgml : 1.4 -> 1.6

Submitted by:	HARADA Kiroh <kiroh@pp.iij4u.or.jp>
This commit is contained in:
Motoyuki Konno 1998-10-15 16:19:10 +00:00
parent 50d39f7b02
commit 3639938984
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=3608
2 changed files with 400 additions and 6 deletions

View file

@ -1,6 +1,6 @@
<!-- $Id: hackers.sgml,v 1.4 1998-09-06 13:15:50 motoyuki Exp $ -->
<!-- $Id: hackers.sgml,v 1.5 1998-10-15 16:19:10 motoyuki Exp $ -->
<!-- The FreeBSD Japanese Documentation Project -->
<!-- Original revision: 1.4 -->
<!-- Original revision: 1.6 -->
<sect>
<heading>まじめな FreeBSD ハッカーだけの話題<label id="hackers"></heading>
@ -265,5 +265,202 @@
これらの番号を使用してください. どちらの場合であれ, ドライバに関する情報を
<tt>&lt;freebsd-hackers@FreeBSD.ORG&gt;</tt> に流して頂けると助かります.
</sect>
<sect1>
<heading>代替のディレクトリ配置ポリシー</heading>
<p>
現在使われているディレクトリの配置ポリシーは, 私が 1983 年に書い
たものから全く変更されていません. 私は当初の配置ポリシーを, オリ
ジナルの fast filesystem のために書き, まったく改定していません.
このポリシーはシリンダグループを使い尽くすのを防ぐにはうまくいき
ましたが,お気づきの方もいる通り find の動作には不適切です. ほと
んどのファイルシステムの内容は, 深さ優先検索 (ftw とも呼ばれます)
によって作られたアーカイブからレストアして作成されます. この際,
ディレクトリは,シリンダグループにまたがって配置され, 以降の深さ
優先検索を行うには考え得る限り最悪の状態になります. もし作成する
ディレクトリの総数がわかっていれば, 解決方法はあります. (総数 /
シリンダグループ数)個のディレクトリをシリンダグループごとにまと
めて作成すれば良いのです. もちろん最適なディレクトリ配置になるよ
うに, 総数を予測する方法を考えなければなりません. しかし仮にシリ
ンダグループあたりのディレクトリ数を 10 くらいの小さな数に固定し
てしまったとしても, 大幅な改善が望めるでしょう. このポリシーを用
いるべきリストア作業を, 通常の作業(おそらく既存のポリシーを使用
したほうが良いでしょう)を区別するには, 10 秒間の間に作成されたディ
レクトリを最大 10 個までまとめて単一のシリンダグループに書き込む
という手順が使えるでしょう. とにかく私の結論は, そろそろ実験
を始めて見る時期だろうということです.
<sect1>
<heading>カーネルパニックを最大限に利用する</heading>
<p>
<em>[この節は, freebsd-current <ref id="mailing" name="mailing
list"> に <url url="mailto:<wpaul@FreeBSD.ORG" name="Bill Paul">
が投稿したメールを, <url url="mailto:des@FreeBSD.ORG"
name="Dag-Erling Co&iuml;dan Sm&oslash;rgrav"> が校正し,括弧内のコ
メントを追加して引用したものです. ]</em>
<p>
<verb>
From: Bill Paul <wpaul@skynet.ctr.columbia.edu>
Subject: Re: the fs fun never stops
To: ben@rosengart.com
Date: Sun, 20 Sep 1998 15:22:50 -0400 (EDT)
Cc: current@FreeBSD.ORG
</verb>
<p>
<em>[&lt;ben@rosengart.com&gt; が以下のパニックメッセージを
投稿しました.]</em>
<verb>
> Fatal trap 12: page fault while in kernel mode
> fault virtual address = 0x40
> fault code = supervisor read, page not present
> instruction pointer = 0x8:0xf014a7e5
^^^^^^^^^^
> stack pointer = 0x10:0xf4ed6f24
> frame pointer = 0x10:0xf4ed6f28
> code segment = base 0x0, limit 0xfffff, type 0x1b
> = DPL 0, pres 1, def32 1, gran 1
> processor eflags = interrupt enabled, resume, IOPL = 0
> current process = 80 (mount)
> interrupt mask =
> trap number = 12
> panic: page fault
</verb>
<p>このようなメッセージが表示された場合, 問題が起きる状況を確認し
て, 情報を送るだけでは十分ではありません. 下線をつけた命令ポインタ
値は重要な値ですが, 残念ながらこの値は構成に依存します. つまり, こ
の値は使っているカーネルのイメージに依存するのです. もしスナップショッ
トなどの GENERIC カーネルを使っているのであれば, 他の人間が問題の
ある関数について追試をすることができますが, カスタマイズされたカー
ネルの場合は, 使っている本人にしか問題の起こった場所は特定できない
のです.
<p> 何をすれば良いのでしょう?
<itemize>
<item>命令ポインタ値をメモします. <tt/0x8:/ という部分は今回必
要ありません. 必要なのは <tt/0xf0xxxxxx/ という部分です.
<item>システムがリブートしたら, 以下の操作を行います:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
</verb>
ここで, <tt/f0xxxxxx/ は命令ポインタ値です. カーネルシンボルの
テーブルは関数のエントリポイントを含み, 命令ポインタ値は,
関数内部のある点であり, 最初の点ではないため, この操作を行っても
完全に一致するものが表示されない場合もあります. この場合は,
最後の桁を省いてもういちどやってみてください. このようになりま
す:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxx
</verb>
これでも一致しない場合は, 桁を減らしながら何らかの出力があるま
で繰り返してください. 何か出力されたら, それがカーネルパニック
を引き起こした可能性のある関数のリストです. これは, 問題点を見付ける
正確な方法ではありませんが, 何もないよりましです.
</itemize>
<p>このようなパニックメッセージを投稿している人はよく見掛けますが,
このように, 命令ポインタ値を, カーネルシンボルテーブルの中の関数
とつき合わせて調べている人はまれです.
<p>パニックの原因を突き止める最良の方法は, クラッシュダンプをとり,
<tt/gdb(1)/ でスタックトレースを行うことです. もちろん -current
で <tt/gdb(1)/ がちゃんと動いていればですが (私は動くことを保証
できません. ELF 化された <tt/gdb(1)/ はカーネルクラッシュダンプを
正しく扱えないと言っている人がいました. 3.0 がβテストを終える前,
に調べなければいけません. さもないと CD 出荷後に大顰蹙を買うことに
なります).
<p>
どっちにしろ, 私は普通以下のようにします.
<itemize>
<item>カーネルコンフィグファイルを作ります. カーネルデバッガが
必要そうであれば options 'DDB' を加えても良いです(私は永久ルー
プが起こっていそうな場合に, ブレークポイントを設定するのに使って
います).
<item> <tt/config -g KERNELCONFIG/ としてビルドディレクトリを設
定します.
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
<item>カーネルのコンパイルが終了するのを待ちます.
<item><tt/cp kernel kernel.debug/
<item><tt/strip -d kernel/
<item><tt/mv /kernel /kernel.orig/
<item><tt>cp kernel /</tt>
<item>reboot
</itemize>
<p> <em>[注: 現在 3.0-BETA では, <tt/strip -d/ の代りに
<tt/strip -aout -d/ を使う必要があります.]</em>
<p> 全てのデバッグシンボルを含んだカーネルを, 実際にブートする必要は
<em>ありません.</em> <tt/-g/ をつけてコンパイルされたカーネルは,
簡単に 10MB 近くの大きさになってしまいます. こんな大きなカーネル
を実際にブートする必要はありません. この大きなカーネルイメージは
後で<tt/gdb(1)/を使うときにのみ必要です(<tt/gdb(1)/ がシンボル
テーブルを必要とするため). シンボルを含んだカーネルのコピーを保
存 しておき, <tt/strip -d/ を使ってシンボルを除いたカーネルを作
成して ブートします.
<p> 確実にクラッシュダンプをとるには, <tt>/etc/rc.conf</tt> を編
集して <tt/dumpdev/ を使用しているスワップパーティションに指定す
る必 要があります. こうすると <tt/rc(8)/ スクリプトから
<tt/dumpon(8)/ コマンドが実行されクラッシュダンプ機能が有効にな
ります. 手動で <tt/dumpon(8)/ コマンドを実行してもかまいませ
ん. パニックの後, クラッシュダンプは <tt/savecore(8)/ コマンドを
使用して取り出すこと ができます. <tt/dumpdev/ が
<tt>/etc/rc.conf</tt> で設定されていれ ば, <tt/rc(8)/ スクリプト
から <tt/savecore(8)/ が自動的に実行され, クラッシュダンプを
<tt>/var/crash</tt> に保存します.
<p> 注: FreeBSD のクラッシュダンプのサイズは, ふつう物理メモリサ
イズと同じです. つまり 64MB のメモリを積んでいれば, 64MB のクラッ
シュ ダンプが生成されることになります. <tt>/var/crash</tt> に十
分な空き 容量があることを確認してください. 手動で
<tt/savecore(8)/ を実行す れば, もっと空き容量のあるディレクトリ
にクラッシュダンプを保存でき ます. <tt/options MAXMEM=(foo)/ と
いう行をカーネルコンフィグファイ ルに追加することで, カーネルの
メモリ使用量を制限できます. たとえば 128MB のメモリがある場合も,
カーネルのメモリ使用量を 16MB に制限し クラッシュダンプのサイズ
も 128MB ではなく 16MB にすることができます.
<p> クラッシュダンプを取り出せたら, 以下のように <tt/gdb(1)/ を使っ
てスタックトレースをとります:
<p>
<verb>
% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
(gdb) where
</verb>
<p> 必要な情報が 1 画面に収まらないことも多いので, できれば
<tt/script(1)/ を使って出力を記録します. strip していないカーネ
ル イメージを使うことで, 全てのデバッグシンボルが参照でき, パニッ
ク の発生したカーネルのソースコードの行が表示されているはずです.
通常, 正確なクラッシュへの過程を追跡するには, 出力を最後の行から
逆方向に読まなければなりません. また <tt/gdb(1)/ を使って, 変数
や 構造体の内容を表示させ, クラッシュした時のシステムの状態を調
べられ ます.
<p> もしあなたがデバッグ狂で, 同時に別のコンピュータを利用できる
環境にあれば, <tt/gdb(1)/ をリモートデバッグに使うこともできます.
リモートデバッグを使うと, あるコンピュータ上の <tt/gdb(1)/ を使っ
て, 別のコンピュータのカーネルをデバッグできます. ブレークポイン
トの設 定, カーネルコードのステップ実行など, ふつうのプログラム
のデバッグ と変わりません. コンピュータを 2 台並べてデバッグする
チャンスには, なかなか恵まれないので, 私はまだリモートデバッグを
試したことはあり ません.
<p> <em>[Bill による注: DDB を有効にしていてカーネルがデバッガに
落ちたら, ddb のプロンプトで 'panic' と入力すれば, 強制的にパニッ
クを 起こしクラッシュダンプさせることができます. パニックの途中
で, 再び デバッガに落ちるかもしれませんが, 'continue' と入力すれ
ば, クラッシュダンプを最後まで実行させられます.]</em>
</sect>

View file

@ -1,6 +1,6 @@
<!-- $Id: hackers.sgml,v 1.4 1998-09-06 13:15:50 motoyuki Exp $ -->
<!-- $Id: hackers.sgml,v 1.5 1998-10-15 16:19:10 motoyuki Exp $ -->
<!-- The FreeBSD Japanese Documentation Project -->
<!-- Original revision: 1.4 -->
<!-- Original revision: 1.6 -->
<sect>
<heading>まじめな FreeBSD ハッカーだけの話題<label id="hackers"></heading>
@ -265,5 +265,202 @@
これらの番号を使用してください. どちらの場合であれ, ドライバに関する情報を
<tt>&lt;freebsd-hackers@FreeBSD.ORG&gt;</tt> に流して頂けると助かります.
</sect>
<sect1>
<heading>代替のディレクトリ配置ポリシー</heading>
<p>
現在使われているディレクトリの配置ポリシーは, 私が 1983 年に書い
たものから全く変更されていません. 私は当初の配置ポリシーを, オリ
ジナルの fast filesystem のために書き, まったく改定していません.
このポリシーはシリンダグループを使い尽くすのを防ぐにはうまくいき
ましたが,お気づきの方もいる通り find の動作には不適切です. ほと
んどのファイルシステムの内容は, 深さ優先検索 (ftw とも呼ばれます)
によって作られたアーカイブからレストアして作成されます. この際,
ディレクトリは,シリンダグループにまたがって配置され, 以降の深さ
優先検索を行うには考え得る限り最悪の状態になります. もし作成する
ディレクトリの総数がわかっていれば, 解決方法はあります. (総数 /
シリンダグループ数)個のディレクトリをシリンダグループごとにまと
めて作成すれば良いのです. もちろん最適なディレクトリ配置になるよ
うに, 総数を予測する方法を考えなければなりません. しかし仮にシリ
ンダグループあたりのディレクトリ数を 10 くらいの小さな数に固定し
てしまったとしても, 大幅な改善が望めるでしょう. このポリシーを用
いるべきリストア作業を, 通常の作業(おそらく既存のポリシーを使用
したほうが良いでしょう)を区別するには, 10 秒間の間に作成されたディ
レクトリを最大 10 個までまとめて単一のシリンダグループに書き込む
という手順が使えるでしょう. とにかく私の結論は, そろそろ実験
を始めて見る時期だろうということです.
<sect1>
<heading>カーネルパニックを最大限に利用する</heading>
<p>
<em>[この節は, freebsd-current <ref id="mailing" name="mailing
list"> に <url url="mailto:<wpaul@FreeBSD.ORG" name="Bill Paul">
が投稿したメールを, <url url="mailto:des@FreeBSD.ORG"
name="Dag-Erling Co&iuml;dan Sm&oslash;rgrav"> が校正し,括弧内のコ
メントを追加して引用したものです. ]</em>
<p>
<verb>
From: Bill Paul <wpaul@skynet.ctr.columbia.edu>
Subject: Re: the fs fun never stops
To: ben@rosengart.com
Date: Sun, 20 Sep 1998 15:22:50 -0400 (EDT)
Cc: current@FreeBSD.ORG
</verb>
<p>
<em>[&lt;ben@rosengart.com&gt; が以下のパニックメッセージを
投稿しました.]</em>
<verb>
> Fatal trap 12: page fault while in kernel mode
> fault virtual address = 0x40
> fault code = supervisor read, page not present
> instruction pointer = 0x8:0xf014a7e5
^^^^^^^^^^
> stack pointer = 0x10:0xf4ed6f24
> frame pointer = 0x10:0xf4ed6f28
> code segment = base 0x0, limit 0xfffff, type 0x1b
> = DPL 0, pres 1, def32 1, gran 1
> processor eflags = interrupt enabled, resume, IOPL = 0
> current process = 80 (mount)
> interrupt mask =
> trap number = 12
> panic: page fault
</verb>
<p>このようなメッセージが表示された場合, 問題が起きる状況を確認し
て, 情報を送るだけでは十分ではありません. 下線をつけた命令ポインタ
値は重要な値ですが, 残念ながらこの値は構成に依存します. つまり, こ
の値は使っているカーネルのイメージに依存するのです. もしスナップショッ
トなどの GENERIC カーネルを使っているのであれば, 他の人間が問題の
ある関数について追試をすることができますが, カスタマイズされたカー
ネルの場合は, 使っている本人にしか問題の起こった場所は特定できない
のです.
<p> 何をすれば良いのでしょう?
<itemize>
<item>命令ポインタ値をメモします. <tt/0x8:/ という部分は今回必
要ありません. 必要なのは <tt/0xf0xxxxxx/ という部分です.
<item>システムがリブートしたら, 以下の操作を行います:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxxx
</verb>
ここで, <tt/f0xxxxxx/ は命令ポインタ値です. カーネルシンボルの
テーブルは関数のエントリポイントを含み, 命令ポインタ値は,
関数内部のある点であり, 最初の点ではないため, この操作を行っても
完全に一致するものが表示されない場合もあります. この場合は,
最後の桁を省いてもういちどやってみてください. このようになりま
す:
<verb>
% nm /kernel.that.caused.the.panic | grep f0xxxxx
</verb>
これでも一致しない場合は, 桁を減らしながら何らかの出力があるま
で繰り返してください. 何か出力されたら, それがカーネルパニック
を引き起こした可能性のある関数のリストです. これは, 問題点を見付ける
正確な方法ではありませんが, 何もないよりましです.
</itemize>
<p>このようなパニックメッセージを投稿している人はよく見掛けますが,
このように, 命令ポインタ値を, カーネルシンボルテーブルの中の関数
とつき合わせて調べている人はまれです.
<p>パニックの原因を突き止める最良の方法は, クラッシュダンプをとり,
<tt/gdb(1)/ でスタックトレースを行うことです. もちろん -current
で <tt/gdb(1)/ がちゃんと動いていればですが (私は動くことを保証
できません. ELF 化された <tt/gdb(1)/ はカーネルクラッシュダンプを
正しく扱えないと言っている人がいました. 3.0 がβテストを終える前,
に調べなければいけません. さもないと CD 出荷後に大顰蹙を買うことに
なります).
<p>
どっちにしろ, 私は普通以下のようにします.
<itemize>
<item>カーネルコンフィグファイルを作ります. カーネルデバッガが
必要そうであれば options 'DDB' を加えても良いです(私は永久ルー
プが起こっていそうな場合に, ブレークポイントを設定するのに使って
います).
<item> <tt/config -g KERNELCONFIG/ としてビルドディレクトリを設
定します.
<item><tt>cd /sys/compile/KERNELCONFIG; make</tt>
<item>カーネルのコンパイルが終了するのを待ちます.
<item><tt/cp kernel kernel.debug/
<item><tt/strip -d kernel/
<item><tt/mv /kernel /kernel.orig/
<item><tt>cp kernel /</tt>
<item>reboot
</itemize>
<p> <em>[注: 現在 3.0-BETA では, <tt/strip -d/ の代りに
<tt/strip -aout -d/ を使う必要があります.]</em>
<p> 全てのデバッグシンボルを含んだカーネルを, 実際にブートする必要は
<em>ありません.</em> <tt/-g/ をつけてコンパイルされたカーネルは,
簡単に 10MB 近くの大きさになってしまいます. こんな大きなカーネル
を実際にブートする必要はありません. この大きなカーネルイメージは
後で<tt/gdb(1)/を使うときにのみ必要です(<tt/gdb(1)/ がシンボル
テーブルを必要とするため). シンボルを含んだカーネルのコピーを保
存 しておき, <tt/strip -d/ を使ってシンボルを除いたカーネルを作
成して ブートします.
<p> 確実にクラッシュダンプをとるには, <tt>/etc/rc.conf</tt> を編
集して <tt/dumpdev/ を使用しているスワップパーティションに指定す
る必 要があります. こうすると <tt/rc(8)/ スクリプトから
<tt/dumpon(8)/ コマンドが実行されクラッシュダンプ機能が有効にな
ります. 手動で <tt/dumpon(8)/ コマンドを実行してもかまいませ
ん. パニックの後, クラッシュダンプは <tt/savecore(8)/ コマンドを
使用して取り出すこと ができます. <tt/dumpdev/ が
<tt>/etc/rc.conf</tt> で設定されていれ ば, <tt/rc(8)/ スクリプト
から <tt/savecore(8)/ が自動的に実行され, クラッシュダンプを
<tt>/var/crash</tt> に保存します.
<p> 注: FreeBSD のクラッシュダンプのサイズは, ふつう物理メモリサ
イズと同じです. つまり 64MB のメモリを積んでいれば, 64MB のクラッ
シュ ダンプが生成されることになります. <tt>/var/crash</tt> に十
分な空き 容量があることを確認してください. 手動で
<tt/savecore(8)/ を実行す れば, もっと空き容量のあるディレクトリ
にクラッシュダンプを保存でき ます. <tt/options MAXMEM=(foo)/ と
いう行をカーネルコンフィグファイ ルに追加することで, カーネルの
メモリ使用量を制限できます. たとえば 128MB のメモリがある場合も,
カーネルのメモリ使用量を 16MB に制限し クラッシュダンプのサイズ
も 128MB ではなく 16MB にすることができます.
<p> クラッシュダンプを取り出せたら, 以下のように <tt/gdb(1)/ を使っ
てスタックトレースをとります:
<p>
<verb>
% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
(gdb) where
</verb>
<p> 必要な情報が 1 画面に収まらないことも多いので, できれば
<tt/script(1)/ を使って出力を記録します. strip していないカーネ
ル イメージを使うことで, 全てのデバッグシンボルが参照でき, パニッ
ク の発生したカーネルのソースコードの行が表示されているはずです.
通常, 正確なクラッシュへの過程を追跡するには, 出力を最後の行から
逆方向に読まなければなりません. また <tt/gdb(1)/ を使って, 変数
や 構造体の内容を表示させ, クラッシュした時のシステムの状態を調
べられ ます.
<p> もしあなたがデバッグ狂で, 同時に別のコンピュータを利用できる
環境にあれば, <tt/gdb(1)/ をリモートデバッグに使うこともできます.
リモートデバッグを使うと, あるコンピュータ上の <tt/gdb(1)/ を使っ
て, 別のコンピュータのカーネルをデバッグできます. ブレークポイン
トの設 定, カーネルコードのステップ実行など, ふつうのプログラム
のデバッグ と変わりません. コンピュータを 2 台並べてデバッグする
チャンスには, なかなか恵まれないので, 私はまだリモートデバッグを
試したことはあり ません.
<p> <em>[Bill による注: DDB を有効にしていてカーネルがデバッガに
落ちたら, ddb のプロンプトで 'panic' と入力すれば, 強制的にパニッ
クを 起こしクラッシュダンプさせることができます. パニックの途中
で, 再び デバッガに落ちるかもしれませんが, 'continue' と入力すれ
ば, クラッシュダンプを最後まで実行させられます.]</em>
</sect>