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

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

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

![スクリーンショット_2014_07_20_23_05.png](https://qiita-image-store.s3.amazonaws.com/0/94/00de1f9d-f8a9-94d2-6a16-fb248c9ccd6b.png)

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

```scala
package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()
  }

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

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

  }
}
```

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

```scala
package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()
  }

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

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

  }
}
```

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

```scala
package com.sample

object DebuggerSample extends App {

  foo()

  def foo() = {
    bar()
  }

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

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

  }
}
```

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

```scala
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の場合は、設定を無視してスキップせずに実行出来る。

参考

* [IntelliJ IDEA 2016.3 Help :: Stepping Through the Program](https://www.jetbrains.com/help/idea/2016.3/stepping-through-the-program.html)

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

```scala
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等した場合、変数の値によっては通るパスが変わることがある。

参考

* [debugging - When using the Java debugger in Intellij what does "Drop Frame" mean? - Stack Overflow](http://stackoverflow.com/questions/2367816/when-using-the-java-debugger-in-intellij-what-does-drop-frame-mean)

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

```scala
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って言うやつもあるっぽい。](http://www.jetbrains.com/idea/features/compiler.html#link24)

# 参考
再掲含む。

* [debugging - When using the Java debugger in Intellij what does "Drop Frame" mean? - Stack Overflow](http://stackoverflow.com/questions/2367816/when-using-the-java-debugger-in-intellij-what-does-drop-frame-mean)
* [javascript - What is step into, step out and step over in Firebug? - Stack Overflow](http://stackoverflow.com/questions/5391684/what-is-step-into-step-out-and-step-over-in-firebug)
* [Debugger. Stepping](http://www.jetbrains.com/idea/webhelp/debugger-stepping.html)