Positive thinking
Simplify the problem
Genetic mutation
Use a debugger
Use tracing code
Use wxObject::Dump and the wxDebugContext class
Check Windows debug messages
It's common to blow up the problem in one's imagination, so that it seems to threaten weeks, months or even years of work. The problem you face may seem insurmountable: but almost never is. Once you have been programming for some time, you will be able to remember similar incidents that threw you into the depths of despair. But remember, you always solved the problem, somehow!
Perseverance is often the key, even though a seemingly trivial problem can take an apparently inordinate amount of time to solve. In the end, you will probably wonder why you worried so much. That's not to say it isn't painful at the time. Try not to worry -- there are many more important things in life.
Reduce the code exhibiting the problem to the smallest program possible that exhibits the problem. If it is not possible to reduce a large and complex program to a very small program, then try to ensure your code doesn't hide the problem (you may have attempted to minimize the problem in some way: but now you want to expose it).
With luck, you can add a small amount of code that causes the program to go from functioning to non-functioning state. This should give a clue to the problem. In some cases though, such as memory leaks or wrong deallocation, this can still give totally spurious results!
If we had sophisticated genetic algorithm tools that could be applied to programming, we could use them. Until then, a common -- if rather irrational -- technique is to just make arbitrary changes to the code until something different happens. You may have an intuition why a change will make a difference; otherwise, just try altering the order of code, comment lines out, anything to get over an impasse. Obviously, this is usually a last resort.
This sounds like facetious advice, but it's surprising how often people don't use a debugger. Often it's an overhead to install or learn how to use a debugger, but it really is essential for anything but the most trivial programs. Some platforms don't allow for debugging, such as WIN32s under Windows 3.x. In this case, you might be advised to debug under 16-bit Windows and when you're confident, compile for WIN32s. In fact WIN32s can be very strict about bad memory handling, so testing out under WIN32s is a good thing to do even if you're not going to distribute this version. (Unless you've got a good memory checking, utility, of course!) Tracking bugs under WIN32s can involve a lot of debug message insertion and relinking, so make sure your compiler has a fast linker (e.g. Watcom, Symantec).
You can use wxDebugMsg statements (or the wxDebugStreamBuf class) to output to a debugging window such as DBWIN under Windows, or standard error under X. If compiling in DEBUG mode, you can use TRACE statements that will be compiled out of the final build of your application.
Using tracing statements may be more convenient than using the debugger in some circumstances (such as when your debugger doesn't support a lot of debugging code, or you wish to print a bunch of variables).
It's good practice to implement the Dump member function for all classes derived from wxObject. You can then make use of wxDebugContext to dump out information on all objects in the program, if DEBUG is defined to be more than zero. You can use wxDebugContext to check for memory leaks and corrupt memory. See the debugging topic in the reference manual for more information.
Under Windows, it's worth running your program with DBWIN running or some other program that shows Windows-generated debug messages. It's possible it'll show invalid handles being used. You may have fun seeing what commercial programs cause these normally hidden errors! Microsoft recommend using the debugging version of Windows, which shows up even more problems. However, I doubt it's worth the hassle for most applications. wxWindows is designed to minimize the possibility of such errors, but they can still happen occasionally, slipping through unnoticed because they are not severe enough to cause a crash.