SYNOPSIS
--------
jdb does not immediately kill the debuggee process when quitting at a breakpoint
OPERATING SYSTEMS
-----------------
Solaris and Linux
Not reproducible on Windows
FULL JDK VERSIONS
-----------------
All, including latest Java 7 (1.7.0_02)
PROBLEM DESCRIPTION from LICENSEE
---------------------------------
Run the attached test class inside the Java Debugger, after defining a breakpoint at line 4 (the println() inside the for loop).
As expected, execution stops at the first call to println(). We can then continue, and the execution stops in each iteration. However, if we quit the debugger when stopped at one of these breakpoints, the Test class starts running again before being killed shortly afterwards, rather than being stopped immediately without any further execution.
This behaviour only occurs on Solaris and Linux. On Windows, when we quit jdb while stopped at a breakpoint the target process dies immediately, with no further execution (there is, at least, no further output from the Test class).
Imagine the following use case:
1. On a production system, a database becomes corrupt and is restored
from backup (several hours work)
2. On restart, the corruption occurs again (and the database is, again,
restored from backup)
3. Support staff start the application using jdb (this is a production
system so normal debugging tools are not installed), setting a
breakpoint immediately before the database commit
4. The problem is identified using the debugger, and the engineer quits
jdb while stopped at the breakpoint, before the commit
5. Application starts running again for a moment, completes the commit
and corrupts the database again, triggering several more hours of
unecessary restoration work...
TESTCASE
--------
public class Test {
public static void main (String args[]) {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}
REPRODUCTION INSTRUCTIONS
-------------------------
1. javac Test.java
2. jdb Test
3. > stop at Test:4
4. > run Test
5. > cont
6. > cont
7. > quit
Expected behaviour (Windows):
------------------------------------------------------------------------
C:\>jdb Test
Initializing jdb ...
> stop at Test:4
Deferring breakpoint Test:4.
It will be set after the class is loaded.
> run Test
run Test
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint Test:4
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
> 0
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
1
>
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] quit
------------------------------------------------------------------------
Observed behaviour (Solaris/Linux):
------------------------------------------------------------------------
bash-3.00$ jdb Test
Initializing jdb ...
> stop at Test:4
Deferring breakpoint Test:4.
It will be set after the class is loaded.
> run Test
run Test
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint Test:4
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
> 0
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
1>
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] quit
2
3
4
5
6
7
8
9
Fatal error:
Failed reading output of child java interpreter.
------------------------------------------------------------------------
WORKAROUND
----------
None
--------
jdb does not immediately kill the debuggee process when quitting at a breakpoint
OPERATING SYSTEMS
-----------------
Solaris and Linux
Not reproducible on Windows
FULL JDK VERSIONS
-----------------
All, including latest Java 7 (1.7.0_02)
PROBLEM DESCRIPTION from LICENSEE
---------------------------------
Run the attached test class inside the Java Debugger, after defining a breakpoint at line 4 (the println() inside the for loop).
As expected, execution stops at the first call to println(). We can then continue, and the execution stops in each iteration. However, if we quit the debugger when stopped at one of these breakpoints, the Test class starts running again before being killed shortly afterwards, rather than being stopped immediately without any further execution.
This behaviour only occurs on Solaris and Linux. On Windows, when we quit jdb while stopped at a breakpoint the target process dies immediately, with no further execution (there is, at least, no further output from the Test class).
Imagine the following use case:
1. On a production system, a database becomes corrupt and is restored
from backup (several hours work)
2. On restart, the corruption occurs again (and the database is, again,
restored from backup)
3. Support staff start the application using jdb (this is a production
system so normal debugging tools are not installed), setting a
breakpoint immediately before the database commit
4. The problem is identified using the debugger, and the engineer quits
jdb while stopped at the breakpoint, before the commit
5. Application starts running again for a moment, completes the commit
and corrupts the database again, triggering several more hours of
unecessary restoration work...
TESTCASE
--------
public class Test {
public static void main (String args[]) {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}
REPRODUCTION INSTRUCTIONS
-------------------------
1. javac Test.java
2. jdb Test
3. > stop at Test:4
4. > run Test
5. > cont
6. > cont
7. > quit
Expected behaviour (Windows):
------------------------------------------------------------------------
C:\>jdb Test
Initializing jdb ...
> stop at Test:4
Deferring breakpoint Test:4.
It will be set after the class is loaded.
> run Test
run Test
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint Test:4
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
> 0
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
1
>
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] quit
------------------------------------------------------------------------
Observed behaviour (Solaris/Linux):
------------------------------------------------------------------------
bash-3.00$ jdb Test
Initializing jdb ...
> stop at Test:4
Deferring breakpoint Test:4.
It will be set after the class is loaded.
> run Test
run Test
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint Test:4
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
> 0
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] cont
1>
Breakpoint hit: "thread=main", Test.main(), line=4 bci=8
4 System.out.println(i);
main[1] quit
2
3
4
5
6
7
8
9
Fatal error:
Failed reading output of child java interpreter.
------------------------------------------------------------------------
WORKAROUND
----------
None