Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set StageError cause in ChiselStage #1382

Merged
merged 2 commits into from
Mar 26, 2020
Merged

Conversation

seldridge
Copy link
Member

Change ChiselStage to set the cause of a StageError due to a ChiselException to be the ChiselException. This should fix issues where libraries that want to inspect the stack trace can do so. Previously, this would do stack trace trimming and drop a no-cause StageError.

Related issue: #1114 (comment)

Type of change: bug report

Impact: no functional change

Development Phase: implementation

Signed-off-by: Schuyler Eldridge <[email protected]>
@seldridge seldridge requested review from ucbjrl and jackkoenig March 21, 2020 20:21
@seldridge seldridge requested a review from a team as a code owner March 21, 2020 20:21
Copy link
Contributor

@chick chick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok. Should there be a test to illustrate?

@jackkoenig
Copy link
Contributor

Looks good to me as well. One thing I was wondering, instead of printlning the trimmed stack trace ourselves, what would happen if we override some of the methods in Throwable? https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html

Perhaps then we can use normal printStackTrace() for both and it will make it easier for custom Stages to compose with this

@ucbjrl
Copy link
Contributor

ucbjrl commented Mar 23, 2020

Unfortunately, this by itself, isn't sufficient. Driver.execute catches StageError exceptions and returns an error:

    val annosx = try {
      phases.foldLeft(annos)( (a, p) => p.transform(a) )
    } catch {
      /* ChiselStage and FirrtlStage can throw StageError. Since Driver is not a StageMain, it cannot catch these. While
       * Driver is deprecated and removed in 3.2.1+, the Driver catches all errors.
       */
      case e: StageError => annos
    }

    view[ChiselExecutionResult](annosx)

which eventually gets converted into another zero information exception in chisel3.iotesters.setupTreadleBackend:

    chisel3.Driver.execute(optionsManager, dutGen) match {
      case ChiselExecutionSuccess(Some(circuit), _, Some(firrtlExecutionResult)) =>
        ...
      case _ =>
        throw new Exception("Problem with compilation")
    }

@jackkoenig
Copy link
Contributor

@ucbjrl I think we should reconsider how we compose things and update those places to not catch Errors. As described in the Java documentation: "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."

@ucbjrl
Copy link
Contributor

ucbjrl commented Mar 23, 2020

Perhaps it's time to revisit #361?

@seldridge
Copy link
Member Author

Good catch, @ucbjrl.

I expect the Driver shouldn't be catching anything. In 3.1.5 it didn't... This fails some DriverSpec tests, though (checking what's going on).

Hot take: the sooner we can remove Driver, the sooner we can move to a unified exception model...

@seldridge
Copy link
Member Author

Actually, @ucbjrl: I think what's happening is the correct behavior of stack trace trimming:

  1. Elaboration fails and ChiselStage will print a verbose trimmed stack trace on stdout
  2. A StageError gets thrown
  3. The Driver converts this to a ChiselExecutionFailure
  4. iotesters converts this to an information-less exception

Even though (4) happens, the information is still provided to the user. This is, as far as I can tell, how #931 was intended to work.

The contract of StageError is that the thrower is providing all information to the user to debug the problem (here, a trimmed stack trace on stdout). Hence, StageError may legally provide zero information on what is going on because the thrower has already provided that information. This is likely an anti-pattern.

@jackkoenig has suggested that stack trace trimming should instead directly manipulate the stack trace. This may be a better approach. Perhaps we should implement something like this instead?

@ucbjrl
Copy link
Contributor

ucbjrl commented Mar 23, 2020

Right, the problem is the failure isn't available programmatically (without some contortions). Chisel is a library and may not always be the top application. One could argue that we shouldn't be printing errors without some negotiation with/advice from the enclosing application.

@jackkoenig
Copy link
Contributor

Printing generally isn't great, imagine if there's bug in MIDAS Chisel code that isn't supposed to be exposed to the user, they can catch and report a better user error, but Chisel is still going to print the stack trace as if the Chisel code itself is user code.

I think there's general agreement about finding a more composable solution, the real question is if we should do this for 3.3 or perhaps do this for 3.4.

@seldridge
Copy link
Member Author

Hot take 2️⃣: We're late enough on 3.3, let's just fix it. (I volunteer...)

@chick chick added this to the 3.3.0 milestone Mar 23, 2020
Copy link
Contributor

@ucbjrl ucbjrl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, lgtm

@ucbjrl ucbjrl merged commit 8184590 into master Mar 26, 2020
@ucbjrl ucbjrl deleted the StageError-wraps-ChiselException branch March 26, 2020 20:27
jackkoenig pushed a commit that referenced this pull request Feb 28, 2023
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants