scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

runtime reflection: corruption in unpickling when pickled data is chunked #7556

Closed scabug closed 11 years ago

scabug commented 11 years ago
% head sandbox/mega-trait.scala # attached
trait MegaTrait {
def method0: Int = 0
def method1: Int = 0
def method2: Int = 0
def method3: Int = 0
def method4: Int = 0
def method5: Int = 0
def method6: Int = 0
def method7: Int = 0
def method8: Int = 0
  ~/code/scala tail sandbox/mega-trait.scala
def method2991: Int = 0
def method2992: Int = 0
def method2993: Int = 0
def method2994: Int = 0
def method2995: Int = 0
def method2996: Int = 0
def method2997: Int = 0
def method2998: Int = 0
def method2999: Int = 0
}

% qbin/scalac -d sandbox/ sandbox/mega-trait.scala &&  qbin/scala -nc -classpath sandbox/ -e 'scala.reflect.runtime.universe.typeTag[MegaTrait].tpe.members'java.lang.ArrayIndexOutOfBoundsException: 958737694
    at scala.reflect.internal.pickling.PickleBuffer.readByte(PickleBuffer.scala:104)
    at scala.reflect.internal.pickling.PickleBuffer$$anonfun$createIndex$1.apply$mcVI$sp(PickleBuffer.scala:181)
    at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:149)
    at scala.reflect.internal.pickling.PickleBuffer.createIndex(PickleBuffer.scala:179)
    at scala.reflect.internal.pickling.UnPickler$Scan.<init>(UnPickler.scala:60)
    at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:38)
    at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:592)
    at scala.reflect.runtime.SymbolLoaders$TopClassCompleter$$anonfun$complete$1.apply$mcV$sp(SymbolLoaders.scala:35)
    at scala.reflect.runtime.SymbolLoaders$TopClassCompleter$$anonfun$complete$1.apply(SymbolLoaders.scala:32)
    at scala.reflect.runtime.SymbolLoaders$TopClassCompleter$$anonfun$complete$1.apply(SymbolLoaders.scala:32)
    at scala.reflect.internal.SymbolTable.enteringPhaseNotLaterThan(SymbolTable.scala:226)
    at scala.reflect.runtime.SymbolLoaders$TopClassCompleter.complete(SymbolLoaders.scala:32)
    at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1319)
    at scala.reflect.internal.Types$TypeRef.thisInfo(Types.scala:2321)
    at scala.reflect.internal.Types$TypeRef.baseClasses(Types.scala:2326)
    at scala.reflect.internal.Types$Type.scala$reflect$internal$Types$Type$$findMembersInternal$1(Types.scala:990)
    at scala.reflect.internal.Types$Type.findMembers(Types.scala:1036)
    at scala.reflect.internal.Types$Type.membersBasedOnFlags(Types.scala:624)
    at scala.reflect.internal.Types$Type.members(Types.scala:577)
    at scala.reflect.internal.Types$Type.members(Types.scala:256)
    at Main$$anon$1.<init>(scalacmd6150594393612715057.scala:1)
    at Main$.main(scalacmd6150594393612715057.scala:1)
    at Main.main(scalacmd6150594393612715057.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:68)
    at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:99)
    at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:68)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:99)
    at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
    at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
    at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
    at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
    at scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:158)
    at scala.tools.nsc.ScriptRunner$$anonfun$runCommand$1.apply(ScriptRunner.scala:205)
    at scala.tools.nsc.ScriptRunner$$anonfun$runCommand$1.apply(ScriptRunner.scala:205)
    at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1$$anonfun$apply$mcZ$sp$1.apply(ScriptRunner.scala:144)
    at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1$$anonfun$apply$mcZ$sp$1.apply(ScriptRunner.scala:144)
    at scala.Option.exists(Option.scala:228)
    at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:144)
    at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:118)
    at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:118)
    at scala.tools.nsc.util.package$.trackingThreads(package.scala:46)
    at scala.tools.nsc.util.package$.waitingForThreads(package.scala:30)
    at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:117)
    at scala.tools.nsc.ScriptRunner.runCommand(ScriptRunner.scala:205)
    at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:92)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
java.lang.RuntimeException: error reading Scala signature of MegaTrait: 958737694
    at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:46)
    at scala.reflect.runtime.JavaMirrors$JavaMirror.unpickleClass(JavaMirrors.scala:592)

During unpickling, the var readIndex is mutated thusly:

// (old, new)
(57432,57433)
(57433,57434)
(57434,57435)
(57435,57436)
(57436,57437)
(57437,958737694)

From JavaMirrors

            loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match {
              case Some(slsig) =>
                info(s"unpickling Scala $clazz and $module with long Scala signature")
                val byteSegments = slsig map (_.getBytes)
                val lens = byteSegments map ByteCodecs.decode
                val bytes = Array.ofDim[Byte](lens.sum)
                var len = 0
                for ((bs, l) <- byteSegments zip lens) {
                  bs.copyToArray(bytes, len, l)
                  len += l
                }
                unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
              case None =>
                // class does not have a Scala signature; it's a Java class
                info("translating reflection info for Java " + jclazz) //debug
                initClassAndModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz))
            }

We get the corruption just over the boundary between the two byteSegments.

byteSegments = {byte[2][]@5299}
[0] = {byte[65515]@5315}
[1] = {byte[1864]@5316}

len = {scala.runtime.IntRef@5302}"58957"
lens = {int[2]@5300}
[0] = 57326
[1] = 1631
scabug commented 11 years ago

Imported From: https://issues.scala-lang.org/browse/SI-7556?orig=1 Reporter: @retronym Affected Versions: 2.10.0 Attachments:

scabug commented 11 years ago

@retronym said: https://github.com/scala/scala/pull/2626