Skip to content

Basic stacktrace augmentation #493

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
qwwdfsad opened this issue Aug 14, 2018 · 0 comments
Closed

Basic stacktrace augmentation #493

qwwdfsad opened this issue Aug 14, 2018 · 0 comments
Assignees
Milestone

Comments

@qwwdfsad
Copy link
Collaborator

qwwdfsad commented Aug 14, 2018

After #333 we can do a basic [pluggable? opt-in or opt-out?] stacktrace augmentation on throw call-site.

The basic idea is to attempt to reflectively instantiate exception of the same type at throw call-site with original exception as a cause.

For example currently this code

val deferred = async {
  throw IllegalStateException("Some invariant failed")
}

try {
  deferred.await()
} catch (t: Throwable) {
  t.printStackTrace()
}

will print

java.lang.IllegalStateException: Some invariant failed
  at kotlinx.coroutines.experimental.AsyncJvmTest$simpleTest$1$deferred$1.doResume(AsyncJvmTest. 
 kt:15)
  at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:42)
  at kotlinx.coroutines.experimental.DispatchedTask$DefaultImpls.run(Dispatched.kt:149)

after stacktrace augmentation it will be

java.lang.IllegalStateException: java.lang.IllegalStateException: Some invariant failed

  at kotlinx.coroutines.experimental.AsyncJvmTest$simpleTest$1.doResume(AsyncJvmTest.kt:21)
  at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:42)
  at kotlinx.coroutines.experimental.DispatchedTask$DefaultImpls.run(Dispatched.kt:149)
  at kotlinx.coroutines.experimental.DispatchedContinuation.run(Dispatched.kt:13)
  at kotlinx.coroutines.experimental.EventLoopBase.processNextEvent(EventLoop.kt:132)
  ....
  at kotlinx.coroutines.experimental.AsyncJvmTest.simpleTest(AsyncJvmTest.kt:13) // <- WHERE EXCEPTION IS ACTUALLY THROWN
Caused by: java.lang.IllegalStateException: Some invariant failed
  at kotlinx.coroutines.experimental.AsyncJvmTest$simpleTest$1$deferred$1.doResume(AsyncJvmTest.kt:15)
  at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:42)
  at kotlinx.coroutines.experimental.DispatchedTask$DefaultImpls.run(Dispatched.kt:149)

FJP for FJ-tasks does exactly the same: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/concurrent/ForkJoinTask.java#l582

@qwwdfsad qwwdfsad self-assigned this Aug 14, 2018
qwwdfsad added a commit that referenced this issue Sep 14, 2018
…lders) and channels

  * Implement CoroutineStackFrame in CancellableContinuationImpl, DispatchedContinuation and withContext
  * On coroutine resumption try to reflectively instantiate exception instance of the same type, but with augmented stacktrace
  * Augment stacktrace by walking over CoroutineStackFrame
  * Augment stacktrace on fast-path exceptions without CoroutineStackFrame walking to provide more context to an exception

Fixes #493
qwwdfsad added a commit that referenced this issue Sep 14, 2018
  * Agent automatically captures stacktrace when coroutine is created
  * Agent patches coroutine completion, so backtrace augmentation (#493) prepends creation stacktrace to the augmented stacktrace
  * Agent can be dynamically loaded and unloaded

Fixes #74
@qwwdfsad qwwdfsad added this to the Release 1.1 milestone Oct 26, 2018
qwwdfsad added a commit that referenced this issue Oct 29, 2018
…outine and AbstractChannel

  * Implement CoroutineStackFrame in CancellableContinuationImpl, DispatchedContinuation and ScopeCoroutine
  * On coroutine resumption try to reflectively instantiate exception instance of the same type, but with augmented stacktrace
  * Recover stacktrace by walking over CoroutineStackFrame
  * Recover stacktrace on fast-path exceptions without CoroutineStackFrame walking to provide more context to an exception
  * Unwrap exceptions when doing aggregation in JobSupport

Fixes #493
qwwdfsad added a commit that referenced this issue Oct 30, 2018
…outine and AbstractChannel

  * Implement CoroutineStackFrame in CancellableContinuationImpl, DispatchedContinuation and ScopeCoroutine
  * On coroutine resumption try to reflectively instantiate exception instance of the same type, but with augmented stacktrace
  * Recover stacktrace by walking over CoroutineStackFrame
  * Recover stacktrace on fast-path exceptions without CoroutineStackFrame walking to provide more context to an exception
  * Unwrap exceptions when doing aggregation in JobSupport

Fixes #493
qwwdfsad added a commit that referenced this issue Nov 2, 2018
  * Implement CoroutineStackFrame in CancellableContinuationImpl, DispatchedContinuation and ScopeCoroutine
  * On coroutine resumption try to reflectively instantiate exception instance of the same type, but with augmented stacktrace
  * Recover stacktrace by walking over CoroutineStackFrame
  * Recover stacktrace on fast-path exceptions without CoroutineStackFrame walking to provide more context to an exception
  * Unwrap exceptions when doing aggregation in JobSupport
  * Add kill-switch to disable stacktrace recovery, introduce method to recover stacktrace on the exceptional fast-path
  * Add `suspendCoroutineOrReturn` on exceptional fast-path in await in order to provide "real" stacktrace

Design rationale:
All recovery of *suspended* continuations takes place in Dispatched.kt file, the only place where all calls to "resume*" ends up, so we don't have to remember about stacktrace recovery in every primitive we are implementing. But to provide more accurate stacktraces we *have to* recover it on every fast-path for better debuggability.

Fixes #493
qwwdfsad added a commit that referenced this issue Nov 4, 2018
  * Implement CoroutineStackFrame in CancellableContinuationImpl, DispatchedContinuation and ScopeCoroutine
  * On coroutine resumption try to reflectively instantiate exception instance of the same type, but with augmented stacktrace
  * Recover stacktrace by walking over CoroutineStackFrame
  * Recover stacktrace on fast-path exceptions without CoroutineStackFrame walking to provide more context to an exception
  * Unwrap exceptions when doing aggregation in JobSupport
  * Add kill-switch to disable stacktrace recovery, introduce method to recover stacktrace on the exceptional fast-path
  * Add `suspendCoroutineOrReturn` on exceptional fast-path in await in order to provide "real" stacktrace

Design rationale:
All recovery of *suspended* continuations takes place in Dispatched.kt file, the only place where all calls to "resume*" ends up, so we don't have to remember about stacktrace recovery in every primitive we are implementing. But to provide more accurate stacktraces we *have to* recover it on every fast-path for better debuggability.

Fixes #493
qwwdfsad added a commit that referenced this issue Dec 6, 2018
  * Implement CoroutineStackFrame in CancellableContinuationImpl, DispatchedContinuation and ScopeCoroutine
  * On coroutine resumption try to reflectively instantiate exception instance of the same type, but with augmented stacktrace
  * Recover stacktrace by walking over CoroutineStackFrame
  * Recover stacktrace on fast-path exceptions without CoroutineStackFrame walking to provide more context to an exception
  * Unwrap exceptions when doing aggregation in JobSupport
  * Add kill-switch to disable stacktrace recovery, introduce method to recover stacktrace on the exceptional fast-path
  * Add `suspendCoroutineOrReturn` on exceptional fast-path in await in order to provide "real" stacktrace

Design rationale:
All recovery of *suspended* continuations takes place in Dispatched.kt file, the only place where all calls to "resume*" ends up, so we don't have to remember about stacktrace recovery in every primitive we are implementing. But to provide more accurate stacktraces we *have to* recover it on every fast-path for better debuggability.

Fixes #493
qwwdfsad added a commit that referenced this issue Dec 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant