The OS is necessary, but insufficient, part of the solution.
It's certainly insufficient. I'm not sure that it's even necessary. There
are mechanisms which the OS could provide and which a language could use,
but there are also mechanisms which don't require support from the OS.
The API is certainly part of the solution.
Agreed. The fact that ANSI C provides e.g. strcpy() but doesn't provide a
safe alternative (strncpy() won't NUL-terminate the string if it is
truncated) has been responsible for innumerable buffer overrun bugs.
Compilers are constrained by the language. Not only does C support
treating any pointer as an array, but arrays are automatically converted
to pointers when used in an expression or as a function argument.
Keeping track of the end (and ensuring that it isn't overrun) is the
programmer's responsibility.
[OTOH, C doesn't require that negative indices are supported, yet every
compiler which I've ever used allows this.]
If arrays were a first-class data type, containing both their start
address and length, many of the problems would go away.
Saying that the
"OS can't" do something is letting it completely off the hook.
I didn't say that it can't do "something", although I'm not sure that it
actually matters all that much.
Windows, or more accurately M$, *is* the problem.
Windows is no worse than any other OS when it comes to buffer overruns.
[And the NT/2K/XP branch is no worse when it comes to process isolation.
That's a separate issue to what I was talking about, but there seems to be
some confusion.]
The real problem is the widespread use of C/C++ as an application
programming language.
C was designed as a systems programming language, one step up from
assembler. In that area, you often need the flexibility of a language
which will let programmers do whatever they want, including shooting
themselves in the foot. You may also need the efficiency.
This isn't true for applications, where the additional overhead and
reduced flexibility of a higher level language wouldn't be a problem for a
word processor or web browser.
IMHO, Windows' weak point is its extreme complexity (sometimes I'm
convinced that Rube Goldberg is alive and well and working as a systems
programmer at Microsoft).
Windows doesn't crash because applications are allowed to trash system
memory. Windows crashes because Windows trashes system memory, because of
occasional programming errors multiplied by the massive size of the code
base.
[In this context, "system" memory doesn't have to be "kernel" memory.
Windows has lots of auxilliary "services", which run as normal
applications but without which the OS will effectively cease to function.]