Upload
iulian-dragos
View
153
Download
0
Embed Size (px)
DESCRIPTION
New abstractions for concurrency make writing programs easier by moving away from threads and locks, but debugging such programs becomes harder. The call-stack, an essential tool in understanding why and how control flow reached a certain point in the program, loses meaning when inspected in traditional debuggers. Futures, actors or iteratees make code easier to write and reason about, and in this talk I'll show a simple solution to make them easier to debug. The tool I present integrates well with the Eclipse plugin for Scala, and shows how a "reactive debugger" might look like.
Citation preview
Iulian Dragos @jaguarul
Rethinking the debugger
Overview
• Async Debugger
• Scala IDE for Eclipse 4.0
Reactive applications
• Different parts of the application run in different logical threads
• ..the programmer must ensure correct coordination and communication
Concurrency
• Threads and Locks are replaced by
• Futures
• Actors
• parallel collections (fork-join frameworks)
Concurrency
• non-blocking
• often leads to callbacks
• flow of execution is not flow of program text
Futures
val fTweets = Future { getAllTweets(user) } ! // also a future val nrOfTweets = fTweets.map(ts => ts.size) ! nrOfTweets onSuccess { println }
Execution continues without
waiting for all tweets
Futures can be chained
Callback for successful completion
How do we debug asynchronous programs?
Detective work
• go from undesirable effects back to causes
• attempt a fix
• repeat
The Call Stack
java.lang.Exception at test.FuturesTest$$anonfun$simpleUse$1$$anonfun$2$$anonfun$apply$1.apply$mcI$sp(Futur.. at test.FuturesTest$$anonfun$simpleUse$1$$anonfun$2$$anonfun$apply$1.apply(FuturesTest.sca.. at test.FuturesTest$$anonfun$simpleUse$1$$anonfun$2$$anonfun$apply$1.apply(FuturesTest.sca.. at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107) at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Futures use a thread pool for execution!
The Problem
• The call-stack used to record the flow of control of sequential programs
• futures (and actors) execute each computation step on a different thread
• on a mostly uninteresting call stack
Can we recover the async stack?
Record call stack when a future is created
Under the hood
• Intercept Future instantiation
• Save stack contents (all of it)
• Resume
• When a breakpoint is hit
• check async stacks store
• (overhead is comparable to conditional breakpoint)
Chrome does it
Visual Studio does it, too
Debugging Actors
Debugging Actors
• Can we find out where a message was sent?
• what was the state at that point?
• IT’S THE SAME THING!
Not just futures
• message sends (Akka, Scala actors)
• Play iteratees
• any composable asynchronous structure
• user-defined/data-flow debugging
Debugging Actors
• Message-send is like an asynchronous method call
• “I’d really like to step-into that message send”
Step-with-a-bang
• resume execution until the next message sent is received by an actor
• the receiving actor might run on a different thread
• other messages might be exchanged in the meantime
Demo Time!
More tools
• Exception breakpoint: break on dead letters
• Logical Structure of an actor
• parent
• current sender
• supervisor strategy
Future
• user-extensible points-of-interest
• filter collected data (by package, frame)
Summary
Call Stack
Step Into
Exception breakpoint
Logical Structure
Async stack
Step-Message
Break on Dead Letters
Actor details
Scala IDE for Eclipse 4.0 preview and roadmap
Lithium release (4.0)
quiescence type-checking
quick fixes (implement abstract member)
multiple Scala version support
name hashing
stable API for plugins
Community steps up
4.0 community
Evaluate expression
Debugger improvements
Refactoring (extract..)
UI cleanups
wizards, hovers
completions
Quiescence Typing
3.0.x 4.0.0-M2
Multiple Scala Version support
• Starting with Scala 2.11.0 and IDE 4.0-M2
• Presentation compiler works in (2.10) compatibility mode
• The build compiler is 2.10
• Can have multiple Scala versions in the same workspace
What next?
Sbt-server
• Delegate build to an Sbt (shared) process
• Directly import Sbt project
• Run any task
• Launch/debug Play apps
GSoC project
• extensible IDE
• use Scala snippets to plug into the IDE
• Save Actions
• Debug Object rendering
• Auto-edits
Contribute!