From 4f530c492d94e2c86dd906737a8d35806b5e450a Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 6 Jun 2013 04:59:56 -0700 Subject: Cleanup of crash output. I finally ran across the assert (or one of them) which produces such voluminous output that it scares the cattle. When you see "decls" in an assert, run. After silencing that, I extended the journey into quieting the default crash message down, way down. I assume this will be met only with sighs of relief. And then most challenging of all for some reason, I convinced it to only print the information once. Volume of crash data generated when reproducing the fsc bug shown below: Before this commit 1158 lines After this commit 27 lines Pretty sure there's more information in the 27 lines. To reproduce the crash: fsc src/library/scala/collection/immutable/IntMap.scala fsc src/library/scala/collection/immutable/IntMap.scala The first compile succeeds quietly; the second throws warnings out of the gate, then crashes. And the "after" output: error: Cannot create static reference to method equals because object GenMapLike$class has no source module error: fatal error: while compiling: /scala/trunk/src/library/scala/collection/immutable/IntMap.scala during phase: globalPhase=mixin, enteringPhase=cleanup library version: version 2.11.0-20130606-052937-392858b4f6 compiler version: version 2.11.0-20130606-055515-1856bec71b reconstructed args: -d /tmp last tree to typer: Ident(key$2) tree position: line 377 of /scala/trunk/src/library/scala/collection/immutable/IntMap.scala tree tpe: Int symbol: value key$2 (flags: ) symbol definition: key$2: Int (a TermSymbol) symbol package: scala.collection.immutable symbol owners: value key$2 -> constructor IntMap$$anonfun$unionWith$2 -> anonymous class anonfun$unionWith$2 call site: object IntMap$Nil in package immutable in package immutable == Source file context for tree position == 374 } 375 case (IntMap.Tip(key, value), x) => x.updateWith[S](key, value, (x, y) => f(key, y, x)) 376 case (x, IntMap.Tip(key, value)) => x.updateWith[S](key, value, (x, y) => f(key, x, y)) 377 case (IntMap.Nil, x) => x 378 case (x, IntMap.Nil) => x 379 } 380 --- src/compiler/scala/tools/nsc/Global.scala | 58 +++++++++++++------------------ 1 file changed, 25 insertions(+), 33 deletions(-) (limited to 'src/compiler/scala/tools/nsc/Global.scala') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index a08633ffc8..981dfb24fe 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1060,14 +1060,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter) @inline final def enteringTyper[T](op: => T): T = enteringPhase(currentRun.typerPhase)(op) @inline final def enteringUncurry[T](op: => T): T = enteringPhase(currentRun.uncurryPhase)(op) - // Owners up to and including the first package class. + // Owners which aren't package classes. private def ownerChainString(sym: Symbol): String = ( if (sym == null) "" - else sym.ownerChain.span(!_.isPackageClass) match { - case (xs, pkg :: _) => (xs :+ pkg) mkString " -> " - case _ => sym.ownerChain mkString " -> " // unlikely - } + else sym.ownerChain takeWhile (!_.isPackageClass) mkString " -> " ) + private def formatExplain(pairs: (String, Any)*): String = ( pairs.toList collect { case (k, v) if v != null => "%20s: %s".format(k, v) } mkString "\n" ) @@ -1075,41 +1073,45 @@ class Global(var currentSettings: Settings, var reporter: Reporter) /** Don't want to introduce new errors trying to report errors, * so swallow exceptions. */ - override def supplementErrorMessage(errorMessage: String): String = + override def supplementErrorMessage(errorMessage: String): String = { if (currentRun.supplementedError) errorMessage else try { + currentRun.supplementedError = true val tree = analyzer.lastTreeToTyper val sym = tree.symbol val tpe = tree.tpe - val enclosing = lastSeenContext.enclClassOrMethod.tree + val site = lastSeenContext.enclClassOrMethod.owner + val pos_s = if (tree.pos.isDefined) s"line ${tree.pos.line} of ${tree.pos.source.file}" else "" + val context_s = try { + // Taking 3 before, 3 after the fingered line. + val start = 0 max (tree.pos.line - 3) + val xs = scala.reflect.io.File(tree.pos.source.file.file).lines drop start take 7 + val strs = xs.zipWithIndex map { case (line, idx) => f"${start + idx}%6d $line" } + strs.mkString("== Source file context for tree position ==\n\n", "\n", "") + } + catch { case t: Exception => devWarning("" + t) ; "" } val info1 = formatExplain( "while compiling" -> currentSource.path, - "during phase" -> ( if (globalPhase eq phase) phase else "global=%s, enteringPhase=%s".format(globalPhase, phase) ), + "during phase" -> ( if (globalPhase eq phase) phase else "globalPhase=%s, enteringPhase=%s".format(globalPhase, phase) ), "library version" -> scala.util.Properties.versionString, "compiler version" -> Properties.versionString, "reconstructed args" -> settings.recreateArgs.mkString(" ") ) val info2 = formatExplain( "last tree to typer" -> tree.summaryString, + "tree position" -> pos_s, + "tree tpe" -> tpe, "symbol" -> Option(sym).fold("null")(_.debugLocationString), - "symbol definition" -> Option(sym).fold("null")(_.defString), - "tpe" -> tpe, + "symbol definition" -> Option(sym).fold("null")(s => s.defString + s" (a ${s.shortSymbolClass})"), + "symbol package" -> sym.enclosingPackage.fullName, "symbol owners" -> ownerChainString(sym), - "context owners" -> ownerChainString(lastSeenContext.owner) + "call site" -> (site.fullLocationString + " in " + site.enclosingPackage) ) - val info3: List[String] = ( - ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) ) - ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) ) - ++ ( if (!settings.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) ) - ++ ( List(errorMessage) ) - ) - - currentRun.supplementedError = true - - ("\n" + info1) :: info2 :: info3 mkString "\n\n" + ("\n" + info1) :: info2 :: context_s :: Nil mkString "\n\n" } catch { case _: Exception | _: TypeError => errorMessage } + } /** The id of the currently active run */ @@ -1493,18 +1495,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter) compileUnits(sources map (new CompilationUnit(_)), firstPhase) } - def compileUnits(units: List[CompilationUnit], fromPhase: Phase) { - try compileUnitsInternal(units, fromPhase) - catch { case ex: Throwable => - val shown = if (settings.verbose) - stackTraceString(ex) - else - stackTraceHeadString(ex) // note that error stacktraces do not print in fsc - - globalError(supplementErrorMessage("uncaught exception during compilation: " + shown)) - throw ex - } - } + def compileUnits(units: List[CompilationUnit], fromPhase: Phase): Unit = + compileUnitsInternal(units, fromPhase) private def compileUnitsInternal(units: List[CompilationUnit], fromPhase: Phase) { doInvalidation() -- cgit v1.2.3