bugs in the wires or, an exercise in language design david gay intel research berkeley
Post on 22-Dec-2015
214 views
TRANSCRIPT
Bugs in the Bugs in the WiresWires
or, or, An Exercise in An Exercise in
Language Language DesignDesignDavid Gay
Intel Research Berkeley
IntroductionIntroduction Observation 1: Observation 1:
debugging sensor network programs is harddebugging sensor network programs is hard Observation 2:Observation 2:
nesC makes nesC makes wiringwiring, i.e., connecting , i.e., connecting components of a nesC program, easy; this components of a nesC program, easy; this also means that it’s easy to miswirealso means that it’s easy to miswire example 1: forgetting to wire initialisation codeexample 1: forgetting to wire initialisation code example 2: mistakenly wiring components example 2: mistakenly wiring components
together twicetogether twice Goal: add a simple language extension to Goal: add a simple language extension to
catch these kinds of errorscatch these kinds of errors
Background: Modules and Background: Modules and WiringWiring
module BlinkM {module BlinkM { provides interface provides interface InitInit;; uses interface uses interface TimerTimer;;}}implementation {implementation { command Init.init() {command Init.init() { call Timer.setRate();call Timer.setRate(); }}
event Timer.fired() { }event Timer.fired() { }}}
interface interface InitInit { { command init();command init();}}
interface interface TimerTimer { { command setRate();command setRate(); event fired();event fired();}}
Interfaces are bi-directional. BlinkM can call setRate and must implement init and fired.
BlinkM
Init.init
Timer.fired
Timer.setRateC functions
function calls
Background: Background: ConfigurationsConfigurations
configuration Blink {configuration Blink { provides interface Init;provides interface Init;}}implementation {implementation { components TimerM, BlinkM;components TimerM, BlinkM; Init = BlinkM.Init;Init = BlinkM.Init; BlinkM.Timer -> TimerM.Timer;BlinkM.Timer -> TimerM.Timer;}}
interface Init {interface Init { command init();command init();}}
Init.init
Blink
interface Timer {interface Timer { command setRate();command setRate(); event fired();event fired();}}
TimerMTimer.fired
BlinkM
Init.init
Timer.firedTimer.setRate
Timer.setRate
Wiring Graph is Very Wiring Graph is Very FlexibleFlexible
Can build nearly arbitrary graphs, except:Can build nearly arbitrary graphs, except: module function nodes have 0-outdegreemodule function nodes have 0-outdegree module call nodes have 0-indegreemodule call nodes have 0-indegree
Wiring Bug ExamplesWiring Bug Examples BlinkM’s provided Init interface not wiredBlinkM’s provided Init interface not wired
BlinkM never gets initialisedBlinkM never gets initialised BlinkM’s provided Init interface wired BlinkM’s provided Init interface wired
twicetwice possible incorrect behaviourpossible incorrect behaviour
provided Timer interface non-shareable, provided Timer interface non-shareable, wired twicewired twice incorrect behaviour (wrong rate in one user)incorrect behaviour (wrong rate in one user)
used split-phase interface wired twiceused split-phase interface wired twice ex: ex: interface Send { command send(); event interface Send { command send(); event
sendDone(); }sendDone(); } two responses on every request, will two responses on every request, will
misbehavemisbehave
Wiring Bugs: The FixWiring Bugs: The Fix BlinkM’s provided Init interface not wiredBlinkM’s provided Init interface not wired
BlinkM never gets initialisedBlinkM never gets initialised BlinkM’s provided Init interface wired BlinkM’s provided Init interface wired
twicetwice possible incorrect behaviourpossible incorrect behaviour
provided Timer interface non-shareable, provided Timer interface non-shareable, wired twicewired twice incorrect behaviour (wrong rate in one user)incorrect behaviour (wrong rate in one user)
used split-phase interface wired twiceused split-phase interface wired twice ex: ex: interface Send { command send(); event interface Send { command send(); event
sendDone(); }sendDone(); } two responses on every request, will two responses on every request, will
misbehavemisbehave Fixes: restrict wiring cardinalityFixes: restrict wiring cardinality
≥ 1
= 1
≤ 1
= 1
Wiring Bugs: The FixWiring Bugs: The Fixmodule BlinkM {module BlinkM { provides interface Init provides interface Init @atleastonce@atleastonce;; uses interface Timer uses interface Timer @exactlyonce@exactlyonce;;}}implementation {implementation { command Init.init() {command Init.init() { call Timer.setRate();call Timer.setRate(); }} event Timer.fired() { }event Timer.fired() { }}}
@<attribute>: new syntax for annotations (see @<attribute>: new syntax for annotations (see Java 1.5)Java 1.5)
atmostonceatmostonce, , atleastonceatleastonce, , exactlyonceexactlyonce: : wiring annotations on provided, used interfaceswiring annotations on provided, used interfaces apply to each function in an interfaceapply to each function in an interface
imply a global check on program’s wiring graphimply a global check on program’s wiring graph
Bugs in Language DesignBugs in Language Design What do the annotations mean?What do the annotations mean? Obvious proposal: node in/out degreeObvious proposal: node in/out degree
≤1
Bugs in Language DesignBugs in Language Design What do the annotations mean?What do the annotations mean? Obvious proposal: node in/out degreeObvious proposal: node in/out degree
““Correct” answer appears to be:Correct” answer appears to be: provided functions: number of paths to this provided functions: number of paths to this
functionfunction used functions: number of paths from this used functions: number of paths from this
function callfunction call
≤1
Another ProblemAnother Problem What does this mean in a configuration?What does this mean in a configuration?
Is this program right? wrong?Is this program right? wrong?
provides interface Init @≤1
Another ProblemAnother Problem What does this mean in a configuration?What does this mean in a configuration?
Is this program right? wrong?Is this program right? wrong? Proposal: correct rule is:Proposal: correct rule is:
provided function: check number of paths to this provided function: check number of paths to this nodenode
used function: check number of paths from this nodeused function: check number of paths from this node note: for bi-directional interfaces, this means that note: for bi-directional interfaces, this means that
you check both the paths to and from the nodeyou check both the paths to and from the node
provides interface Init @≤1
Does this do all we want?Does this do all we want? Matched Matched
request/reply request/reply makes split-phase makes split-phase programs simplerprograms simpler Let’s use Let’s use exactlyonceexactlyonce!!
module Simple {module Simple { uses interface Send;uses interface Send;}}implementation {implementation { int state;int state; void somefn() {void somefn() { state = SENDING;state = SENDING; call Send.send();call Send.send(); }}
event Send.sendDone() {event Send.sendDone() { if (state == SENDING) …if (state == SENDING) … }}}}
interface Send {interface Send { command send();command send(); event sendDone();event sendDone();}}
Does this do all we want?Does this do all we want? Matched Matched
request/reply makes request/reply makes split-phase split-phase programs simplerprograms simpler Let’s use Let’s use exactlyonceexactlyonce!!
Code is simplerCode is simpler
module Simple {module Simple { uses interface Senduses interface Send @@exactlyonceexactlyonce;;}}implementation {implementation { void somefn() {void somefn() { call Send.send();call Send.send(); }}
event Send.sendDone() {event Send.sendDone() { … … }}}}
interface Send {interface Send { command send();command send(); event sendDone();event sendDone();}}
Does this do all we want?Does this do all we want? Matched request/reply Matched request/reply
makes split-phase makes split-phase programs simplerprograms simpler Let’s use Let’s use exactlyonceexactlyonce!!
Code is simplerCode is simpler Check is insufficient Check is insufficient
module Simple {module Simple { uses interface Senduses interface Send @@exactlyonceexactlyonce;;}}implementation {implementation { void somefn() {void somefn() { call Send.send();call Send.send(); }}
event Send.sendDone() {event Send.sendDone() { … … }}}}
Simple
=1
=1
send
sendDone
interface Send {interface Send { command send();command send(); event sendDone();event sendDone();}}
ConclusionConclusion Wiring bugs are hard to findWiring bugs are hard to find Some of these bugs can be caught with Some of these bugs can be caught with
annotations that restrict paths in the wiring annotations that restrict paths in the wiring graph:graph: atleastonceatleastonce: at least one path to/from here: at least one path to/from here atmostonceatmostonce: at most one path to/from here: at most one path to/from here exactlyonceexactlyonce: exactly one path to/from here: exactly one path to/from here
Does not cover all needsDoes not cover all needs could add could add singlepathsinglepath: all nodes in path have in/out : all nodes in path have in/out
degree at most onedegree at most one
The annotation syntax will be in nesC 1.2, and The annotation syntax will be in nesC 1.2, and will be user-extensible (see Java 1.5 specification will be user-extensible (see Java 1.5 specification for general idea)for general idea)