I am having trouble getting my breakpoints to hit in jdb when attaching to sbt. I wrote the following scala code, and put it in a file called 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")
}
Then, in the dir containing test.scala, I start sbt and run the program once to make sure everything is working ok.
sbt -jvm-debug 5005
> run
In another terminal (same dir), I start 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.
Then type 'run' in sbt, and the program completes without stopping. However, jdb seems to know enough about the code to be able to set a breakpoint. When I run again, but interrupt all threads in jdb with 'suspend' I can look at the output of 'threads':
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
Select the thread running the test:
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)
So, jdb appears to know about the class and method names as well as the line numbers in my code, but does not stop at the breakpoints. If I set a breakpoint on a function that doesn't exist, I get:
> stop in test.whatever
Unable to set breakpoint test.whatever : No method whatever in test
Indicating that it does understand a breakpoint at test.foo ? It does not matter whether I use stop in, on or at for test.foo or test$.foo. From googling other questions it seems most likely that I have the method name wrong, but I wouldn't know what it would have to be then.
I was hoping to be able to add some simple debugging to my existing development setup without having to switch to Eclipse or IntelliJ. Is there something I am doing wrong or not at all, or is there no easy way to make this work?
Version information:
- Linux: Ubuntu 12.04.4 LTS (precise)
- jdb: 1.6 (Java SE version 1.6.0_31)
- sbt: 0.13.5
- scala: 2.10.4
- java version "1.6.0_31"
- OpenJDK Runtime Environment (IcedTea6 1.13.3) (6b31-1.13.3-1ubuntu1~0.12.04.2)
- OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)