-
Bug
-
Resolution: Cannot Reproduce
-
P3
-
5.0
-
generic
-
solaris_8
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2113651 | 6-pool | Unassigned | P3 | Closed | Won't Fix |
New code sequences first introduced in 1.4.x inlines some finally clauses.
Apparently this confuses some debuggers (both tools and people), which used to
expect the "ret" instruction to be considered part of the "return" statement.
This can easily be fixed in javac by inserting a line number table
entry following the inlined finalizer.
Enclosed is part of a newsgroup conversation regarding this issue.
Reply-To: "Chris Uppal" <###@###.###>
Wrom: IYZUNNYCGPKYLEJGDGVCJVTLBXFGGMEPYOQKEDOTWFAOBUZXU
Newsgroups: comp.lang.java.programmer
References: <bt9a48$4g57n$###@###.###> <ezXJb.16795$###@###.###> <btbg2u$5bg5q$###@###.###> <3ff9643d$0$61071$###@###.###> <###@###.###> <###@###.###>
Subject: Re: optimizing java compiler
Date: Tue, 6 Jan 2004 09:08:54 -0000
Xref: typhoon.sonic.net comp.lang.java.programmer:574466
Neal Gafter wrote:
> This isn't an optimization, it is simply an improved code generation
> strategy. Why would you expect the debugger to go back to the return
> statement? This is the first I've heard of someone being unhappy with
> the new code sequence.
I'm hesitant to mention this because I woudn't like to seem that I'm suggesting
that this is in any way your fault or your problem, but the new code sequences
have broken a few previously useful tools.
For instance neither Jlint 2.3 nor JAD 1.5.8e2 will cope with the result of
compiling either of the two appended classes with a 1.4.2 compiler. Perhaps
the same code sequences will cause problems for other tools too.
(I'd have emailed bug reports to the authors but I don't have an address for
JAD, and I'm not sure that Jlint is actively maintained.)
-- chris
========================
import java.io.*;
class BreakJlintAndJAD
{
public boolean
save(String filename)
{
ObjectOutputStream out = null;
try
{
out = new ObjectOutputStream(new FileOutputStream(filename));
out.writeObject(new Object());
}
catch (Exception e)
{
return false;
}
finally
{
try
{
if (out != null)
out.close();
}
catch (IOException e)
{
return false;
}
}
return true;
}
}
class BreakJlintAndJADAnotherWay
{
Object read()
throws IOException, ClassNotFoundException
{
ObjectInputStream in = null;
try
{
in = new ObjectInputStream(new FileInputStream("tmp"));
return in.readObject();
}
finally
{
if (in != null)
in.close();
}
}
}
=====================================================
From the submitter:
> Is that possible in the case of nested
> try/catch/finally when both finallys are
> inlined?
> Granted, most programmers would have no
> problem with this sequence. We were using a
> debugger to demonstrate sequence of operations
> with nested try/catch/finally to first-year
> students in a class lecture. If the current
> line jumps from the inner finally directly to
> the outer, this is confusing to students,
> especially if the exit point has scrolled off
> the page. Even with a non-nested finally, it
> is less clear if control does not return to
> the return, continue, or break after the finally
> block.
From the evaluator:
For the case of nested finally clauses, it is possible but probably something I would not want to do. The way to do it would be to generate a "nop" instruction between the finalizers with a line number table entry pointing to the return statement.
From the submitter:
I think it is more clear to go back to the
exit, as a reminder of the type and target of
the exit. Since this is how a non-inlined finally
behaves, it would also be more consistent. For
in-class demos, we are now just putting enough
code in the finalizers to avoid the inlining.
=====================================================
Here is one that could be a bit confusing. When
stepping, control goes from the if-statement
directly to the finalizer without ever hitting
the return statement.
try {
for(int i = 0; i < 3; i++) {
if(i != 1)
;
else
return;
}
}
finally {
System.out.println("finally");
}
=====================================================
Apparently this confuses some debuggers (both tools and people), which used to
expect the "ret" instruction to be considered part of the "return" statement.
This can easily be fixed in javac by inserting a line number table
entry following the inlined finalizer.
Enclosed is part of a newsgroup conversation regarding this issue.
Reply-To: "Chris Uppal" <###@###.###>
Wrom: IYZUNNYCGPKYLEJGDGVCJVTLBXFGGMEPYOQKEDOTWFAOBUZXU
Newsgroups: comp.lang.java.programmer
References: <bt9a48$4g57n$###@###.###> <ezXJb.16795$###@###.###> <btbg2u$5bg5q$###@###.###> <3ff9643d$0$61071$###@###.###> <###@###.###> <###@###.###>
Subject: Re: optimizing java compiler
Date: Tue, 6 Jan 2004 09:08:54 -0000
Xref: typhoon.sonic.net comp.lang.java.programmer:574466
Neal Gafter wrote:
> This isn't an optimization, it is simply an improved code generation
> strategy. Why would you expect the debugger to go back to the return
> statement? This is the first I've heard of someone being unhappy with
> the new code sequence.
I'm hesitant to mention this because I woudn't like to seem that I'm suggesting
that this is in any way your fault or your problem, but the new code sequences
have broken a few previously useful tools.
For instance neither Jlint 2.3 nor JAD 1.5.8e2 will cope with the result of
compiling either of the two appended classes with a 1.4.2 compiler. Perhaps
the same code sequences will cause problems for other tools too.
(I'd have emailed bug reports to the authors but I don't have an address for
JAD, and I'm not sure that Jlint is actively maintained.)
-- chris
========================
import java.io.*;
class BreakJlintAndJAD
{
public boolean
save(String filename)
{
ObjectOutputStream out = null;
try
{
out = new ObjectOutputStream(new FileOutputStream(filename));
out.writeObject(new Object());
}
catch (Exception e)
{
return false;
}
finally
{
try
{
if (out != null)
out.close();
}
catch (IOException e)
{
return false;
}
}
return true;
}
}
class BreakJlintAndJADAnotherWay
{
Object read()
throws IOException, ClassNotFoundException
{
ObjectInputStream in = null;
try
{
in = new ObjectInputStream(new FileInputStream("tmp"));
return in.readObject();
}
finally
{
if (in != null)
in.close();
}
}
}
=====================================================
From the submitter:
> Is that possible in the case of nested
> try/catch/finally when both finallys are
> inlined?
> Granted, most programmers would have no
> problem with this sequence. We were using a
> debugger to demonstrate sequence of operations
> with nested try/catch/finally to first-year
> students in a class lecture. If the current
> line jumps from the inner finally directly to
> the outer, this is confusing to students,
> especially if the exit point has scrolled off
> the page. Even with a non-nested finally, it
> is less clear if control does not return to
> the return, continue, or break after the finally
> block.
From the evaluator:
For the case of nested finally clauses, it is possible but probably something I would not want to do. The way to do it would be to generate a "nop" instruction between the finalizers with a line number table entry pointing to the return statement.
From the submitter:
I think it is more clear to go back to the
exit, as a reminder of the type and target of
the exit. Since this is how a non-inlined finally
behaves, it would also be more consistent. For
in-class demos, we are now just putting enough
code in the finalizers to avoid the inlining.
=====================================================
Here is one that could be a bit confusing. When
stepping, control goes from the if-statement
directly to the finalizer without ever hitting
the return statement.
try {
for(int i = 0; i < 3; i++) {
if(i != 1)
;
else
return;
}
}
finally {
System.out.println("finally");
}
=====================================================
- backported by
-
JDK-2113651 inlined finally clauses confuse some debuggers
- Closed
- relates to
-
JDK-7008643 inlined finally clauses confuse debuggers
- Closed
-
JDK-6181889 Empty try/finally results in bytecodes being generated
- Closed