Skip to content

[Prototype] exceptions stracktrace recovery #502

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

Closed
wants to merge 2 commits into from

Conversation

qwwdfsad
Copy link
Member

@qwwdfsad qwwdfsad commented Aug 20, 2018

  1. Provide entry-points for stack-trace recovery at the call-site (not at suspension point), which can be improved in 1.3
  2. First-class support in await and channel
  3. Enable only in debug mode

Things to do

  1. Discuss whether we want to hide this behavior under another system property
  2. Implement caching on JDK 1.7 with ClassValueMap (we can't use CHM because it will be a memory leak)
  3. Implement withContext support

Fixes #493 and (partially) #74

Use Continuation to restore stacktrace
First-class support in await() and Channel
Prefer constructor with arguments over empty constructor
@SUPERCILEX
Copy link
Contributor

This would be amazing! I currently do something very similar by injecting the callsite stacktrace as a fake cause of the suspension point exception.

@@ -144,7 +144,7 @@ public interface DispatchedTask<in T> : Runnable {
else {
val exception = getExceptionalResult(state)
if (exception != null)
continuation.resumeWithException(exception)
continuation.resumeWithException(recoverStackTrace(exception, continuation))
Copy link
Contributor

Choose a reason for hiding this comment

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

It makes sense to have cont.resumeWithStackTrace(exception) extension to simplify boiler-plate in all resumeWithException invocations.

// TODO multi-release JAR to cache in ClassValueMap
var newException: E? = null
try {
for (constructor in exception.javaClass.constructors.sortedBy { -it.parameterTypes.size }) {
Copy link
Contributor

Choose a reason for hiding this comment

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

sortedByDescending { it.parameterTypes.size } is longer, but more idiomatic.

@@ -766,7 +766,7 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
val state = this.state
if (state !is Incomplete) {
// already complete -- just return result
if (state is CompletedExceptionally) throw state.cause
if (state is CompletedExceptionally) throw recoverStackTrace(state.cause)
Copy link
Contributor

Choose a reason for hiding this comment

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

recoverStackTrace is missing from JobSupport.awaitSuspend(). Should find all useages of resumeWithException and systematically replace them.

return newException
}

private fun fillInStackTrace(continuation: Continuation<*>): ArrayList<StackTraceElement> {
Copy link
Contributor

Choose a reason for hiding this comment

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

It does not "fill" anything, so it should be called getStackTrace.

}

// TODO basic stub before 1.3
private fun stackTraceElement(continuation: Continuation<*>): StackTraceElement {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should return a nullable result. An object may not have a stack trace itself, but may be a completion. An good example here is CancellableContinuationImpl that should be supported.

}

internal actual fun <E : Throwable> recoverStackTrace(exception: E, continuation: Continuation<*>): E {
if (!DEBUG || exception is CancellationException || continuation !is CoroutineImpl) {
Copy link
Contributor

Choose a reason for hiding this comment

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

continuation !is CoroutineImpl is too restrictive for experimental coroutines. CancellableContinuationImpl shall be supported, too. It is needed for basic example that use Deferred.await(), for example.

@qwwdfsad qwwdfsad closed this Sep 14, 2018
@qwwdfsad qwwdfsad deleted the augment-exception branch April 23, 2019 11:52
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.

3 participants