(1) and (2) are often the
hard part. Once you have observed or detected an error,
tracing the code in question can help
find the problem. Sometimes inserting calls to
into parts of the code where you think that the problem
might be can help to localise the error.
Ultimately, reading your code carefully will be part of the task. So it would be a good idea to write the code carefully in the first place, in order to make it easy to understand. See also error and warning messages and commenting and white space.