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

Eliminate handler frames from Caught_Panic.stack_trace #12024

Merged
merged 13 commits into from
Jan 10, 2025

Conversation

JaroslavTulach
Copy link
Member

@JaroslavTulach JaroslavTulach commented Jan 9, 2025

Pull Request Description

Fixes #8153 by

  • creating a test that demonstrates the problem - c33d647
  • creating a simple fix - 0393b22
  • measuring impact of a simple fix on performance - done
  • refining the fix to avoid negative performance impact - c188d97

Important Notes

The expected refinement of the fix is going to:

  • record CatchPanicNode in PanicException when it is caught
  • add @ExportMessage Object getExceptionStackTrace() to control the stack trace of PanicException
  • when computing and recording getExceptionStackTrace of the PanicException skip frames between...
  • ... the node that is computing the stack and the recorded CatchPanicNode anchor

This will fix the most common scenario when a caught_exception.stack_trace is requested in the exception handler.

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • All code follows the
    Scala,
    Java,
  • Unit tests have been written where possible.

@JaroslavTulach JaroslavTulach added the CI: No changelog needed Do not require a changelog entry for this PR. label Jan 9, 2025
@JaroslavTulach JaroslavTulach self-assigned this Jan 9, 2025
@JaroslavTulach JaroslavTulach marked this pull request as draft January 9, 2025 06:55
@JaroslavTulach
Copy link
Member Author

JaroslavTulach commented Jan 9, 2025

creating a test that demonstrates the problem

Without any fix the test introduced by c33d647 fails on the CI:

Frames from exception handling should not be in the stacktrace:
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines<arg-0> (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:45:17-42)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.f5 (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:37:21-21)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.f4 (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:38:21-27)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.f3<arg-1> (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:41:21-27)
at Caught_Panic.stack_trace (built-distribution\enso-engine-2025.1.1-dev-windows-amd64\enso-2025.1.1-dev\lib\Standard\Base\2025.1.1-dev\src\Panic.enso:284:9-43)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.do_the_handling (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:30:22-45)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.my_exception_handler (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:35:17-44)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.f3 (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:40-41)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.f2 (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:42:21-27)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines.f1 (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:43:21-27)
at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines (test\Base_Tests\src\Runtime\Stack_Traces_Spec.enso:45:13-43)

because it contains forbidden frames do_the_handling and my_exception_handler. After 0393b22 the test should be fixed, but we have to verify the benchmarks:

Results:

Panics_And_Errors_10000_Panic

Good! Time to speed it up.

@JaroslavTulach JaroslavTulach added the CI: Clean build required CI runners will be cleaned before and after this PR is built. label Jan 9, 2025
@JaroslavTulach JaroslavTulach marked this pull request as ready for review January 9, 2025 16:46
@JaroslavTulach JaroslavTulach requested a review from 4e6 as a code owner January 9, 2025 16:46
@JaroslavTulach
Copy link
Member Author

Local benchmarking indicates everything is OK, but running final verification on the CI as well.

sbt:enso> std-benchmarks/benchOnly Panics_And_Errors
[info] Benchmark                               Mode  Cnt  Score   Error  Units
[info] Panics_And_Errors_10000.Dataflow_Error  avgt    2  0.052          ms/op
[info] Panics_And_Errors_10000.Panic           avgt    2  0.449          ms/op

Just like it always was.

Comment on lines 286 to 295
/**
* Whoever catches a {@code PanicException} should associate its location with it, so proper stack
* traces can be computed later. Because the stacktrace information is relative to the caught
* location
*
* @param node the node who caught the panic
*/
public final void assignCaughtLocation(CatchPanicNode node) {
this.caughtBy = node;
}
Copy link
Member

Choose a reason for hiding this comment

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

What happens if the panic is rethrown and caught again elsewhere? Should this keep the first catch location or be reassigned?

Copy link
Member Author

@JaroslavTulach JaroslavTulach Jan 10, 2025

Choose a reason for hiding this comment

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

That's a very good question. It points out that this all is just a heuristic with the goal (as stated in the description):

... fix the most common scenario when a caught_exception.stack_trace is requested in the exception handler

I will add a new

  • test with re-throw.
  • done here

Should this ... be reassigned?

Both CatchPanicNode and Node queryNode have to be on the stack for any transformation to happen. Thus yes, it has to be reassigned.

I will also add a test that

  • catches the panic
  • queries the stack_trace in the handler
  • stores the panic into a Vector
  • and then queries later
  • both stacks have to be identical

Done in 9a056e3

} else {
// materializes stack trace of non-Enso
// exceptions in case it is needed by the handler
TruffleStackTrace.fillIn(originalException);
Copy link
Member Author

@JaroslavTulach JaroslavTulach Jan 10, 2025

Choose a reason for hiding this comment

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

This path is now tested by a5d001b that throws JavaScript exception and checks its stacktrace.

out . should_contain "f4"
out . should_contain "f5"

top_lines.take (..While l-> l.starts_with "2nd:") . length . should_equal 11
Copy link
Member Author

Choose a reason for hiding this comment

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

The stack trace in this case is:

2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines<arg-1> (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:72:38-63)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check.f5 (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:44:17-17)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check.f4 (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:45:17-23)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check.f3<arg-1> (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:48:17-23)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check.rethrow_handler (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:39:13-36)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check.f3 (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:47-48)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check.f2 (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:49:17-23)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check.f1 (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:50:17-23)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.stack_trace_check (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:52:9-26)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines<arg-1> (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:72:17-77)
2nd: at Stack_Traces_Spec.add_specs.Stack_Traces_Spec.add_specs.lines (Base_Tests/src/Runtime/Stack_Traces_Spec.enso:71-72)

which I believe is exactly what we want.

Copy link
Member

Choose a reason for hiding this comment

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

Looks good I think.

@JaroslavTulach JaroslavTulach force-pushed the wip/jtulach/StackTrace8153 branch from 11f3266 to 64e4af5 Compare January 10, 2025 08:34
@JaroslavTulach JaroslavTulach force-pushed the wip/jtulach/StackTrace8153 branch from 67667bc to 5a8f973 Compare January 10, 2025 13:58
@JaroslavTulach JaroslavTulach merged commit 7d4110d into develop Jan 10, 2025
47 checks passed
@JaroslavTulach JaroslavTulach deleted the wip/jtulach/StackTrace8153 branch January 10, 2025 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: Clean build required CI runners will be cleaned before and after this PR is built. CI: No changelog needed Do not require a changelog entry for this PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

caught_panic.stack_trace includes stack frames from the handler itself
3 participants