All crashes are the result of the execution of a single machine instruction, but their causes are manifold. A typical cause is when the program counter loses track of the correct execution path, due to an earlier bug. In such a case it is quite common for the processor to attempt to execute data or random memory values. Since all data are possible, but only some of these are valid instructions, this very often results in an illegal instruction exception. One might say that the original bug that upset the program counter "caused" the crash, but the actual fault was an illegal instruction, possibly some time later. The art of debugging such crashes is connecting the actual cause of the crash (easily determined) with the code that set off the chain of events. This is often very far from obvious - the original bug may in fact be perfectly valid code from the processor's perspective.
An application typically crashes when it performs an operation which is not allowed by the operating system. The operating system then shuts down the application.
Typical errors that result in application crashes include:
An operating system crash often happens when a hardware exception occurs which cannot be handled, such as a hardware exception occurring within the operating system itself.
Operating system crashes can also occur when internal sanity-checking logic within the operating system detects that the operating system has lost its internal self-consistency.
In an ideal world, well-written operating systems should not be able to be crashed by application-level activity. However, this is not generally the case.
See also:
Application crashes
Operating system crashes