760 likes | 919 Views
Automated Extraction of Transition Systems from Component-model Architectures. Matt Hoosier. SAnToS Laboratory, Kansas State University, USA. http://cadena.projects.cis.ksu.edu. Overview. Distributed mission-critical software is starting a trend toward component-based middleware
E N D
Automated Extraction of Transition Systems from Component-model Architectures Matt Hoosier SAnToS Laboratory, Kansas State University, USA http://cadena.projects.cis.ksu.edu
Overview • Distributed mission-critical software is starting a trend toward component-based middleware • Some initial tools (one from KSU) have come along to help the design of such distributed real-time event-driven (DRE) software • I describe the work to automate model checker verification (more realistically, “bug finding”) of these mission-critical applications Extracting Transition Systems from Component Models
Outline • Component architectures • Cadena design and analysis tool for component architectures • Bogor model checking framework • Model checking Cadena projects • High-level approaches • Translation strategies • Evaluation vs. manually constructed models • Future work Extracting Transition Systems from Component Models
Component Organization A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only. A software component can be deployed independently and is subject to composition by third parties. Szyperski, Component Software Extracting Transition Systems from Component Models
Component Organization All communication with outside is through typed “ports” • Interface ports • Aggregation of operations on an object • Synchronous semantics just like any other OO method call • Event ports • Notification messages • Asynchronous semantics (“fire and forget”) Extracting Transition Systems from Component Models
Component Organization “Receptacle” “Facet” Required interface Provided interface Interface ports All communication with outside is through typed “ports” • Interface ports • Aggregation of operations on an object • Synchronous semantics just like any other OO method call • Event ports • Notification messages • Asynchronous semantics (“fire and forget”) Extracting Transition Systems from Component Models
Component Organization Publisher Subscriber Event ports “Source” “Sink” All communication with outside is through typed “ports” • Interface ports • Aggregation of operations on an object • Synchronous semantics just like any other OO method call • Event ports • Notification messages • Asynchronous semantics (“fire and forget”) Extracting Transition Systems from Component Models
Embedded Components • Real-time distributed component model very similar to the CORBA Component Model • Computation driven by a set of regular system interrupts (timeouts) • All components are passive; a threadpool with event-dispatching threads provides all the CPU time. Boeing’s Prism Avionics Middleware Extracting Transition Systems from Component Models
Prism Development Methodologies • Little abstract design • Natural language requirements often used directly to inspire C++ code • UML is often relegated to documentation, when kept in sync • Engineers want to reason about high-level “mode” transitions • Overall long-run control flow is hard to analyze manually • Formal verification tools would be useful here. • Open Experimental Program was established to solicit new tools to help in the design process. One was developed at KSU… Extracting Transition Systems from Component Models
Cadena Cadena CCM Interface Definition Language Java/C++ Component Code Product Line Customizations Model Checking State Transitions System Configuration <CONFIGURATION_PASS> <HOME> <…> <COMPONENT> <ID> <…></ID> <EVENT_SUPPLIER> <…events this component supplies…> </EVENT_SUPPLIER> </COMPONENT> </HOME> </CONFIGURATION_PASS> High-level Specification Language Eclipse Plug-In Prism XML Configurator Info Integrated Development Environment Analysis and QoS Aspect Synthesis Extracting Transition Systems from Component Models
Behavioral Specification The component is the unit of specification, so we’ll examine one of the more interesting ones. Extracting Transition Systems from Component Models
Behavioral Specification • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Extracting Transition Systems from Component Models
Structure Specification • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; CORBA Interface Definition Language (IDL): Structural Definitions Extracting Transition Systems from Component Models
Structure: Event Sources • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Event source port Extracting Transition Systems from Component Models
Structure: Event Sinks • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Event sink port Extracting Transition Systems from Component Models
Structure: Interface Consumers • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Remote interface client Extracting Transition Systems from Component Models
Structure: Interface Providers • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Interfaces accessible to others remotely (servers) Extracting Transition Systems from Component Models
Behavioral Specification Cadena Component Property Specification (CPS) • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Extracting Transition Systems from Component Models
Behavior: Mode Variables enum OnOffMode {enabled, disabled}; Small, bounded domains • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Behavior-control variables Like finite state control in an automaton Extracting Transition Systems from Component Models
Behavior: Handler Methods The event itself. Can carry payload (not used here). • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Handler method for event sink Extracting Transition Systems from Component Models
Behavior: Modal Control I/O Port Dependencies Differ • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Modal Control Flow Extracting Transition Systems from Component Models
Behavior: Dataflow • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Tracks inflow/outflow of values, but not computation Extracting Transition Systems from Component Models
Behavior: Event Propagation • componentBMModal { • providesChangeModemodeChange; • providesReadDatadataOut; • usesReadDatadataIn; • publishesDataAvailableoutDataAvailable; • consumesDataAvailableinDataAvailable; • modebmModalModeofcommon.OnOffMode • initcommon.OnOffMode.enabled; • behavior { • stringbuf; • handleinDataAvailable(DataAvailablee) { • casebmModalModeof { • common.OnOffMode.enabled: • buf := dataIn.data; • pushnewDataAvailable {} onoutDataAvailable; • common.OnOffMode.disabled: • } • } • … • } • }; Emit event through source port Extracting Transition Systems from Component Models
Event Correlation … + An A3 A2 A1 • Something introduced in Cadena to allow detection and reaction to complex patterns of events • Reduce network bandwidth • Keep components simple B Extracting Transition Systems from Component Models
Event Correlation: Example When a component only cares if each of two others has new data Correlator becomes a bona fide type: And Two event sink ports, and one (implicit) event source port DataAvailablecorrelation And ( DataAvailable e1, DataAvailable e2) e1 + e2 { case true: push new DataAvailable {}; } Extracting Transition Systems from Component Models
Prism Middleware Implementation Each middleware has its own method of achieving the abstraction of inter-component connections. Taken from “A Correlation Framework for the CORBA Component Model” [FASE ’04] Extracting Transition Systems from Component Models
Prism Middleware Implementation Abstractly… consume produce Taken from “A Correlation Framework for the CORBA Component Model” [FASE ’04] Extracting Transition Systems from Component Models
Prism Middleware Implementation Proxy Supplier … … … … … Event channel In reality… proxy dispatch consume threading timer/ thread pool queuing filtering network multiplexing produce consumer references Proxy Consumer proxy Taken from “A Correlation Framework for the CORBA Component Model” [FASE ’04] Extracting Transition Systems from Component Models
My Contributions • Implement front end of CPS language • Lexing, Parsing, Semantic Checking [with Jung, Greenwald] • Implement event correlation language • Front end again • Simulated implementation (re-used in model checking backend) • Automate the creation of checkable models from Cadena specification artifacts • Compiler from CPS Bogor input language • Generate OO structures to mimic component layout • Map CADL configuration Bogor input language API calls to initialize “embedded system” Extracting Transition Systems from Component Models
On the model checker used… Before diving into details about the translation, we give some general information about the model checker used. Extracting Transition Systems from Component Models
Bogor Model Checker Front-end Model Checking Components Lexer IStateMgr IActionTaker IBacktrackIF .bir Parser ISearcher IExpEvaluator ITransformer Type Checking IStateFactory IValueFactory ISchedulingStg .config Semantic Analyses • Developed at Kansas State University [Robby] • Actually, a framework with swappable modules • … as opposed to SPIN Verified Counter Example Extracting Transition Systems from Component Models
Bogor Modeling Language:BIR BIR = Bandera Intermediate Representation • Used as the intermediate language for the Bandera Tool Set for model-checking Java programs • Guarded command language • when <condition> do <command> • Native support for a variety of object-oriented language features • dynamically created objects and threads, exceptions, methods, inheritance, etc. Extracting Transition Systems from Component Models
BIR Example:2 Dining Philosophers right left right left Taken from the Bogor Tutorial [ETAPS ’04] Extracting Transition Systems from Component Models
BIR Example:2 Dining Philosophers systemTwoDiningPhilosophers { recordFork { booleanisHeld; } mainthreadMAIN() { Forkfork1; Forkfork2; locloc0: do { // create forks fork1 := newFork; fork2 := newFork; // start philosophers startPhil(fork1, fork2); startPhil(fork2, fork1); } return; } threadPhil(Forkleft, Forkright) { locloc0: // take left fork when !left.isHelddo { left.isHeld := true; } gotoloc1; locloc1: // take right fork when !right.isHelddo { right.isHeld := true; } gotoloc2; locloc2: // put right fork do { right.isHeld := false; } gotoloc3; locloc3: // put left fork do { left.isHeld := false; } gotoloc0; } } Extracting Transition Systems from Component Models
BIR Example:2 Dining Philosophers Uses a record to model forks systemTwoDiningPhilosophers { recordFork { booleanisHeld; } mainthreadMAIN() { Forkfork1; Forkfork2; locloc0: do { // create forks fork1 := newFork; fork2 := newFork; // start philosophers startPhil(fork1, fork2); startPhil(fork2, fork1); } return; } threadPhil(Forkleft, Forkright) { locloc0: // take left fork when !left.isHelddo { left.isHeld := true; } gotoloc1; locloc1: // take right fork when !right.isHelddo { right.isHeld := true; } gotoloc2; locloc2: // put right fork do { right.isHeld := false; } gotoloc3; locloc3: // put left fork do { left.isHeld := false; } gotoloc0; } } Extracting Transition Systems from Component Models
BIR Example:2 Dining Philosophers Thread declarations systemTwoDiningPhilosophers { recordFork { booleanisHeld; } mainthreadMAIN() { Forkfork1; Forkfork2; locloc0: do { // create forks fork1 := newFork; fork2 := newFork; // start philosophers startPhil(fork1, fork2); startPhil(fork2, fork1); } return; } threadPhil(Forkleft, Forkright) { locloc0: // take left fork when !left.isHelddo { left.isHeld := true; } gotoloc1; locloc1: // take right fork when !right.isHelddo { right.isHeld := true; } gotoloc2; locloc2: // put right fork do { right.isHeld := false; } gotoloc3; locloc3: // put left fork do { left.isHeld := false; } gotoloc0; } } Extracting Transition Systems from Component Models
BIR Example:2 Dining Philosophers threadPhil(Forkleft, Forkright) { locloc0: // take left fork when !left.isHelddo { left.isHeld := true; } gotoloc1; locloc1: // take right fork when !right.isHelddo { right.isHeld := true; } gotoloc2; locloc2: // put right fork do { right.isHeld := false; } gotoloc3; locloc3: // put left fork do { left.isHeld := false; } gotoloc0; } } Local variable declarations systemTwoDiningPhilosophers { recordFork { booleanisHeld; } mainthreadMAIN() { Forkfork1; Forkfork2; locloc0: do { // create forks fork1 := newFork; fork2 := newFork; // start philosophers startPhil(fork1, fork2); startPhil(fork2, fork1); } return; } Extracting Transition Systems from Component Models
BIR Example:2 Dining Philosophers threadPhil(Forkleft, Forkright) { locloc0: // take left fork when !left.isHelddo { left.isHeld := true; } gotoloc1; locloc1: // take right fork when !right.isHelddo { right.isHeld := true; } gotoloc2; locloc2: // put right fork do { right.isHeld := false; } gotoloc3; locloc3: // put left fork do { left.isHeld := false; } gotoloc0; } } Control locations systemTwoDiningPhilosophers { recordFork { booleanisHeld; } mainthreadMAIN() { Forkfork1; Forkfork2; locloc0: do { // create forks fork1 := newFork; fork2 := newFork; // start philosophers startPhil(fork1, fork2); startPhil(fork2, fork1); } return; } Extracting Transition Systems from Component Models
BIR Example:2 Dining Philosophers When condition is true Execute these statement(s) atomically Trivially true guards …aka “guarded transitions”, “guarded commands” Guarded transformations threadPhil(Forkleft, Forkright) { locloc0: // take left fork when !left.isHelddo { left.isHeld := true; } gotoloc1; locloc1: // take right fork when !right.isHelddo { right.isHeld := true; } gotoloc2; locloc2: // put right fork do { right.isHeld := false; } gotoloc3; locloc3: // put left fork do { left.isHeld := false; } gotoloc0; } } Extracting Transition Systems from Component Models
Modeling Approach • Use Bogor model checker • Extend Bogor input language with primitives specific to DRE software • Build translator to map CPS specifications into Bogor input language constructs • Exploit knowledge of runtime scheduling policies to reduce interleavings • Integrate whole thing into Cadena for instant model checking Extracting Transition Systems from Component Models
Publish/Subscribe Primitives Add abstract types (like channels in SPIN) extensionCADforSystemModule { // declaration of abstract types typedefEvent; typedefComponent; // constructors expdefCAD.Component createComponent(string); expdefCAD.EventcreateEvent<'a>('a); // manipulation of subscriber lists actiondefaddSubscriberList(CAD.Component, string); actiondefaddSubscriber<'a>(CAD.Component, string, 'a); expdef'a[] getSubscribers<'a>(CAD.Component, string); } recordSubscriber { EventHandlerTypehandlerFunction; stringportName; } functionfireEventFromComponent( CAD.ComponentsourceComp, stringport, CAD.Eventevent) {} Populate/query subscriber lists } Unit of subscribership } Event multiplexing and queuing Extracting Transition Systems from Component Models
Publish/Subscribe Primitives: Event Correlators extensionCorrelatorforCorrelatorModule { // abstract type for correlator; encapsulates acceptor automaton typedeftype; // Constructor: builds complete automaton from spec. string expdefCorrelator.typecreate(string); // Handle incoming event and dump a newly allocated ‘evtType // into the list for each compound event triggered actiondefhandleEvent<'evtType>( Correlator.type, string, List.type<'evtType>); // subscriber list maintenance actiondefaddSubscriber<'a>(Correlator.type, 'a); expdef'a[] getSubscribers<'a>(Correlator.type); } // allow correlators to be consumers of component events recordCorrelatorSubscriberextendsSubscriber { … } // analagous to event multiplexing and queuing from components functionfireEventFromCorrelator(Correlator.typecor, CAD.Evente) { … } Extracting Transition Systems from Component Models
Interface Port Primitives extensionCADforSystemModule { // abstract type for provided (server) port typedefPort; // constructors expdefCAD.PortcreatePort(); // attach server ports to components actiondefregisterPort(CAD.Component, CAD.Port, string); expdefCAD.PortgetPort(CAD.Component, string); // put BIR function pseudo-references into ports (for named methods) actiondefsetPortMethodHandler<'a>(CAD.Port, string, 'a); expdef'agetPortMethodHandler<'a>(CAD.Port, string); // make client <-> server connections actiondefconnectPorts( Pair.type<CAD.Component, string>, Pair.type<CAD.Component, string> ); expdefPair.type<CAD.Component, string> getProvider( Pair.type<CAD.Component, string>); } Extracting Transition Systems from Component Models
Using the primitives function{|common.BMDevice.dataOut.data<get>()|}(…) returnsstring { … } CAD.ComponentGPS CAD.ComponentAirFrame server ports client port connections CAD.Port methods Extracting Transition Systems from Component Models
Why BIR Extensions? • Avoid slowdown of interpreting “uninteresting” procedures in BIR. • Only relevant parts of configuration go into state vector (sometimes none). • Atomicity of actiondef operations means no intermediate states to be stored. Extension API’s based loosely on work presented in “Model Checking Middleware-based Event-driven Real-time Embedded Software” [FMCO ’02] Extracting Transition Systems from Component Models
Remote Method Indirection • When a client calls a method on some receptacle interface, this must be mapped to the correct BIR function for the facet on the end of the connection • E.g, dataOut.data<get> is implemented by two completely separate functions on BMDevice and BMClosedED components • Client must know which to call! Extracting Transition Systems from Component Models
Remote Method Indirection Solution: • Require all facet methods that implement a particular interface method (ReadData.data<get>) to be enumerated as a BIR virtual function • Wrap client receptacle call in BIR function that looks up remote method host component and function name (prev. slide), then do BIR invoke virtual • Example (next slide)… Extracting Transition Systems from Component Models
Remote Method Indirection enum{|common.ReadData.data<get>()|} { {|common.BMClosedED.dataOut.data<get>()|}, {|common.BMDevice.dataOut.data<get>()|} } virtual{|common.ReadData.data<get>()|}on {|common.ReadData.data<get>()|} { {|common.BMClosedED.dataOut.data<get>()|} -> {|common.BMClosedED.dataOut.data<get>()|} {|common.BMDevice.dataOut.data<get>()|} -> {|common.BMDevice.dataOut.data<get>()|} } function{|common.ReadData.data<get><invoke>()|}( CAD.Componentconsumer, stringportName, stringmethodName) returnsstring { // CAD extension API calls to resolve remote facet component … // handlerFunction is vtable key, provider is CAD.Component result := invokevirtual{|common.ReadData.data<get>()|}( handlerFunction, provider) returnresult; } Generate a set of enumerated values, virtual table, and “lookup” function for each interface method used anywhere in a facet Extracting Transition Systems from Component Models
Value Storage extensionCADforSystemModule { expdefbooleanhasAttribute(CAD.Component, string); expdef'agetAttribute<'a>(CAD.Component, string); actiondefsetAttribute<'a>(CAD.Component, string, 'a); } • Persistent simple variables (modes, buffers) must be stored • We add an internal key-value table indexed by variable name inside each CAD.Component • Only the keys and values are exposed in Bogor’s state vector; avoids lots of data structure overhead Mode variable appears asr-value: use getAttribute() Mode variable appears asl-value: use setAttribute() Extracting Transition Systems from Component Models
Constants • CPS is purposely abstract. It allows only enumerated type constants (no int or other scalars). • All CCM enumerated types are visible to CPS, plus private domains of mode variables. E.g., • IDL:enum OnOffMode { enabled, disabled }; • CPS:mode amEnabled of { enabled, disabled } init enabled; • Generates… Extracting Transition Systems from Component Models