提交 353b501b 编写于 作者: F fparain

6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K

Reviewed-by: sspitsyn, dholmes, coleenp, kamg
上级 ec06f4a8
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -688,8 +688,7 @@ implements ReferenceType {
if (sde == null) {
String extension = null;
if (saKlass instanceof InstanceKlass) {
Symbol sdeSym = ((InstanceKlass)saKlass).getSourceDebugExtension();
extension = (sdeSym != null)? sdeSym.asString() : null;
extension = ((InstanceKlass)saKlass).getSourceDebugExtension();
}
if (extension == null) {
sde = NO_SDE_INFO_MARK;
......
......@@ -342,7 +342,7 @@ public class InstanceKlass extends Klass {
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getHandle())); }
public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
......
......@@ -2337,12 +2337,7 @@ void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantP
// Don't bother storing it if there is no way to retrieve it
if (JvmtiExport::can_get_source_debug_extension()) {
// Optimistically assume that only 1 byte UTF format is used
// (common case)
TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK);
k->set_source_debug_extension(sde_symbol);
// Note that set_source_debug_extension() increments the reference count
// for its copy of the Symbol*, so use a TempNewSymbol here.
k->set_source_debug_extension((char*)sde_buffer, length);
}
// Got utf8 string, set stream position forward
cfs->skip_u1(length, CHECK);
......
......@@ -847,7 +847,6 @@ void instanceKlass::shared_symbols_iterate(SymbolClosure* closure) {
Klass::shared_symbols_iterate(closure);
closure->do_symbol(&_generic_signature);
closure->do_symbol(&_source_file_name);
closure->do_symbol(&_source_debug_extension);
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
int name_index = fs.name_index();
......@@ -1944,9 +1943,10 @@ void instanceKlass::release_C_heap_structures() {
// class can't be referenced anymore).
if (_array_name != NULL) _array_name->decrement_refcount();
if (_source_file_name != NULL) _source_file_name->decrement_refcount();
if (_source_debug_extension != NULL) _source_debug_extension->decrement_refcount();
// walk constant pool and decrement symbol reference counts
_constants->unreference_symbols();
if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
}
void instanceKlass::set_source_file_name(Symbol* n) {
......@@ -1954,9 +1954,22 @@ void instanceKlass::set_source_file_name(Symbol* n) {
if (_source_file_name != NULL) _source_file_name->increment_refcount();
}
void instanceKlass::set_source_debug_extension(Symbol* n) {
_source_debug_extension = n;
if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount();
void instanceKlass::set_source_debug_extension(char* array, int length) {
if (array == NULL) {
_source_debug_extension = NULL;
} else {
// Adding one to the attribute length in order to store a null terminator
// character could cause an overflow because the attribute length is
// already coded with an u4 in the classfile, but in practice, it's
// unlikely to happen.
assert((length+1) > length, "Overflow checking");
char* sde = NEW_C_HEAP_ARRAY(char, (length + 1), mtClass);
for (int i = 0; i < length; i++) {
sde[i] = array[i];
}
sde[length] = '\0';
_source_debug_extension = sde;
}
}
address instanceKlass::static_field_addr(int offset) {
......
......@@ -226,7 +226,9 @@ class instanceKlass: public Klass {
// Name of source file containing this klass, NULL if not specified.
Symbol* _source_file_name;
// the source debug extension for this klass, NULL if not specified.
Symbol* _source_debug_extension;
// Specified as UTF-8 string without terminating zero byte in the classfile,
// it is stored in the instanceklass as a NULL-terminated UTF-8 string
char* _source_debug_extension;
// Generic signature, or null if none.
Symbol* _generic_signature;
// Array name derived from this class which needs unreferencing
......@@ -542,8 +544,8 @@ class instanceKlass: public Klass {
void set_major_version(u2 major_version) { _major_version = major_version; }
// source debug extension
Symbol* source_debug_extension() const { return _source_debug_extension; }
void set_source_debug_extension(Symbol* n);
char* source_debug_extension() const { return _source_debug_extension; }
void set_source_debug_extension(char* array, int length);
// symbol unloading support (refcount already added)
Symbol* array_name() { return _array_name; }
......
......@@ -421,8 +421,7 @@ instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int it
ik->set_protection_domain(NULL);
ik->set_signers(NULL);
ik->set_source_file_name(NULL);
ik->set_source_debug_extension(NULL);
ik->set_source_debug_extension(NULL);
ik->set_source_debug_extension(NULL, 0);
ik->set_array_name(NULL);
ik->set_inner_classes(NULL);
ik->set_static_oop_field_count(0);
......@@ -531,7 +530,7 @@ void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) {
}
if (ik->source_debug_extension() != NULL) {
st->print(BULLET"source debug extension: ");
ik->source_debug_extension()->print_value_on(st);
st->print_cr("%s", ik->source_debug_extension());
st->cr();
}
......
......@@ -268,14 +268,18 @@ void JvmtiClassFileReconstituter::write_source_file_attribute() {
// JSR45| SourceDebugExtension_attribute {
// JSR45| u2 attribute_name_index;
// JSR45| u4 attribute_length;
// JSR45| u2 sourcefile_index;
// JSR45| u1 debug_extension[attribute_length];
// JSR45| }
void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {
assert(ikh()->source_debug_extension() != NULL, "caller must check");
write_attribute_name_index("SourceDebugExtension");
write_u4(2); // always length 2
write_u2(symbol_to_cpool_index(ikh()->source_debug_extension()));
int len = (int)strlen(ikh()->source_debug_extension());
write_u4(len);
u1* ext = (u1*)ikh()->source_debug_extension();
for (int i=0; i<len; i++) {
write_u1(ext[i]);
}
}
// Write (generic) Signature attribute
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -2541,15 +2541,12 @@ JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_pt
if (!Klass::cast(k)->oop_is_instance()) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
Symbol* sdeOop = instanceKlass::cast(k)->source_debug_extension();
NULL_CHECK(sdeOop, JVMTI_ERROR_ABSENT_INFORMATION);
char* sde = instanceKlass::cast(k)->source_debug_extension();
NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
{
JavaThread* current_thread = JavaThread::current();
ResourceMark rm(current_thread);
const char* sdecp = (const char*) sdeOop->as_C_string();
*source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sdecp)+1);
strcpy(*source_debug_extension_ptr, sdecp);
*source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);
strcpy(*source_debug_extension_ptr, sde);
}
}
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -3236,7 +3236,9 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
// Copy the "source debug extension" attribute from new class version
the_class->set_source_debug_extension(
scratch_class->source_debug_extension());
scratch_class->source_debug_extension(),
scratch_class->source_debug_extension() == NULL ? 0 :
(int)strlen(scratch_class->source_debug_extension()));
// Use of javac -g could be different in the old and the new
if (scratch_class->access_flags().has_localvariable_table() !=
......
......@@ -308,7 +308,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
nonstatic_field(instanceKlass, _protection_domain, oop) \
nonstatic_field(instanceKlass, _signers, objArrayOop) \
nonstatic_field(instanceKlass, _source_file_name, Symbol*) \
nonstatic_field(instanceKlass, _source_debug_extension, Symbol*) \
nonstatic_field(instanceKlass, _source_debug_extension, char*) \
nonstatic_field(instanceKlass, _inner_classes, typeArrayOop) \
nonstatic_field(instanceKlass, _nonstatic_field_size, int) \
nonstatic_field(instanceKlass, _static_field_size, int) \
......
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6294277
* @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
*/
import java.io.*;
public class SourceDebugExtension extends ClassLoader
{
static final int attrSize = 68000;
static byte[] header = {
(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x32, (byte)0x00, (byte)0x1e, (byte)0x0a, (byte)0x00, (byte)0x06, (byte)0x00,
(byte)0x0f, (byte)0x09, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x11, (byte)0x08,
(byte)0x00, (byte)0x12, (byte)0x0a, (byte)0x00, (byte)0x13, (byte)0x00, (byte)0x14,
(byte)0x07, (byte)0x00, (byte)0x15, (byte)0x07, (byte)0x00, (byte)0x16, (byte)0x01,
(byte)0x00, (byte)0x06, (byte)0x3c, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x74,
(byte)0x3e, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x28, (byte)0x29, (byte)0x56,
(byte)0x01, (byte)0x00, (byte)0x04, (byte)0x43, (byte)0x6f, (byte)0x64, (byte)0x65,
(byte)0x01, (byte)0x00, (byte)0x0f, (byte)0x4c, (byte)0x69, (byte)0x6e, (byte)0x65,
(byte)0x4e, (byte)0x75, (byte)0x6d, (byte)0x62, (byte)0x65, (byte)0x72, (byte)0x54,
(byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x04,
(byte)0x6d, (byte)0x61, (byte)0x69, (byte)0x6e, (byte)0x01, (byte)0x00, (byte)0x16,
(byte)0x28, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61,
(byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53,
(byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67, (byte)0x3b, (byte)0x29,
(byte)0x56, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x53, (byte)0x6f, (byte)0x75,
(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x46, (byte)0x69, (byte)0x6c, (byte)0x65,
(byte)0x01, (byte)0x00, (byte)0x0d, (byte)0x54, (byte)0x65, (byte)0x73, (byte)0x74,
(byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x2e, (byte)0x6a, (byte)0x61,
(byte)0x76, (byte)0x61, (byte)0x0c, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08,
(byte)0x07, (byte)0x00, (byte)0x17, (byte)0x0c, (byte)0x00, (byte)0x18, (byte)0x00,
(byte)0x19, (byte)0x01, (byte)0x00, (byte)0x34, (byte)0x54, (byte)0x65, (byte)0x73,
(byte)0x74, (byte)0x20, (byte)0x70, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x72,
(byte)0x61, (byte)0x6d, (byte)0x20, (byte)0x66, (byte)0x6f, (byte)0x72, (byte)0x20,
(byte)0x62, (byte)0x69, (byte)0x67, (byte)0x20, (byte)0x53, (byte)0x6f, (byte)0x75,
(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65, (byte)0x62, (byte)0x75,
(byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65, (byte)0x6e, (byte)0x73,
(byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x20, (byte)0x61, (byte)0x74, (byte)0x74,
(byte)0x72, (byte)0x69, (byte)0x62, (byte)0x75, (byte)0x74, (byte)0x65, (byte)0x73,
(byte)0x07, (byte)0x00, (byte)0x1a, (byte)0x0c, (byte)0x00, (byte)0x1b, (byte)0x00,
(byte)0x1c, (byte)0x01, (byte)0x00, (byte)0x08, (byte)0x54, (byte)0x65, (byte)0x73,
(byte)0x74, (byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x01, (byte)0x00,
(byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x4f, (byte)0x62, (byte)0x6a,
(byte)0x65, (byte)0x63, (byte)0x74, (byte)0x01, (byte)0x00, (byte)0x10, (byte)0x6a,
(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e,
(byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x79, (byte)0x73, (byte)0x74, (byte)0x65,
(byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x6f, (byte)0x75, (byte)0x74,
(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76,
(byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f, (byte)0x50, (byte)0x72,
(byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x65,
(byte)0x61, (byte)0x6d, (byte)0x3b, (byte)0x01, (byte)0x00, (byte)0x13, (byte)0x6a,
(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f,
(byte)0x50, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74,
(byte)0x72, (byte)0x65, (byte)0x61, (byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x07,
(byte)0x70, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x6c, (byte)0x6e,
(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x28, (byte)0x4c, (byte)0x6a, (byte)0x61,
(byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
(byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67,
(byte)0x3b, (byte)0x29, (byte)0x56, (byte)0x01, (byte)0x00, (byte)0x14, (byte)0x53,
(byte)0x6f, (byte)0x75, (byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65,
(byte)0x62, (byte)0x75, (byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65,
(byte)0x6e, (byte)0x73, (byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x00, (byte)0x21,
(byte)0x00, (byte)0x05, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x07,
(byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x2a, (byte)0xb7, (byte)0x00,
(byte)0x01, (byte)0xb1, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00,
(byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x01,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
(byte)0x0b, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x25, (byte)0x00, (byte)0x02, (byte)0x00,
(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0xb2, (byte)0x00,
(byte)0x02, (byte)0x12, (byte)0x03, (byte)0xb6, (byte)0x00, (byte)0x04, (byte)0xb1,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x04, (byte)0x00,
(byte)0x02, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
(byte)0x00, (byte)0x0e, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x09,
(byte)0xa0
};
public static void main(String[] args) throws Exception
{
try {
SourceDebugExtension loader = new SourceDebugExtension();
/* The test program creates a class file from the header
* stored above and adding the content of a SourceDebugExtension
* attribute made of the character 0x02 repeated 68000 times.
* This attribute doesn't follow the syntax specified in JSR 45
* but it's fine because this test just checks that the JVM is
* able to load a class file with a SourceDebugExtension
* attribute bigger than 64KB. The JVM doesn't try to
* parse the content of the attribute, this work is performed
* by the SA or external tools.
*/
byte[] buf = new byte[header.length + attrSize];
for(int i=0; i<header.length; i++) {
buf[i] = header[i];
}
for(int i=0; i<attrSize; i++) {
buf[header.length+i] = (byte)0x02;
}
Class c = loader.defineClass("TestProg", buf, 0, buf.length);
System.out.println("Test PASSES");
} catch(Exception e) {
System.out.println("Test FAILS");
}
}
}
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test Test6294277.sh
# @bug 6294277
# @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
# @run shell Test6294277.sh
#
if [ "${TESTSRC}" = "" ]
then TESTSRC=.
fi
if [ "${TESTJAVA}" = "" ]
then
PARENT=`dirname \`which java\``
TESTJAVA=`dirname ${PARENT}`
echo "TESTJAVA not set, selecting " ${TESTJAVA}
echo "If this is incorrect, try setting the variable manually."
fi
BIT_FLAG=""
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
SunOS | Linux )
NULL=/dev/null
PS=":"
FS="/"
## for solaris, linux it's HOME
FILE_LOCATION=$HOME
if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" -a `uname -p`='sparc' ]
then
BIT_FLAG="-d64"
fi
;;
Windows_* | Darwin )
NULL=NUL
PS=";"
FS="\\"
echo "Test skipped"
exit 0
;;
* )
echo "Unrecognized system!"
exit 1;
;;
esac
cp ${TESTSRC}${FS}*.java .
${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
${TESTJAVA}${FS}bin${FS}javac *.java
${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -classpath . -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension > test.out 2>&1 &
P_PID=$!
sleep 60
STATUS=1
grep "Test PASSES" test.out > ${NULL}
if [ $? = 0 ]; then
cat test.out
STATUS=0
fi
exit $STATUS
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册