This is the mail archive of the
java-discuss@sourceware.cygnus.com
mailing list for the Java project.
Re: jc1 segfaults compiling volano
- To: bryce@albatross.co.nz
- Subject: Re: jc1 segfaults compiling volano
- From: Andrew Haley <aph@pasanda.cygnus.co.uk>
- Date: 22 Jun 1999 14:44:04 -0000
- CC: java-discuss@sourceware.cygnus.com
> >From alias Tue Jun 22 07:18:01 1999
> Mailing-List: contact java-discuss-help@sourceware.cygnus.com; run by ezmlm
> Precedence: bulk
> Sender: java-discuss-owner@sourceware.cygnus.com
> Delivered-To: mailing list java-discuss@sourceware.cygnus.com
> Date: Tue, 22 Jun 1999 18:16:35 +1200
> From: Bryce McKinlay <bryce@albatross.co.nz>
> X-Mailer: Mozilla 4.6 [en] (X11; I; Linux 2.2.5 i686)
> X-Accept-Language: en
> MIME-Version: 1.0
> Content-Type: text/plain; charset=iso-8859-1
> Content-Transfer-Encoding: 8bit
>
> As part of my ongoing effort to get the "volano" benchmark
> (ftp://ftp.volano.com/vmark2_1_2_0.class) to work on gcj (Volano
> consists of some rather nasty obfuscated classes), I have encountered
> two seperate segfaults trying to compile the "volano" benchmark :
>
> These are with:
> GNU Java version gcc-2.96 19990621 (experimental) (i686-pc-linux-gnu)
> compiled by GNU C version egcs-2.91.66 19990314/Linux (egcs-1.1.2
> release).
>
> The first one (COM/volano/NTService.class):
>
> (gdb) run COM/volano/NTService.class -quiet -g1 -version -o
> /tmp/ccdlQRPp.s
> Starting program:
> /usr/local/egcs/lib/gcc-lib/i686-pc-linux-gnu/gcc-2.96/jc1
> COM/volano/NTService.class -quiet -g1 -version -o /tmp/ccdlQRPp.s
> GNU Java version gcc-2.96 19990621 (experimental) (i686-pc-linux-gnu)
> compiled by GNU C version egcs-2.91.66 19990314/Linux (egcs-1.1.2
> release).
> COM/volano/NTService.java:0: Cannot find file for class
> com.ms.service.Service.
> COM/volano/NTService.java:0: Cannot find file for class
> com.ms.service.Service.
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x805b107 in class_depth (clas=0x820dc18) at
> ../../../gcc/java/class.c:266
> 266 clas = TYPE_BINFO_BASETYPE (clas, 0);
> (gdb) bt
> #0 0x805b107 in class_depth (clas=0x820dc18) at
> ../../../gcc/java/class.c:266
> #1 0x8060b7e in can_widen_reference_to (source_type=0x820dd78,
> target_type=0x820db80) at ../../../gcc/java/expr.c:380
> #2 0x8060a87 in pop_type_0 (type=0x820da1c) at
> ../../../gcc/java/expr.c:308
> #3 0x8060abd in pop_type (type=0x820da1c) at
> ../../../gcc/java/expr.c:328
> #4 0x8068e56 in verify_jvm_instructions (jcf=0x81e3f00,
> byte_ops=0x820cce8 "*·", length=138) at
> ../../../gcc/java/verify.c:881
> #5 0x80632f9 in expand_byte_code (jcf=0x81e3f00, method=0x820ecc0)
> at ../../../gcc/java/expr.c:2149
> #6 0x806c4fa in parse_class_file () at
> ../../../gcc/java/jcf-parse.c:726
> #7 0x806c920 in yyparse () at ../../../gcc/java/jcf-parse.c:886
> #8 0x8075422 in compile_file (name=0xbffff9de
> "COM/volano/NTService.class")
> at ../../gcc/toplev.c:3265
> #9 0x8078287 in main (argc=7, argv=0xbffff874) at
> ../../gcc/toplev.c:5441
> #10 0x40031cb3 in __libc_start_main (main=0x80773c8 <main>, argc=7,
> argv=0xbffff874, init=0x8049004 <_init>, fini=0x819127c <_fini>,
> rtld_fini=0x4000a350 <_dl_fini>, stack_end=0xbffff86c)
> at ../sysdeps/generic/libc-start.c:78
>
> Of course, we don't need NTService.class, so I replaced it with the
> following stub, which gcj seems to accept:
>
> package COM.volano;
>
> public class NTService
> {
> public static void \u01ad (String a, String b) {}
> public boolean handleStop() {return true;}
> public boolean handleShutdown() {return true;}
> }
>
> Unfortunatly, we get another segfault further down the track, in
> COM/volano/mbi.class:
>
> (gdb) run COM/volano/mbi.class -g1 -version -o /tmp/ccrq582R.s
> Program received signal SIGSEGV, Segmentation fault.
> load_type_state (label=0x824fe60) at ../../../gcc/java/expr.c:1801
> 1801 int cur_length = TREE_VEC_LENGTH (vec);
> (gdb) bt
> #0 load_type_state (label=0x824fe60) at ../../../gcc/java/expr.c:1801
> #1 0x8064f06 in process_jvm_instruction (PC=130,
> byte_ops=0x82162f2 "¸\001\016L§", length=180)
> at ../../../gcc/java/javaop.def:310
> #2 0x8063494 in expand_byte_code (jcf=0x81e3f00, method=0x8214458)
> at ../../../gcc/java/expr.c:2217
> #3 0x806c4fa in parse_class_file () at
> ../../../gcc/java/jcf-parse.c:726
> #4 0x806c920 in yyparse () at ../../../gcc/java/jcf-parse.c:886
> #5 0x8075422 in compile_file (name=0xbffff9eb "COM/volano/mbi.class")
> at ../../gcc/toplev.c:3265
> #6 0x8078287 in main (argc=6, argv=0xbffff884) at
> ../../gcc/toplev.c:5441
> #7 0x40031cb3 in __libc_start_main (main=0x80773c8 <main>, argc=6,
> argv=0xbffff884, init=0x8049004 <_init>, fini=0x819127c <_fini>,
> rtld_fini=0x4000a350 <_dl_fini>, stack_end=0xbffff87c)
> at ../sysdeps/generic/libc-start.c:78
>
> regards
>
> [ bryce ]
>
>
Index: verify.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/verify.c,v
retrieving revision 1.43
diff -c -2 -p -r1.43 verify.c
*** verify.c 1999/06/21 15:20:46 1.43
--- verify.c 1999/06/22 14:42:24
*************** verify_jvm_instructions (jcf, byte_ops,
*** 428,431 ****
--- 428,492 ----
INVALIDATE_PC;
}
+ /* Check if there are any more pending blocks in the current
+ subroutine. Because we push pending blocks in a
+ last-in-first-out order, and because we don't push anything
+ from our caller until we are done with this subroutine or
+ anything nested in it, then we are done if the top of the
+ pending_blocks stack is not in a subroutine, or it is in our
+ caller. */
+ if (current_subr
+ && PC == INVALID_PC)
+ {
+ tree caller = LABEL_SUBR_CONTEXT (current_subr);
+
+ if (pending_blocks == NULL_TREE
+ || ! LABEL_IN_SUBR (pending_blocks)
+ || LABEL_SUBR_START (pending_blocks) == caller)
+ {
+ int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
+ tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
+ tmp = LABEL_RETURN_LABELS (current_subr);
+
+ /* FIXME: If we exit a subroutine via a throw, we might
+ have returned to an earlier caller. Obviously a
+ "ret" can only return one level, but a throw may
+ return many levels.*/
+ current_subr = caller;
+
+ if (RETURN_MAP_ADJUSTED (ret_map))
+ {
+ /* Since we are done with this subroutine , set up
+ the (so far known) return address as pending -
+ with the merged type state. */
+ for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
+ {
+ tree return_label = TREE_VALUE (tmp);
+ tree return_state = LABEL_TYPE_STATE (return_label);
+ if (return_state == NULL_TREE)
+ {
+ /* This means means we had not verified the
+ subroutine earlier, so this is the first jsr to
+ call it. In this case, the type_map of the return
+ address is just the current type_map - and that
+ is handled by the following PUSH_PENDING. */
+ }
+ else
+ {
+ /* In this case we have to do a merge. But first
+ restore the type_map for unused slots to those
+ that were in effect at the jsr. */
+ for (index = size; --index >= 0; )
+ {
+ type_map[index] = TREE_VEC_ELT (ret_map, index);
+ if (type_map[index] == TYPE_UNUSED)
+ type_map[index]
+ = TREE_VEC_ELT (return_state, index);
+ }
+ }
+ PUSH_PENDING (return_label);
+ }
+ }
+ }
+ }
if (PC == INVALID_PC)
{
*************** verify_jvm_instructions (jcf, byte_ops,
*** 450,453 ****
--- 511,516 ----
VERIFICATION_ERROR ("falling through end of method");
+ /* fprintf (stderr, "** %d\n", PC); */
+
oldpc = PC;
*************** verify_jvm_instructions (jcf, byte_ops,
*** 1208,1272 ****
return 0;
}
-
- /* Check if there are any more pending blocks in this subroutine.
- Because we push pending blocks in a last-in-first-out order,
- and because we don't push anything from our caller until we
- are done with this subroutine or anything nested in it,
- then we are done if the top of the pending_blocks stack is
- not in a subroutine, or it is in our caller. */
- if (current_subr
- && PC == INVALID_PC)
- {
- tree caller = LABEL_SUBR_CONTEXT (current_subr);
-
- if (pending_blocks == NULL_TREE
- || ! LABEL_IN_SUBR (pending_blocks)
- || LABEL_SUBR_START (pending_blocks) == caller)
- {
- int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
- tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
- tmp = LABEL_RETURN_LABELS (current_subr);
-
- /* FIXME: If we exit a subroutine via a throw, we might
- have returned to an earlier caller. Obviously a
- "ret" can only return one level, but a throw may
- return many levels.*/
- current_subr = caller;
-
- if (RETURN_MAP_ADJUSTED (ret_map))
- {
- /* Since we are done with this subroutine , set up
- the (so far known) return address as pending -
- with the merged type state. */
- for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
- {
- tree return_label = TREE_VALUE (tmp);
- tree return_state = LABEL_TYPE_STATE (return_label);
- if (return_state == NULL_TREE)
- {
- /* This means means we had not verified the
- subroutine earlier, so this is the first jsr to
- call it. In this case, the type_map of the return
- address is just the current type_map - and that
- is handled by the following PUSH_PENDING. */
- }
- else
- {
- /* In this case we have to do a merge. But first
- restore the type_map for unused slots to those
- that were in effect at the jsr. */
- for (index = size; --index >= 0; )
- {
- type_map[index] = TREE_VEC_ELT (ret_map, index);
- if (type_map[index] == TYPE_UNUSED)
- type_map[index]
- = TREE_VEC_ELT (return_state, index);
- }
- }
- PUSH_PENDING (return_label);
- }
- }
- }
- }
prevpc = oldpc;
--- 1271,1274 ----