One way to detect the blocking of the door is to monitor the current through the motor. If it reaches a certain (high) value, you assume the motor is stalled and do *something*.
Limit switches are typically hard wired in such a way that they will remove power from the motor even if the rest of the circuit is still commanding that the motor continue to operate.
A simple example of a limit switch for a motor that can run in either direction is to have a blocking diode in series with the motor. This is normally shorted out by a switch, but this opens when the door (in this case) reaches the end of its travel. The diode prevents further current flowing in that direction (thus stopping the door). However it allows current to flow in the opposite direction (to open it). A similar technique is used at the other end of travel.
Another method would be to place the switches in series with relay coils. My garage door uses two SPDT relays to control the direction of travel. The limit switches could interrupt power to the relay which initiates movement in that direction. The problem here is that since the limit switches do not directly interrupt power to the motor, a failure in the relay (stuck ON for example) will cause the limit switch to be ineffective.
Going back another level to having the limit switches as inputs to a microcontroller, you have the problem that if the program crashes while the motor is turned on, the limit switch indication may be ignored.
To detect a stalled motor, the easiest thing is to detect excess current through the motor. This can be as simple as connecting a transistor across a current sense resistor so that a logic signal is generated when the voltage across the resistor exceeds 0.7V
What you do with this logic signal is then up to you, but note that using it to simply interrupt power to the motor is insufficient. It needs to feed back to the logic to stop or reverse the commanded action. You also may need a slight time delay as the high current may also flow during startup of the motor.