3

附加到 sbt 时,我无法让断点在 jdb 中命中。我编写了以下 scala 代码,并将其放在一个名为 test.scala 的文件中:

object test extends App {
  def foo(x: Int): Int = {
    print(".")
    Thread.sleep(100)
    x
  }  

  println("started")
  List.range(1, 100).foreach { a =>
    foo(a)
  } 
  println("done")
} 

然后,在包含 test.scala 的目录中,我启动 sbt 并运行程序一次以确保一切正常。

sbt -jvm-debug 5005
> run

在另一个终端(相同的目录)中,我启动 jdb:

jdb -attach 5005
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
> stop in test.foo
Set breakpoint test.foo
> stop in test$.foo
Set breakpoint test$.foo
> stop at test.scala:3
Deferring breakpoint test.scala:3.
It will be set after the class is loaded.

然后在 sbt 中输入 'run',程序就不停的完成了。但是,jdb 似乎对能够设置断点的代码了解得足够多。当我再次运行,但用“挂起”中断 jdb 中的所有线程时,我可以查看“线程”的输出:

jdb> threads
Group system:
  (java.lang.ref.Reference$ReferenceHandler)0x1627 Reference Handler cond. waiting
  (java.lang.ref.Finalizer$FinalizerThread)0x1626  Finalizer         cond. waiting
  (java.lang.Thread)0x1625                         Signal Dispatcher running
Group main:
  (java.lang.Thread)0x1628                         main              cond. waiting
  (java.lang.Thread)0x162a                         pool-4-thread-1   cond. waiting
  (java.lang.Thread)0x162b                         pool-4-thread-2   cond. waiting
  (java.lang.Thread)0x162c                         pool-4-thread-3   cond. waiting
  (java.lang.Thread)0x162d                         pool-4-thread-4   cond. waiting
  (java.lang.Thread)0x162e                         pool-4-thread-5   cond. waiting
  (java.lang.Thread)0x162f                         pool-4-thread-6   cond. waiting
Group run-main-group-2:
  (java.lang.Thread)0x1630                         run-main-2        sleeping

选择运行测试的线程:

jdb> thread 0x1630
run-main-2[1] where
[1] java.lang.Thread.sleep (native method)
[2] test$.foo (test.scala:4)
...

run-main-2[1] step up
> 
Step completed: "thread=run-main-2", test$.foo(), line=5 bci=14
run-main-2[1] class test
Class: test
extends: java.lang.Object
nested: test$
...

run-main-2[1] methods test
** methods list **
test main(java.lang.String[])
test delayedInit(scala.Function0)
test args()
test scala$App$_setter_$executionStart_$eq(long)
test executionStart()
test foo(int)

因此,jdb 似乎知道我的代码中的类和方法名称以及行号,但不会在断点处停止。如果我在不存在的函数上设置断点,我会得到:

> stop in test.whatever
Unable to set breakpoint test.whatever : No method whatever in test

表明它确实理解 test.foo 处的断点?对于 test.foo 或 test$.foo,我是否使用 stop in、on 或 at 都没有关系。从谷歌搜索其他问题看来,我的方法名称很可能是错误的,但我不知道那会是什么。

我希望能够在我现有的开发设置中添加一些简单的调试,而无需切换到 Eclipse 或 IntelliJ。我做错了什么或根本没有做错,或者没有简单的方法可以完成这项工作?

版本信息:

  • Linux:Ubuntu 12.04.4 LTS(精确)
  • jdb:1.6(Java SE 版本 1.6.0_31)
  • sbt:0.13.5
  • 斯卡拉:2.10.4
  • java版本“1.6.0_31”
    • OpenJDK 运行环境 (IcedTea6 1.13.3) (6b31-1.13.3-1ubuntu1~0.12.04.2)
    • OpenJDK 64 位服务器 VM(内部版本 23.25-b01,混合模式)
4

0 回答 0