Design Article
Comment
Mario Blunk
John Smith
This is a very valuable post, I found it looking through Google. I believe most ...
High-integrity object-oriented programming with Ada - Part 1
Benjamin M. Brosgol, Senior Software Engineer, AdaCore
7/20/2011 8:11 PM EDT
OOP-Related Vulnerabilities
The Object-Oriented Technologies supplement to DO-178C3 identifies a number of vulnerabilities and provides guidance how to deal with them. They fall into several categories.
Storage Management
Storage predictability is essential for high-integrity systems. A stack overflow, or the failure of a dynamic allocation because of heap exhaustion or fragmentation, is unacceptable, and the developer needs to show that such errors are prevented.
Polymorphism in OOP makes this difficult. A polymorphic variable can denote objects from different classes at different times. Since a class may be added to an inheritance hierarchy after the code containing the declaration of a polymorphic variable has been compiled, the compiler cannot predict the maximum size for the object that the variable denotes. As a result, a compiler for an object-oriented language will implement polymorphic variables as references (pointers) to their denoted objects. Application code will generally use dynamic allocation to create such objects, so the developer needs to ensure that:
Whether and how these requirements are met depends on both the techniques used in writing the application code, such as avoidance of storage leaks and dangling references, and the implementation of the run-time library for storage management.
Some object-oriented languages, such as Java, provide automatic storage reclamation, also known as a garbage collector, instead of an explicit deallocation feature. A garbage collector prevents dangling references but complicates the software verification effort by introducing an element of nondeterminism — when, for example, is an inaccessible object reclaimed? The garbage collector, similar to any other run-time support library, is also subject to the same certification requirements as the application.
Note that the presence of a garbage collector does not by itself prevent storage leaks. An errant program with an infinite loop that adds nodes to a linked list will eventually exhaust the heap.
Inheritance, Substitutability, and Dynamic Dispatch
Inheritance is both a programming technique — defining a subclass as an extension of a superclass — and a type of theoretic and data modeling formalism. From the latter perspective, inheritance corresponds to the specialization relationship: if class C2 inherits from (is a subclass of) C1, then any instance of C2 is also an instance of C1, and thus any operation applied to a C1 instance should also work correctly (with dynamic dispatch) when applied to a C2 instance. This concept is referred to as the Liskov Substitution Principle4 (LSP). The problem is that inheritance as a general programming language feature can be misused to violate LSP.
Violation of LSP can lead to vulnerabilities in dynamic dispatch. A call that works correctly when applied to a polymorphic variable denoting an instance of a superclass can fail when the variable denotes an instance of a subclass, if the subclass does not conform to LSP. Further, in the context of DO-178B, it’s unclear what kinds of requirements-based tests and structural coverage analysis are needed to detect and prevent such errors. Testing each call for every possible subclass for a denoted object can lead to a combinatorial explosion and might not be necessary.
Next: Three Approaches
The Object-Oriented Technologies supplement to DO-178C3 identifies a number of vulnerabilities and provides guidance how to deal with them. They fall into several categories.
Storage Management
Storage predictability is essential for high-integrity systems. A stack overflow, or the failure of a dynamic allocation because of heap exhaustion or fragmentation, is unacceptable, and the developer needs to show that such errors are prevented.
Polymorphism in OOP makes this difficult. A polymorphic variable can denote objects from different classes at different times. Since a class may be added to an inheritance hierarchy after the code containing the declaration of a polymorphic variable has been compiled, the compiler cannot predict the maximum size for the object that the variable denotes. As a result, a compiler for an object-oriented language will implement polymorphic variables as references (pointers) to their denoted objects. Application code will generally use dynamic allocation to create such objects, so the developer needs to ensure that:
- No allocation request fails (i.e., the heap is large enough, it does not become fragmented, and there are no storage leaks).
- No object is deallocated while it is still accessible to the program (i.e., dangling references are prevented), if the language provides an explicit deallocation construct.
- The time required for allocation and deallocation is bounded and short enough so that all real-time deadlines are met.
Whether and how these requirements are met depends on both the techniques used in writing the application code, such as avoidance of storage leaks and dangling references, and the implementation of the run-time library for storage management.
Some object-oriented languages, such as Java, provide automatic storage reclamation, also known as a garbage collector, instead of an explicit deallocation feature. A garbage collector prevents dangling references but complicates the software verification effort by introducing an element of nondeterminism — when, for example, is an inaccessible object reclaimed? The garbage collector, similar to any other run-time support library, is also subject to the same certification requirements as the application.
Note that the presence of a garbage collector does not by itself prevent storage leaks. An errant program with an infinite loop that adds nodes to a linked list will eventually exhaust the heap.
Inheritance, Substitutability, and Dynamic Dispatch
Inheritance is both a programming technique — defining a subclass as an extension of a superclass — and a type of theoretic and data modeling formalism. From the latter perspective, inheritance corresponds to the specialization relationship: if class C2 inherits from (is a subclass of) C1, then any instance of C2 is also an instance of C1, and thus any operation applied to a C1 instance should also work correctly (with dynamic dispatch) when applied to a C2 instance. This concept is referred to as the Liskov Substitution Principle4 (LSP). The problem is that inheritance as a general programming language feature can be misused to violate LSP.
Violation of LSP can lead to vulnerabilities in dynamic dispatch. A call that works correctly when applied to a polymorphic variable denoting an instance of a superclass can fail when the variable denotes an instance of a subclass, if the subclass does not conform to LSP. Further, in the context of DO-178B, it’s unclear what kinds of requirements-based tests and structural coverage analysis are needed to detect and prevent such errors. Testing each call for every possible subclass for a denoted object can lead to a combinatorial explosion and might not be necessary.
Next: Three Approaches
Navigate to related information


EREBUS
7/21/2011 4:09 PM EDT
It is a shame that more software people did not understand or use the benefits of Ada. I understand the desire to get to the coding quickly, but from my observations over the last 30 years, you get much better software faster with Ada then you will ever get from C or C++.
A major part of this failure lies with managers who want to see instant results rather than see a well thought out software design. If you build code without a good design, you get bad software. Many managers do not understand the true issues involved with software engineering versus coding. Coding is about 5% of the job.
I really liked the real-time support built into Ada. I have seen it implemented for complex real time avionics software and it does a very good job.
Hopefully, we can get some solid Ada compilers for the microcontroller market. The cost to generate good solid firmware would be greatly reduced.
Ada is an excellent way to build software. The problem is that it requires the developers to think before they code. Sadly, most are too undisciplined to take the time to build software correctly.
Oh well, maybe someday.
Thanks
Sign in to Reply
cdhmanning
7/25/2011 10:08 PM EDT
From what I've seen, Ada is just too limited to be completely useful for general embedded development.
Ada might be good for writing some parts of the code, but not all. It is hard to partition many systems into stuff to be written in Ada and stuff that should not.
Ada seems particularly unsuited to writing device drivers, interrupt service routines and such.
You can get GNAT for ARM and even AVR.
Sign in to Reply
UncleFin
7/26/2011 10:58 AM EDT
I am not sure what "general embedded development" is, but the orgainization I belong has used Ada as the primary language for many of our avionic systems - ranging from small high integrity controllers to flight management systems.
Sign in to Reply
cdhmanning
7/27/2011 10:46 PM EDT
I can write a complete system in C, with a few lines of assembler for the start up code etc.
Can you do that in Ada? From what I've seen Ada RTEs are written in C or such because Ada isn't flexible enough.
Sign in to Reply
Powernine
10/24/2011 10:39 AM EDT
About being adequate for general and embedded development you can do in ADA what you can do in C (eg bit manipulation) except that it is safer and cleaner. You can aslo do things you cannot do in C like controlling the address a variable is stored in. In C you have to use pointers and lose all "compiler protection". In Ada you can do like that but haven't to and shouldn't to.
About RTEs the reason is because ADA vendors cut costs by using preexisting libraries and these are, unfortunately because they are a source of bugs, in C.
Sign in to Reply
Aaron451
8/4/2011 5:30 PM EDT
I used Ada '83 for several years do hard-realtime software (motor control) with great success. Now I do the same thing in 'C' and with for the Ada tools. It took a bit of time to learn, but once I got it down coding went fast and debugging was almost an after-thought. AND REAL code reuse was in the 80% range from project to project.
Sign in to Reply
Dixy3
7/21/2011 8:43 PM EDT
EREBUS, I totally agree with you, managers are always looking to cut corners to save on costs rather than have the best quality code for the job. Ada as a lot to offer given time for programmers to develop good code without additional pressure from their managers to complete the programming job like yesterday. May be it is time for someone to write a free Ada IDE for microprocessors like ARM and Arduino so developers and programmers can play at home on development boards and then start to use Ada at work in a more commercial environment? Ada I think would also be ideal for areospace nano satellites like CubeSats given the chance to develop it.
Sign in to Reply
Niklas Holsti
7/24/2011 2:59 PM EDT
Links in reply to Dixy3:
GNATDroid, a version of the GNU Ada compiler GNAT for Android: http://www.dragonlace.net/
AVR-Ada, a version of GNAT for the Atmel AVR chips: http://sourceforge.net/projects/avr-ada.
and the trump: an Ada compiler that generates C code and thus targets any system that has a C compiler: http://www.sofcheck.com/products/adamagic.html
The AdaMagic compiler is being used for a CubeSat project, I believe.
Sign in to Reply
cdhmanning
7/27/2011 11:14 PM EDT
If you really want to play, there's Ada for Lego Mindstorms robots...
http://libre.adacore.com/libre/tools/mindstorms/
Free download.
This runs on a small ARM micro and should be readily portable to other small ARM systems.
The Mindstorms Ada environment seems to use the Lejos code as its underpinnings. That is written in C.
Sign in to Reply
Ed Falis
7/26/2011 7:57 PM EDT
Here you go: http://www.cubesatlab.org/LunarLander/index.html
Sign in to Reply
John Smith
2/7/2012 5:07 AM EST
This is a very valuable post, I found it looking through Google. I believe most readers will agree with your views. Finally – a person with common sense!
http://www.zuneauto.com
Sign in to Reply
Mario Blunk
4/3/2012 9:17 AM EDT
Hi there,
I'm about to begin programming in a language other than assembly and shell programming. I'm also used to code hardware designs in Verilog HDL.
So I'm asking myself whether it is useful for me to start right with ADA and ignoring all the C/C++/Java... My mind has not been "spoiled" with this stuff :-) So what do you guys recommend ?
Sign in to Reply