凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 6847
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

いらっしゃいませ。
某国産の食品の品質がいろいろといわれた昨今ですが、やはり、流通路というか出自というのは重要な情報ですよね。
なお、当店の素材はできるだけ本家の厳選された素材に基づくようにしております。

スタックトレースでの追跡

デバッグの際に非常に役立つスタックトレース。活用していますか?
これはスレッドの流れを示しています。いわば流通路のようなものです。

メソッドに不正な引数が渡された場合、この流通路を遡ればどこの誰がばったもんを流したのか調査することが出来ます。犯人を見つけたらとっちめてやりましょう。

しかし、キャッシュされるオブジェクトや、staticフィールドに保持されるオブジェクトなどスレッドの流れとは一旦隔絶される場合、トレースを追いかけても犯人をつかめないことがあります。

    /** Object置き場。ここに置いたのを処理する */
    private Object object;

    /** 置き場にObjectを置く */
    public void setObject(Object object) {
        this.object = object;
    }

    /** 置き場のデータを処理するメソッド */
    public void hoge() {
        Object o = this.object;
        // 置き場にあるデータを使って処理を進める
        // ...
    }

このコードではhoge()メソッドの呼び出しに直接手渡しでオブジェクトが渡されるわけではありません。そのため、何時どこで誰がObject置き場にデータを置いたのか、スタックトレースからは追いかけることができません。

オブジェクトの出自

このスタックトレース、プログラムで扱うことができるようになっています。 Thread#getStackTrace()で対象スレッドの現時点でのスタックトレースを取得することが出来ます。
オブジェクトの生成時にこれをとっておいたらどうでしょうか?

    /** インスタンス生成時のスタックトレース */
    private StackTraceElement[] createLog;

    /** コンストラクタ */
    public TraceTest() {
        // カレントスレッドからスタックトレースを取得
        this.createLog = Thread.currentThread().getStackTrace();
    }

このように、オブジェクトにスタックトレースの保管フィールドを用意し、コンストラクタの時点でスタックトレースをとっておきます。
すると、デバッグ時にオブジェクトの作られた場所が分かるという寸法です。

いかがでしょうか。これでデバッグの効率が上がると思いませんか?

環境ごとの注意点

Thread#getStackTrace()はJavaSE5.0からのサポートです。
JDK1.4の場合はExceptionをnewして生成したExceptionからgetStackTrace()してやることで同様の効果を得られます。

StackTraceElementクラスがJDK1.4からのサポートなので、JDK1.3以前の場合はExceptionをnewして printStackTrace(PrintStream)を利用し、ByteArrayOutputStreamか何かに繋げた PrintStreamを作成してそこにトレースを書き出すという手法を使います。文字列情報になってしまいますが、デバッグには十分でしょう。

なお、C#でもほぼ同等のことができるようですね。具体的なやり方は…誰かが書いてくれることを期待しましょう。

投稿日時 : 2007年8月20日 12:04
コメント
  • # re: Objectよ、汝の出自を示せ
    かつのり
    Posted @ 2007/08/20 13:26
    ThreadとThrowableでは微妙に帰ってくるスタックトレースの配列が違うので、
    微妙に使いにくい感じがして、ちょっと困っています。

    スタックトレースももうちょっとオーバーロードを意識してくれるとうれしいのですが、
    コレばっかりは文句も言えない・・・
  • # re: Objectよ、汝の出自を示せ
    凪瀬
    Posted @ 2007/08/20 14:25
    トレース自体がVMに依存するところだったと記憶しています。
    あんまり挙動を決め打ちして処理を書いちゃいけないトコロじゃなかったかな。
    トレースは人間にプレゼンする以上の使い方しちゃ駄目でしょう。

    言語でnewについての情報をサポートしてくれるといいのですけども。
    大阪でとっちゃんと話をしていて、C++だと確保したメモリのアドレスがわかるから、まだnewの位置を探査しやすいというような話を聞きましたが。
    デバッグ情報としては有用だと思うんだけどなー。
  • # NETのObjectのトレーサビリティ
    むらぶろ - .NETって面白い -
    Posted @ 2007/09/10 12:37
    NETのObjectのトレーサビリティ
  • # NETのObjectのトレーサビリティ
    むらぶろ - .NETって面白い -
    Posted @ 2007/09/10 12:39
    NETのObjectのトレーサビリティ
  • # re: OOPでシステム内のオブジェクトのアクセス権を管理する
    凪瀬 Blog
    Posted @ 2008/05/14 17:34
    re: OOPでシステム内のオブジェクトのアクセス権を管理する
  • # I recokn you are quite dead on with that.
    Wimpy
    Posted @ 2012/01/28 19:47
    I recokn you are quite dead on with that.
  • # I recokn you are quite dead on with that.
    Wimpy
    Posted @ 2012/01/28 19:47
    I recokn you are quite dead on with that.
タイトル  
名前  
Url
コメント