250 likes | 380 Views
Macrodebugging: Global Views of Distributed Program Execution. Tamim Sookoor, Timothy Hnat, Pieter Hooimeijer, Westley Weimer, and Kamin Whitehouse. Motivation. command result_t StdContro.init() { call Leds.init(); return SUCCESS; } …. command result_t StdContro.init() {
E N D
Macrodebugging: Global Views of Distributed Program Execution Tamim Sookoor, Timothy Hnat, Pieter Hooimeijer, Westley Weimer, and Kamin Whitehouse
Motivation command result_t StdContro.init() { call Leds.init(); return SUCCESS; } … command result_t StdContro.init() { call Leds.init(); return SUCCESS; } … command result_t StdContro.init() { call Leds.init(); return SUCCESS; } … >> break BlinkM.nc:18 breakpoint 1 is inserted >> next BlinkM.nc:19 is reached >> print state 0 ERROR >> print state 1 >> print state 0
Macrodebugging 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 6: baseDisplay(lightVals(leader)) 7: end 1 10 10 10 10 >> break(4) >> step >> nLightVals 3 nLightVals = (1, 1) 525 (1, 2) 590 (2, 1) 525 (2, 2) 590 (2 ,3) 498 … … … 8 8 8 8 7 7 7 7 2
Contributions • Implementation named MDB • Post-mortem debugger • Source-level debugging • Hypothetical code changes • Trace Analysis • Summary of results • Less than 300 bytes RAM • Logging code executes < 0.5 % of execution time • Energy overhead: MDB: 30 %, MDB-Lite: 0.9 %
Outline • Implementation • Features • Views of global state • View effect of code changes • Search for bugs • Evaluation
Implementation 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 6: baseDisplay(lightVals(leader)) 7: end 1 1 2 3 4 5 6 7 1 2 2 3 4 5 7 1 2 3 4 5 7 3 Time
Outline • Implementation • Features • Views of global state • View effect of code changes • Search for bugs • Evaluation
Views of Global State 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 6: baseDisplay(lightVals(leader)) 7: end Asynchronous 1 1 2 3 4 5 6 7 1 2 2 3 4 5 7 1 2 3 4 5 7 3 t Time
Views of Global State • Our Solution: two views • Logically synchronous: state of all nodes at the same global operation • Temporally synchronous: state of all nodes at the same time
Logically Synchronous 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 6: baseDisplay(lightVals(leader)) 7: end >> break (5) >> step >> step(-1) >> step(-1) Time Travel 1 1 2 3 4 5 6 7 1 2 2 3 4 5 7 1 2 3 4 5 7 3 Time
Temporally Synchronous 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 6: baseDisplay(lightVals(leader)) 7: end >> jump(10000) >> tstep 1 1 2 3 4 5 6 7 1 2 2 3 4 5 7 1 2 3 4 5 7 3 Time
Outline • Implementation • Features • Views of global state • View effect of code changes • Search for bugs • Evaluation
View Effects of Code Changes 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 6: baseDisplay(lightVals(leader)) 7: end 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 5a: barrier 6: baseDisplay(lightVals(leader)) 7: end Expensive
Hypothetical Change 1: lightVals = macrovector(motes) 2: nLightVals = reflection(lightVals) 3: every(1000) 4: lightVals = lightSensors.sense() 5: leader = find(max(nLightVals)) 5a: barrier 6: baseDisplay(lightVals(leader)) 7: end 1 2 3 1 4 5 6 7 1 2 3 7 5 2 4 1 2 3 4 5 7 3 Time
Testing Bug Fixes • Implemented 4 hypothetical changes: • Barrier • Delayed Execution • Cache coherence • Cache expiration
Outline • Implementation • Features • Views of global state • View effect of code changes • Search for bugs • Evaluation
Searching for Bugs >> nLightVals(3, :, :) nLightVals(3, :) >> mean(nLightVals(3, :, :)) >> find(lightVals(3, :) > 1000)
Outline • Implementation • Features • Views of global state • View effect of code changes • Search for bugs • Evaluation
Experimental Setup • MDB used to debug three applications: • Surge • Acoustic Monitoring • Object Tracking • Combination of testbed and simulation • Three evaluation metrics • Flash overhead • CPU overhead • Energy overhead
Flash Overhead 288 Bps 137 Bps 31 Bps Surge Acoustic Tracking Can store at least 1hr with current 1 MB flash
CPU Overhead Application Logging 0.3% 5.6% 0.1% Percentage of execution time 4.4% 0.1% 2.1% Surge Acoustic Tracking Almost no CPU overhead!
Energy Overhead Some energy overhead Lightweight version has almost no energy overhead 28.1 mW Eliminates Heisenbugs 21.6 mW 21.8 mW No MDB MDB MDB Lite
Inspiration Source code: Clairvoyant , Marionette Log-and-replay: EnviroLog Global views/analysis: DustMiner, LiveNet, Sympathy, SNMS
Conclusions • MDB provides views of global state • MDB is the first debugger for WENs to allow: • inspection of application state • searching for bugs over time • testing fixes before deploying
Thank You • Demo this afternoon • 2:30 – 5:00 • Code release: • http://www.cs.virginia.edu/sookoor/mdb.php