By Paul D. Stachour
Honeywell Computer Sciences Center
March 26, 1984
Dr. Paul Stachour of the Honeywell Computer Sciences Center will speak about software maintenance
He will provide a definition of software maintenance and contrast it with other forms of maintenance
Dr. Stachour will discuss the four approaches (traditional, never, discrete and continuous) used in the software industry
Dr. Stachour believes that today's reliability and the non-stop systems's requirements make the continuous approach the the only practical one. None of the other approaches allows the dynamic maintenance of running systems.
He further believes that continuous maintenance is impossible on most of today's systems using most programming languages. He will describe in detail one well-know implementation of the continuous approach.
This is a talk contrasting state-of-the-art with state-of-the-practice.
The material used in today's presentation is taken from twenty years of personal experience in designing, implementing and maintaining medium - and large-scale computer software. This experience is on a variety of operating systems from a variety of manufacturers using a variety of programming languages.
This talk presents the results on introspection into computing practitioners ' attitudes and behaviors, not the results of planned experiments or theoretical research.
All data presented today comes from the personal experience of the and represents (only) his own views of the processes and practices prevalent within the software industry.
Observation
Definition
Approaches
Implementation of the Continuous approach
Conclusion
Software is the only industry where the equivalent of adding a six-lane automobile expressway to a railroad bridge could even be classified as maintenance.
Maintain
2b. To keep in a certain condition or position, especially efficiency, good repair, etc, as the state maintains the roads
Maintenance:
1. a maintaining or being maintained; upkeep, support, defense, etc.
Characteristics of Software maintenance
a) It does not wear out in a physical sense
b) any aging characteristics are easily bypassed
c) most "Real Maintenance" is for implementation errors
d) also Requirement/Design errors
e) enhancement (New Function)
f) whimsical change (including people/procedures/laws)
Maintenance in other professions and of other articles is concerned with the return of the item to its original state; in Software, maintenance is concerned with moving an item away from its original state (From a presentation by Les Belady.)
Software Maintenance is all activities associated with the process of changing software.
The general categories are "error-correction" and "remedying inadequacies".
This includes all change associated with "bug fixes" to previous software, functional and performance enhancements, providing back-compatibility and covering up hardware errors, creating user-interface access methods and other cosmetic changes, and updating to a new method-of-performing a function.
Axiom 1
An x that isn't designed to be maintained can't be maintained
Observation
Most programs aren't designed to be maintained
Corollary
Most programs are unmaintainable
Observation
The only constant is change
Question
Is it possible to design software so it can be maintained ?
Answer
Yes it is. But we don't.
Approach 1: Traditional - Everyone's Senior project
Write software any way you like, and fix the bugs when you find them; if you can.
Approach 2: Never - DoD Embedded Systems
Design perfect specifications and interfaces, never change them.
Change only the implementation, and then only for bug-fixes before the product is released.
Approach 3: Discrete Approach - Batch Operating Systems
Define hard-and-fast, highly configuration-controlled interfaces to elements of software; massive all-at-once changes.
Approach 4: Continuous Approach - Multics
Define both code and data interfaces that can evolve as changes happen
Characterization:
Don't even think about the possibility of maintenance.
Practice
Hard Coding of elements
Code
Data structures
No named constants
No macros
No subroutines
No local variables
No understandable organization
Names too short to be understood
No block or in-line comments
Incomplete separation of functions/operations
All modules dependent on externals
Gross mismatch between structure of problem and structure of solution
Examples
we all know far too many.
Notes
this is what most of us do at times.
Characterization
Design "perfect" specifications
Validate specifications against the real-world
Code to these specifications
Verify the code against the specifications
Test "forever" to find compiler errors / os problems / timings
Never change once running
Practice
Specification frozen, but faulty
Specification unvalidatable
Specifications not adhered to when code is written
Program not proven correct
Testing continues so long that programs are late
Replaced as a complete entity
Examples
DoD embedded systems
Microwave ovens
Washing machines
Notes
Ada will be a tremendous help in this area.
Characterization
Accept (reluctantly) the fact of change
Keep a parts-list and tools-list on every item
Allow only pre-authorized changes
Interface and functions statically configuration controlled.
All servers/user change in one discrete step
Practice
Change happens more often and in more places than predicted
All components of an item are not recorded
Patching is alive (and unfortunately thriving) due to time-lag for authorization and rebuild-time for system
Official interfaces controlled, unofficial interfaces proliferate, varying problems later
Data structures so "available" that even when change is desired, it is impossible to change due to impact
Never can the singe-step change be done
Multiple change interrelationships conflict
Networks mean multiple versions are simultaneously current
owners/users want to control change date
Examples
IBM OS/360
Notes
Experience shows that it is completely unrealistic to expect that all users of an interface (i.e., all users to whom an interface is visible) change at the same time.
Characterization
Understand that the only constant is change
Migration (for hardware, software and function) during system operation is necessary
Change must be designed from the very beginning
Practice
Weakly typed HLL and good macro assembler
No direct reference to anything if it can be avoided
Every data structure designed for expansion and self-identifying as to version
Every code segment built self-identifying by the compiler or other construction procedure
code/data changeable on a per command/process/system basis
As few copies a possible of anything (reference philosophy) which can be dynamically updated as necessary
Examples
ARPANET Backbone (BBN)
Honeywell Multics (MIT/GE/Bell)
Notes
Hardware, operating systems, languages and practices all have a massive effect on the ease and efficiency of how one designs and implements software that one knows will change.
Good languages
Macro assembler
Weakly typed HLL
C
PL/1
Bad languages
Totally untyped languages
BCPL
Strongly typed languages
Pascal
Ada
Reasoning
Controlled, checkable change is needed
Untyped: no control
Strongly typed: too much control
Direct references destroy flexibility
Literal constants
Static array bounds
Enumeration realizations
Supervisor call numbers in instruction
Descriptor references in instruction
Static procedure binding
Static storage binding
"Any solvable problem in computer science can be easily solved by the right number of levels of indirection" (Morven's Methatheorem), W. Morven Gentleman , University of Waterloo.
Indirect references provide changeability
Symbolic constants
Array bounds via attributes or language functions
All machine instructions take parameters rather than implied addresses
Procedures are called indirectly and dynamically linked
Storage bound through process registry, not OS allocations
Designed for expansion and change
Absolute requirement
Example: based structure in PL/1
Contain version numbers (version identification)
Version numbers checked
Obsolete versions rejected
Not-quite-current version processed differently
Not-quite-current can be upgraded
Unimplemented versions rejected
Implications
Many different versions can exist simultaneously while upgrades take place at the user's convenience
Upgrades can happen automatically
Non-locality doesn't cause problems
Even non-obsolete versions or not-yet-available versions from sources like save-0taps is handled without any data-smashing
An example from Multics com_err_()
dcl 1 query_info aligned,
2 version fixed bin, /* Fixed-point binary */
2 switches aligned,
3 ..
Structure Elements
Version is the version number of the structure. (input) The version number must be set by the caller and identifies the format of the structure. The current version is a static variable named query_info_version_ in query_info.pl1.
Self-identification
Name
Version
Built by compiler or construction system
Dynamically changeable
Entry variables, e.g. PL/1
Per-process settable
(Example: always call user-shell instead of system-command-processor)
System installable/ deinstallable
Non-current version retained and used
Example
Multics system install mechanism (slow change)
Multics process initiate/terminate mechanism (fast change)
The Method of Access is Important
Don't make copies of objects; copies get out of synchronization
If there is only one copy of something in a system/process, it can be upgraded more-or-less transparently
This means not only objects, but reference to objects should have only one copy
Software maintenance isn't hard, it's easy
The theory and practice is more than ten years old [in 1984]
Note: no self- respecting data-processing manager would accept a first-generation vacuum-tube machine.
Question: why do we as software professionals, allow ourselves to
One answer: We did it so badly at first (or were forced to do so badly at first by inadequate and incomplete hardware ) that we painted ourselves into a corner, with no way to get out.
Another answer: It's to the benefit of a giant in the industry to make it impossible for users to move away from its hardware/software because it would cost the user too much to re-write everything (I only half believe this one)
A third answer: We've grown so fast that we haven't taken time to learn our own minimal past; our teachers don't even know we're all (including me) working in the era of the Barber Surgeon.
My own answer: I don't. I refuse. If I can't get a Multics or a Symbolics Lisp machine or a Macintosh or some other half-reasonable system, I'll quit.(However, I do limp along on some half- baked systems for some of my work. But I'll never accept it)
Get the software out now, and decide what its real function is later
Don't provide any place or space for
Logging
Test-points
Debugging
in any delivered software
Don't allow any room or facility for expansion
Design and build the hardware first.
Later decide how to shoehorn the software in.
Then wonder how to sandwich the changes in.
Chose a programming language that's inadequate to express either our application or packaging concepts.