Help us understand the problem. What is going on with this article?

IntelliJ IDEAのデバッガのstep over, step into, force step into, step out, drop frame, run to cursor 機能の解説

概要

IntelliJのデバッガ使いこなせてなかったから調べたのを共有。割とぐぐってすぐ出てこなかったし。

ここのボタン押したらどうなるか、って話。

スクリーンショット_2014_07_20_23_05.png

前提

例として以下のプログラムを使う。コメント入れてあるところにブレイクポイントをセットして、そこで止まった時の話をする。

package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()
  }

  def bar() = {
    buz()  // ここにブレイクポイントをセット
    buz()
  }

  def buz() = {
    println("Hello World!")

  }
}

step over

step overを実行すると、次の行に移動する。つまり

package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()
  }

  def bar() = {
    buz()  // ここにブレイクポイントをセット
    buz()  // ***ここにくる***
  }

  def buz() = {
    println("Hello World!")

  }
}

step into

step intoを実行すると、その行で実行してる関数に移動する。つまり

package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()
  }

  def bar() = {
    buz()  // ここにブレイクポイントをセット
    buz()
  }

  def buz() = {
    println("Hello World!")  // ***ここにくる***

  }
}

step out

step outを実行すると、その行を含む関数を呼び出しているところまで移動する。つまり

package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()  // ***ここにくる***
  }

  def bar() = {
    buz()  // ここにブレイクポイントをセット
    buz()
  }

  def buz() = {
    println("Hello World!")

  }
}

ここまでは多分IntelliJとか関係なくどんなデバッガでも大抵ある機能のような気がする(あんまりデバッガ使ったことないから分からんけど)

force step into

step intoはcom.sum.*java.*、他にもコンストラクタ関数や、クラスローダなどのどうでもいいところまで見ないといけないところをスキップする設定がある。(Preferences->Build Excecution, Deployment->Debugger->Steppingで変更可能)
force step intoの場合は、設定を無視してスキップせずに実行出来る。

参考

drop frame

drop frameを実行すると、call stackを遡る。つまり、

package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()  // ***ここにくる***
  }

  def bar() = {
    buz()  // ここにブレイクポイントをセット
    buz()
  }

  def buz() = {
    println("Hello World!")

  }
}

これだけ見るとstep outと同じようにみえるが、step outの場合はbar()が実行された後で、drop frameの場合はbar()を呼び出す前であることに注意。

ちなみに、drop frameによって外れたscope(例の場合def bar()のscope)の変数はリセットされるが、外れないscope内の変数の値は現状維持になる。つまり、drop frameしたあとにstep into等した場合、変数の値によっては通るパスが変わることがある。

参考

run to cursor

カーソルがあるところで止まる。要はカーソルがお手軽ブレイクポイントになる。例えばprintlnのところにカーソルがあったらそこで止まる。今の例だとstep intoと同じになる。

package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()
  }

  def bar() = {
    buz()  // ここにブレイクポイントをセット
    buz()
  }

  def buz() = {
    println("Hello World!")  // ***カーソルがここにあったらここに来る***

  }
}

カーソルがあるところを通らない場合はresume programと同じになる。

補足

自分がscala使ってるからscalaの例だけど他の言語でも同じはず。
あとIntelliJ IDEAのバージョンが違うとdrop frameはpop frameって言うやつもあるっぽい。

参考

再掲含む。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away