Download presentation
Presentation is loading. Please wait.
Published byClifford May Modified over 9 years ago
1
A Portable Virtual Machine for Program Debugging and Directing Camil Demetrescu University of Rome “La Sapienza” Irene Finocchi University of Rome “Tor Vergata”
2
Motivation Devising powerful methodologies and tools for assuring software reliability Directors reactive systems that monitor the run-time environment reacting to events generated by the processes What kind of events? Variable referencing, program interruption, memory allocation/ deallocation, function calls, memory accesses...
3
Difficulties of implementation Instrumenting source code programming efforts, flexibility Low-level OS primitives Instrumenting assembly code portability Interpreted execution (high level languages) efficiency
4
Directing through virtual machines Interpreting intermediate level languages (e.g., Java bytecodes) Capabilities of introspection Targeting multiple languages Targeting “difficult” languages (C, C++ need instructions to manipulate addresses) Running in reversible mode (very useful for error localization)
5
Our contribution The Leonardo Virtual Machine The Leonardo Virtual Machine Provides advanced facilities for implementing directors with low effort: Fine grained monitoring of memory accesses Reversible computing capabilities Continuous monitoring (not just on demand) by means of a flexible event handling mechanism
6
Architectural layers Hardware / operating system Leonardo Library (LL-Win32, LL-Qt) Leonardo Virtual Machine Native applications (editors, compilers) Interpreted applications (directors, visualizers, analysis tools) Virtual CPU Kernel
7
Virtual CPU Stack-based Only 5 registers About 100 elementary instructions About 180 lines of C code Handlers installed by external clients are executed at critical instructions (e.g., ld / st / jsr / rts )
8
2 bits per word Memory protection Typically, processes prevented from getting outside their logical address space … but how to avoid damages inside it? Memory mask for detecting illegal accesses to each memory word
9
Correctness of target address of calls to subroutine is checked at run time: 1 bit in the memory mask indicates if a memory word is a valid function entry point Code protection Correctness of jumps is checked statically
10
Stack protection 101 out of 107 VCPU instructions access the top of the stack Combine compile - time & run - time checking Static analysis to compute max stack usage in a subroutine Run-time checks necessary only on function calls ( jsr ) Run-time checks for overflow / underflow would be very inefficient
11
Reversibility State = registers + memory image Incremental log of state changes Only special points are checkpointable Log record = addresses + values of memory words changed in the transaction Forward execution: at each checkpoint a new log record is pushed onto a history stack Backward execution: the log record on the top of the history stack is used to restore the state
12
Optimizations Stack optimization: data over the top of the execution stack are not part of the state Buffering techniques to reduce I/Os Multiple changes of the same word are not saved saved in the log record transaction
13
Stack-preserving transactions A stack-preserving transaction pushes temporary data on the top of the stack and pop them leaving the final height unchanged LVM executables satisfy this property: transactions between consecutive checkpoints within the same subroutine are stack-preserving We support reversibility at different granularities
14
Event handling: an example void _MemAccessH(ui4 inBase, ui4 inSize){ ui4 theB1 = inBase/LINE; ui4 theB2 = (inBase+inSize-1)/LINE; if (sB != theB1) { sB = theB1; ++sMiss; } if (sB != theB2) { sB = theB2; ++sMiss; } ++sMems; } #include #define LINE 4096 static ui4 sMems; /* # of mem accesses */ static ui4 sMiss; /* # of cache misses */ static ui4 sB; /* current line address */
15
Event handling: an example /* install mem access handlers */ KNewAsyncEvtH(thePID, KMEM_READ_EVENT, 0, (KEvtHT)_MemAccessH); KNewAsyncEvtH(thePID, KMEM_WRITE_EVENT, 0, (KEvtHT)_MemAccessH); void main(){ } /* create new process */ ui4 thePID = KNewProc(“bubblesort.leo”, 0, 0); /* output results */ KPuts("# Mem accesses = "); KPrintlnUI4(sMems); KPuts("# Cache misses = "); KPrintlnUI4(sMiss); /* start process, wait for termination */ KStartProc(thePID); KWaitSyncEvtH(thePID, KHALT_EVENT,0, NULL);
16
Experiments: running times
17
Experiments: history log
18
Future work http://www.leonardo-vm.org/ Further information and source code at: Feedback is welcome! Trading time for space: a (partial) re-execution based approach to reversibility Implementation of directors: memory monitor tools for software visualization Just in time compilation
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.