JDK-4459541 : "javap -l" shows line numbers as signed short; they should be unsigned.
  • Type: Bug
  • Component: tools
  • Sub-Component: javap
  • Affected Version: 1.4.0,5.0,6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2001-05-16
  • Updated: 2012-01-13
  • Resolved: 2012-01-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b30Fixed
Description
Name: tb29552			Date: 05/16/2001


If a .java file contains executable code at a source line
index greater than 32767, then running "javap -l" on the
resulting class will print incorrect line numbers.

Attached to this report is Foo.java, which is 70007 lines long
and contains code before line 32767, at 32767, between 32768
and 65535, at 65535, and after 65536.

% wc Foo.java
   70007   84068  586770 Foo.java

% javac Foo.java

% javap -l Foo
Compiled from Foo.java
class Foo extends java.lang.Object {
    Foo();
    public void before_32767();
    public void straddle_32768();
    public void between_32768_65536();
    public void straddle_65535();
    public void after_65536();
    public static void main(java.lang.String[]);
}

Line numbers for method Foo()
   line 1: 0

Line numbers for method void before_32767()
   line 32003: 0
   line 32004: 8

Line numbers for method void straddle_32768()
   line 32764: 0
   line 32765: 8
   line 32766: 16
   line 32767: 24
   line -32768: 32
   line -32767: 40
   line -32766: 48
   line -32765: 54

Line numbers for method void between_32768_65536()
   line -533: 0
   line -532: 8

Line numbers for method void straddle_65535()
   line -2: 0
   line -1: 8



Note: javac (correctly) does not generate any line number information
for code at or after line 65536, because the class file specification
does not allow for it.  Reference section 4.7.8 "The LineNumberTable
Attribute" at this URL:
 http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#22856


======================================================================
Suggested fix contributed by java.net member dmytro_sheyko:

A DESCRIPTION OF THE FIX :
  Bug number : 4459541
  Bug Description : javap shows line numbers as signed short; they should be unsigned
Diff Baseline : Mustang b67.
Comment: The problem is in the fact that method readShort() was used instead of readUnsignedShort(). That method was used in several places, therefore this bug may appear not only with line numbers but also with
1. major/minor version of class file;
2. list of implemented interfaces;
3. local var table;
4. exception trap table (inside Code attribute);
5. declared exception table (Exceptions attribute);
6. unknown attribute output (in hex).
Diff :
diff -u -r old\sun\tools\javap\ClassData.java src\sun\tools\javap\ClassData.java
--- old\sun\tools\javap\ClassData.java	Tue Jan 17 10:48:39 2006
+++ src\sun\tools\javap\ClassData.java	Wed Jan 18 12:58:24 2006
@@ -72,8 +72,8 @@
 				       toHex(magic) + ", expected " +
 				       toHex(JAVA_MAGIC));
 	}
-	minor_version = in.readShort();
-	major_version = in.readShort();
+	minor_version = in.readUnsignedShort();
+	major_version = in.readUnsignedShort();
 	if (major_version != JAVA_VERSION) {
 	}
 	
@@ -89,7 +89,7 @@
 	    interfaces = new int[interfaces_count];
 	}
 	for (int i = 0; i < interfaces_count; i++) {
-	    interfaces[i]=in.readShort();
+	    interfaces[i]=in.readUnsignedShort();
 	}
 	
 	// Read the fields
@@ -237,22 +237,22 @@
 	return "0x"+s.toString();
     }
 
-    static String toHex(long val) {
-	int width;
-	for (width=16; width>0; width--) {
-	    if ((val>>(width-1)*4)!=0) break;
+	static String toHex(long val) {
+		return toHex(val, 16);
 	}
-	return toHex(val, width);
-    }
     
-    static String toHex(int val) {
-	int width;
-	for (width=8; width>0; width--) {
-	    if ((val>>(width-1)*4)!=0) break;
+	static String toHex(int val) {
+		return toHex(val, 8);
+	}
+    
+	static String toHex(short val) {
+		return toHex(val, 4);
 	}
-	return toHex(val, width);
-    }
     
+	static String toHex(byte val) {
+		return toHex(val, 2);
+	}
+
     public void error(String msg) {
 	System.err.println("ERROR:" +msg);
     }
diff -u -r old\sun\tools\javap\JavapPrinter.java src\sun\tools\javap\JavapPrinter.java
--- old\sun\tools\javap\JavapPrinter.java	Tue Jan 17 10:48:39 2006
+++ src\sun\tools\javap\JavapPrinter.java	Wed Jan 18 12:56:08 2006
@@ -871,12 +871,7 @@
 	
 	while (i < data.length){
 	    String databytestring = cls.toHex(data[i]);
-	    if(databytestring.equals("0x")) out.print("00");
-	    else if(databytestring.substring(2).length() == 1){
-		out.print("0"+databytestring.substring(2));
-	    } else{
-		out.print(databytestring.substring(2));
-	    }
+	    out.print(databytestring.substring(2));
 	     
 	     j++;
 	    if(j == 16) {
diff -u -r old\sun\tools\javap\LineNumData.java src\sun\tools\javap\LineNumData.java
--- old\sun\tools\javap\LineNumData.java	Tue Jan 17 10:48:39 2006
+++ src\sun\tools\javap\LineNumData.java	Wed Jan 18 12:50:48 2006
@@ -8,7 +8,6 @@
 
 package sun.tools.javap;
 
-import java.util.*;
 import java.io.*;
 
 /**
@@ -17,7 +16,7 @@
  * @author  Sucheta Dambalkar (Adopted code from jdis)
  */
 class LineNumData {
-    short start_pc, line_number;
+    int start_pc, line_number;
     
     public LineNumData() {}
     
@@ -25,8 +24,8 @@
      * Read LineNumberTable attribute.
      */
     public LineNumData(DataInputStream in) throws IOException {
-	start_pc = in.readShort();
-	line_number=in.readShort();
+	start_pc = in.readUnsignedShort();
+	line_number=in.readUnsignedShort();
 	
     }
 }
diff -u -r old\sun\tools\javap\LocVarData.java src\sun\tools\javap\LocVarData.java
--- old\sun\tools\javap\LocVarData.java	Tue Jan 17 10:48:39 2006
+++ src\sun\tools\javap\LocVarData.java	Wed Jan 18 12:50:39 2006
@@ -8,7 +8,6 @@
 
 package sun.tools.javap;
 
-import java.util.*;
 import java.io.*;
 
 /**
@@ -17,7 +16,7 @@
  * @author  Sucheta Dambalkar (Adopted code from jdis)
  */
 class LocVarData {
-    short start_pc, length, name_cpx, sig_cpx, slot;
+    int start_pc, length, name_cpx, sig_cpx, slot;
     
     public LocVarData() {
     }
@@ -26,11 +25,11 @@
      * Read LocalVariableTable attribute.
      */
     public LocVarData(DataInputStream in) throws IOException {
-	start_pc = in.readShort();
-	length=in.readShort();
-	name_cpx=in.readShort();
-	sig_cpx=in.readShort();
-	slot=in.readShort();
+	start_pc = in.readUnsignedShort();
+	length=in.readUnsignedShort();
+	name_cpx=in.readUnsignedShort();
+	sig_cpx=in.readUnsignedShort();
+	slot=in.readUnsignedShort();
 	
     }
 }
diff -u -r old\sun\tools\javap\MethodData.java src\sun\tools\javap\MethodData.java
--- old\sun\tools\javap\MethodData.java	Tue Jan 17 10:48:39 2006
+++ src\sun\tools\javap\MethodData.java	Wed Jan 18 12:51:12 2006
@@ -185,7 +185,7 @@
 	int num_exceptions = in.readUnsignedShort();
 	exc_index_table=new int[num_exceptions];
 	for (int l = 0; l < num_exceptions; l++) {
-	    int exc=in.readShort();
+	    int exc=in.readUnsignedShort();
 	    exc_index_table[l]=exc;
 	}
     }
diff -u -r old\sun\tools\javap\TrapData.java src\sun\tools\javap\TrapData.java
--- old\sun\tools\javap\TrapData.java	Tue Jan 17 10:48:39 2006
+++ src\sun\tools\javap\TrapData.java	Wed Jan 18 12:51:50 2006
@@ -17,7 +17,7 @@
  * @author  Sucheta Dambalkar (Adopted code from jdis)
  */
 class TrapData {
-    short start_pc, end_pc, handler_pc, catch_cpx;
+    int start_pc, end_pc, handler_pc, catch_cpx;
   int num;
     
      
@@ -26,10 +26,10 @@
      */
     public TrapData(DataInputStream in, int num) throws IOException {
 	this.num=num;
-	start_pc = in.readShort();
-	end_pc=in.readShort();
-	handler_pc=in.readShort();
-	catch_cpx=in.readShort();
+	start_pc = in.readUnsignedShort();
+	end_pc=in.readUnsignedShort();
+	handler_pc=in.readUnsignedShort();
+	catch_cpx=in.readUnsignedShort();
     }
     
     /**


FIX FOR BUG NUMBER:
4459541

Comments
EVALUATION The proposed fix looks correct. But it is too late to be included in JDK 6. Will be fixed in the next release.
25-04-2006

EVALUATION Contribution-forum:https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=10946
18-01-2006

PUBLIC COMMENTS .
08-09-2004

EVALUATION Annoying, yes. Likely to go away as a result of the javap rewrite necessary for Tiger. ###@###.### 2001-09-17
17-09-2001