diff options
| author | Albert Chen | 2018-11-26 09:47:28 -0800 |
|---|---|---|
| committer | Schuyler Eldridge | 2018-11-26 12:47:28 -0500 |
| commit | ab951049c2c60402e2318ba863520d4a16c8288d (patch) | |
| tree | 496a62cb509f06711a01795bca7eafc8ae260a8b /chiselFrontend/src/main/scala | |
| parent | dd82374f79005a2998b016712f0aec07775eb506 (diff) | |
Trim Stack Trace (#931)
- Trim stack trace to show better, reduced information to the user
- Add --full-stacktrace to FIRRTL option to show full stack trace
Diffstat (limited to 'chiselFrontend/src/main/scala')
6 files changed, 56 insertions, 19 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 9a2e9a38..5563092e 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -507,7 +507,7 @@ trait IgnoreSeqInBundle { override def ignoreSeq: Boolean = true } -class AutoClonetypeException(message: String) extends ChiselException(message, null) +class AutoClonetypeException(message: String) extends ChiselException(message) /** Base class for data types defined as a bundle of other data types. * diff --git a/chiselFrontend/src/main/scala/chisel3/core/Attach.scala b/chiselFrontend/src/main/scala/chisel3/core/Attach.scala index edc0a7c9..b3096fd5 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Attach.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Attach.scala @@ -9,7 +9,7 @@ import chisel3.internal.sourceinfo.{SourceInfo} object attach { // scalastyle:ignore object.name // Exceptions that can be generated by attach - case class AttachException(message: String) extends Exception(message) + case class AttachException(message: String) extends ChiselException(message) def ConditionalAttachException = AttachException(": Conditional attach is not allowed!") diff --git a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala index 1dcb968d..ad7ba98a 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala @@ -2,6 +2,7 @@ package chisel3.core +import chisel3.internal.ChiselException import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.{Connect, DefInvalid} import scala.language.experimental.macros @@ -23,7 +24,7 @@ import chisel3.internal.sourceinfo._ object BiConnect { // These are all the possible exceptions that can be thrown. - case class BiConnectException(message: String) extends Exception(message) + case class BiConnectException(message: String) extends ChiselException(message) // These are from element-level connection def BothDriversException = BiConnectException(": Both Left and Right are drivers") diff --git a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala index b3b754de..60235477 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala @@ -1,10 +1,11 @@ package chisel3.core +import chisel3.internal.ChiselException import chisel3.internal.Builder.{forcedModule} import chisel3.internal.firrtl.LitArg object Binding { - class BindingException(message: String) extends Exception(message) + class BindingException(message: String) extends ChiselException(message) /** A function expected a Chisel type but got a hardware object */ case class ExpectedChiselTypeException(message: String) extends BindingException(message) diff --git a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala index c9420ba7..d4c80405 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala @@ -2,6 +2,7 @@ package chisel3.core +import chisel3.internal.ChiselException import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.{Connect, DefInvalid} import scala.language.experimental.macros @@ -33,7 +34,7 @@ import chisel3.internal.sourceinfo.SourceInfo object MonoConnect { // These are all the possible exceptions that can be thrown. - case class MonoConnectException(message: String) extends Exception(message) + case class MonoConnectException(message: String) extends ChiselException(message) // These are from element-level connection def UnreadableSourceException = MonoConnectException(": Source is unreadable from current module.") diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala index 2346181a..07f4db73 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala @@ -6,7 +6,38 @@ import scala.collection.mutable.{ArrayBuffer, LinkedHashMap} import chisel3.core._ -class ChiselException(message: String, cause: Throwable) extends Exception(message, cause) +class ChiselException(message: String, cause: Throwable = null) extends Exception(message, cause) { + + val blacklistPackages = Set("chisel3", "scala", "java", "sun", "sbt") + val builderName = "chisel3.internal.Builder" + + /** trims the top of the stack of elements belonging to [[blacklistPackages]] + * then trims the bottom elements until it reaches [[builderName]] + * then continues trimming elements belonging to [[blacklistPackages]] + */ + def trimmedStackTrace: Array[StackTraceElement] = { + def isBlacklisted(ste: StackTraceElement) = { + val packageName = ste.getClassName().takeWhile(_ != '.') + blacklistPackages.contains(packageName) + } + + val trimmedLeft = getStackTrace().view.dropWhile(isBlacklisted) + val trimmedReverse = trimmedLeft.reverse + .dropWhile(ste => !ste.getClassName.startsWith(builderName)) + .dropWhile(isBlacklisted) + trimmedReverse.reverse.toArray + } + + def chiselStackTrace: String = { + val trimmed = trimmedStackTrace + val sw = new java.io.StringWriter + sw.write(toString + "\n") + sw.write("\t...\n") + trimmed.foreach(ste => sw.write(s"\tat $ste\n")) + sw.write("\t... (Stack trace trimmed to user code only, rerun with --full-stacktrace if you wish to see the full stack trace)\n") + sw.toString + } +} private[chisel3] object throwException { def apply(s: String, t: Throwable = null): Nothing = @@ -14,6 +45,12 @@ private[chisel3] object throwException { } /** Records and reports runtime errors and warnings. */ +private[chisel3] object ErrorLog { + val depTag = s"[${Console.BLUE}deprecated${Console.RESET}]" + val warnTag = s"[${Console.YELLOW}warn${Console.RESET}]" + val errTag = s"[${Console.RED}error${Console.RESET}]" +} + private[chisel3] class ErrorLog { /** Log an error message */ def error(m: => String): Unit = @@ -43,33 +80,30 @@ private[chisel3] class ErrorLog { /** Throw an exception if any errors have yet occurred. */ def checkpoint(): Unit = { - val depTag = s"[${Console.BLUE}deprecated${Console.RESET}]" - val warnTag = s"[${Console.YELLOW}warn${Console.RESET}]" - val errTag = s"[${Console.RED}error${Console.RESET}]" deprecations.foreach { case ((message, sourceLoc), count) => - println(s"$depTag $sourceLoc ($count calls): $message") + println(s"${ErrorLog.depTag} $sourceLoc ($count calls): $message") } errors foreach println if (!deprecations.isEmpty) { - println(s"$warnTag ${Console.YELLOW}There were ${deprecations.size} deprecated function(s) used." + + println(s"${ErrorLog.warnTag} ${Console.YELLOW}There were ${deprecations.size} deprecated function(s) used." + s" These may stop compiling in a future release - you are encouraged to fix these issues.${Console.RESET}") - println(s"$warnTag Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:") - println(s"$warnTag In the sbt interactive console, enter:") - println(s"""$warnTag set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")""") - println(s"$warnTag or, in your build.sbt, add the line:") - println(s"""$warnTag scalacOptions := Seq("-unchecked", "-deprecation")""") + println(s"${ErrorLog.warnTag} Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:") + println(s"${ErrorLog.warnTag} In the sbt interactive console, enter:") + println(s"""${ErrorLog.warnTag} set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")""") + println(s"${ErrorLog.warnTag} or, in your build.sbt, add the line:") + println(s"""${ErrorLog.warnTag} scalacOptions := Seq("-unchecked", "-deprecation")""") } val allErrors = errors.filter(_.isFatal) val allWarnings = errors.filter(!_.isFatal) if (!allWarnings.isEmpty && !allErrors.isEmpty) { - println(s"$errTag There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} and ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.") + println(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} and ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.") } else if (!allWarnings.isEmpty) { - println(s"$warnTag There were ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.") + println(s"${ErrorLog.warnTag} There were ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.") } else if (!allErrors.isEmpty) { - println(s"$errTag There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} during hardware elaboration.") + println(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} during hardware elaboration.") } if (!allErrors.isEmpty) { |
