rethinking the debugger

34
Iulian Dragos @jaguarul Rethinking the debugger

Upload: iulian-dragos

Post on 02-Jul-2015

147 views

Category:

Software


0 download

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.

TRANSCRIPT

Page 1: Rethinking the debugger

Iulian Dragos @jaguarul

Rethinking the debugger

Page 2: Rethinking the debugger

Overview

• Async Debugger

• Scala IDE for Eclipse 4.0

Page 3: Rethinking the debugger

Reactive applications

• Different parts of the application run in different logical threads

• ..the programmer must ensure correct coordination and communication

Page 4: Rethinking the debugger
Page 5: Rethinking the debugger
Page 6: Rethinking the debugger

Concurrency

• Threads and Locks are replaced by

• Futures

• Actors

• parallel collections (fork-join frameworks)

Page 7: Rethinking the debugger

Concurrency

• non-blocking

• often leads to callbacks

• flow of execution is not flow of program text

Page 8: Rethinking the debugger

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

Page 9: Rethinking the debugger

How do we debug asynchronous programs?

Page 10: Rethinking the debugger

Detective work

• go from undesirable effects back to causes

• attempt a fix

• repeat

Page 11: Rethinking the debugger

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!

Page 12: Rethinking the debugger

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

Page 13: Rethinking the debugger

Can we recover the async stack?

Record call stack when a future is created

Page 14: Rethinking the debugger

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)

Page 15: Rethinking the debugger

Chrome does it

Visual Studio does it, too

Page 16: Rethinking the debugger

Debugging Actors

Page 17: Rethinking the debugger

Debugging Actors

• Can we find out where a message was sent?

• what was the state at that point?

• IT’S THE SAME THING!

Page 18: Rethinking the debugger

Not just futures

• message sends (Akka, Scala actors)

• Play iteratees

• any composable asynchronous structure

• user-defined/data-flow debugging

Page 19: Rethinking the debugger

Debugging Actors

• Message-send is like an asynchronous method call

• “I’d really like to step-into that message send”

Page 20: Rethinking the debugger

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

Page 21: Rethinking the debugger

Demo Time!

Page 22: Rethinking the debugger

More tools

• Exception breakpoint: break on dead letters

• Logical Structure of an actor

• parent

• current sender

• supervisor strategy

Page 23: Rethinking the debugger

Future

• user-extensible points-of-interest

• filter collected data (by package, frame)

Page 24: Rethinking the debugger

Summary

Call Stack

Step Into

Exception breakpoint

Logical Structure

Async stack

Step-Message

Break on Dead Letters

Actor details

Page 25: Rethinking the debugger

Scala IDE for Eclipse 4.0 preview and roadmap

Page 26: Rethinking the debugger

Lithium release (4.0)

quiescence type-checking

quick fixes (implement abstract member)

multiple Scala version support

name hashing

stable API for plugins

Page 27: Rethinking the debugger

Community steps up

Page 28: Rethinking the debugger

4.0 community

Evaluate expression

Debugger improvements

Refactoring (extract..)

UI cleanups

wizards, hovers

completions

Page 29: Rethinking the debugger

Quiescence Typing

3.0.x 4.0.0-M2

Page 30: Rethinking the debugger

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

Page 31: Rethinking the debugger

What next?

Page 32: Rethinking the debugger

Sbt-server

• Delegate build to an Sbt (shared) process

• Directly import Sbt project

• Run any task

• Launch/debug Play apps

Page 33: Rethinking the debugger

GSoC project

• extensible IDE

• use Scala snippets to plug into the IDE

• Save Actions

• Debug Object rendering

• Auto-edits

Page 34: Rethinking the debugger

Contribute!