- PR -

core_uses_pid=0でもcore.%pになる

1
投稿者投稿内容
raccoon
ベテラン
会議室デビュー日: 2002/12/18
投稿数: 58
投稿日時: 2004-05-14 20:33
ども。raccoonといいます。
sysctlのcore_uses_pidの設定について質問があります。

core_uses_pid=0に設定すると,シングルスレッドで動作している
プロセスが出すcoreファイルの名称はちゃんと'core'になりますが,
マルチスレッドで動作しているプロセスが出すcoreファイルの名称は
core.%pのようにPIDがついてしまいます。

manを見てもネットで検索して調べても,core_uses_pid=0が
プロセスのシングル/マルチスレッドに影響を受けるようには
思えないのですが・・・。

マルチスレッドのプロセスからのcoreファイル名にPIDが
つかなくする方法はないのでしょうか?
あるいは,普通(他のバージョンやディストリビューション)は
こういうことは起こらないのでしょうか?


[当方動作環境]
Red Hat Enterprise Linux AS release 3 (Taroon)
Kernel 2.4.21-9.ELsmp on an i686

[/sbin/sysctl -a実行結果からの抜粋]
kernel.core_pattern = core
kernel.core_uses_pid = 0
はゆる
ぬし
会議室デビュー日: 2004/02/16
投稿数: 1008
お住まい・勤務地: 首都圏をウロウロと
投稿日時: 2004-05-17 13:06
こんにちは〜。

コアダンプ周りは詳しくないのですが(汗)、気になったのでちょっと調べてみました。
core_uses_pid が 0 であれば PID は付かなくなるハズなのですが… core_pattern ?
そんなパラメータあったっけ?と調べてみましたところ、 kernel 2.5 系から加わったもののようです。
ちなみに、近くにある kernel 2.4.18 な Linux を調べましたところ、core_pattern パラメータはありませんでした。
(いつごろから追加されたんだろ?)

どうして PID が付いてしまうのかは、ソースを追ってみないと分からないと思うのですが…(って、私は追えない・苦笑) Red Hat のサポセンに問い合わせてみてはいかがでしょうか。
参考になるようなレスでなくてすいません(苦笑)。

※ 参考:
 ・ Manpage of PROC (JM)
 ・ @IT:-procによるLinuxチューニング [後編](4-4) ←こっちは 2.4 系のみを解説
raccoon
ベテラン
会議室デビュー日: 2002/12/18
投稿数: 58
投稿日時: 2004-05-18 16:26
ども。はゆるさん,レスありがとうございます。
# & こちらのレス遅くてスミマセン。m(_ _)m

> core_pattern ? そんなパラメータあったっけ?
> と調べてみましたところ、 kernel 2.5 系から加わったもののようです。

ホントだ。core_patternはKernel 2.5からですね。ということは,

『RedHat AS 3.0は,2.4ベースにいくつか2.5以降の機能を
取り込んでいいて,その影響で期待と異なる動作が出た』

と推測することができますね。
# そういえば,マルチスレッドプロセス(=スレッドグループ)管理
# のあたりでは,他にもアヤシイ動きが見られるんです。
# そのあたりがクサイかな?

> どうして PID が付いてしまうのかは、ソースを追ってみないと
> 分からないと思うのですが…
うっ。それはおっしゃるとおり。(大汗;;)
こういうのを機会に勉強するべきなんでしょうが・・・。(さらに汗;;;;)


# 仕事的には結局,core.%pでも大丈夫なようにプログラムを
# 直すことになりそうです。(ちょっと面倒ですが)
# 個人的には原因を掴んでおきたいところですが・・・
# でも,はゆるさんのおかげで推定原因が見えてたので,
# だいぶスッキリしました。ありがとうございました。

t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2004-05-19 17:49
kernek2.4.7、2.4.25でもマルチスレッドだとPIDが付きますね。
普段PIDをつける方に設定してたんで全然しりませんでした。

ソースは、fs/exec.cを見ると分かります。kernel2.4.26では、

1093 if (!pid_in_pattern
1094 && (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
1095 rc = snprintf(out_ptr, out_end - out_ptr,
1096 ".%d", current->pid);
1097 if (rc > out_end - out_ptr)
1098 goto out;
1099 out_ptr += rc;
1100 }

こんな感じです。(先頭の数字は行番号)

ここから先は予想ですが、マルチスレッドの場合、多分
atomic_read(&current->mm->mm_users) != 1
これがtrueになるのでしょう。
これは、恐らく(名前から予想して)1回の操作でメモリを読み込めるかどうか
を示しているのだと思います。
アトミックに読み込めない場合、coreを書いている途中で、別のプロセスがcore
ダンプする可能性があり、同一ファイルに書き込まれる恐れがあるためcoreが壊れ
ないようPIDを付加しているのだと考えます。

ちなみに、kernel 2.4.20辺りのfs/exec.c#do_coredumpを読んだほうが分かりやすいです。(patternをサポートしていないので、coreファイルの名前の付け方が良く分かる)

[ メッセージ編集済み 編集者: t-wata 編集日時 2004-05-19 17:54 ]
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2004-05-20 01:09
# カーネルのことはほとんど知らないのですが...

current という名前は現在のプロセスの管理情報をかかえている
task_struct 構造体によく使われるので、それだと思います。
そいつの定義をみればわかりますが、mm は そのプロセスの(ユーザ)
メモリを管理している mm_struct へのポインタで、mm_struct の
定義を行っているヘッダをみると mm_users のところには「この
メモリを共有している user の数」とかゆーコメントがあります。
user ってのはユーザ空間のことかしら? 
ともかく、マルチスレッドでメモリを共有している場合には、
mm_users の値がスレッドの個数になるかと。

atomic_read を使ってるのは... 「32ビットのデータを読み込むのを
16ビットずつ2回に分けて行う」というようなアーキテクチャのマシン
においても、いま必要としているデータがアトミック操作として
読まれることを保証するためにやっていることかと思います。
# 前半16ビットを読んだ後、後半16ビットを読む前に値が書き換えられる、
# というような事態を防ぐため。

[ メッセージ編集済み 編集者: ぽんす 編集日時 2004-05-20 01:12 ]
raccoon
ベテラン
会議室デビュー日: 2002/12/18
投稿数: 58
投稿日時: 2004-05-21 23:05
t-wataさん,ぽんすさん,ありがとうございます。
# あいかわらず遅レスで申し訳ないです・・・


「他にこのメモリを使用している人がいたら,core_uses_pid==0
であってもcoreファイル名にはPIDがつく」

という作りになっているのですね。マルチスレッドプロセスでは
まだ他のスレッドがいるために(mm_users != 1)になり,
常にcore.PIDになるのかな?
# 詳しくソースを追うのは時間がかかりそうので,
# 今のところはこんなレベルでゴカンベンを・・・


ところで,
/etc/sysctl.confのcore_uses_pidのところには
こんなコメントがついています。(RedHatだけかも)

コード:
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1



また,はゆるさんに紹介していただいた@ITの記事ではこう説明されています。
コード:
core_uses_pid
コアダンプ作成時に、「core.1234」のようにPID付きの形式を使用するかどうかを指定します。
coreファイルの区別が簡単になると同時に、マルチスレッド、マルチプロセスのプログラムを
デバッグする際に、古いcoreが上書きされないという利点があります




これらを読むと,
「マルチスレッドプログラムでは,coreファイル名にPIDがつくと便利なので,
core_uses_pidの値に関わらず常にPIDをつけるようにしている」
というふうに見受けられるのですが・・・
ただ,実際にマルチスレッドプロセスでcoreファイル名にPIDがつくことにより
恩恵を受けるには,次の2つの条件が必要なはずです。

(1)coreを出力後(または出力中)でも,他のスレッドからcoreを出力できる。
(2)coreにつくPIDはスレッド毎に異なる。


実際には(1)については,coreは1プロセスから1つしか出力されません。
t-wataさんに教えていただいた,fs/exec.c#do_coredump()のソースからも
たぶんそうでしょう。(ごく一部のソースしか見ていないので弱気)
コード:
    948     if (!current->mm->dumpable)
    949         goto fail;
    950     current->mm->dumpable = 0;



(2)についても実験してみましたが,どのスレッドからcore dumpしても,
coreファイルにつくPIDは同じでした。


ということで,なぜこんな作りになっているかの理由はナゾ・・・

今後,mm_usersがどのようにカウントアップ/ダウンされるのかとか,
その辺のソースを追ってみたいと思います。
# 時間かかりそうだなぁ。でもいいや。
# 結局,自分のプログラムをcore.PIDでも耐えられるように
# 修正しちゃったので,仕事的には解決済みだから。

1

スキルアップ/キャリアアップ(JOB@IT)