When I try to solve problems with a binary tree, I find that it helps to keep track of exactly when a certain node is entered and existed (when is it pushed to and popped from the call stack). This is similar to Lasse V. Karlsen's suggestion, but done in directly in the code. Any other code that you would use for a task (such as swapping the left and right children, collecting the sum of all visited nodes etc.) would have to happen between the two logs, and should probably have their own logs so you can see on exactly which node your error may have occurred. For example:
static ArrayList results = new ArrayList();
public static void Traverse(Node root)
{
if (root == null)
return;
Console.WriteLine("Entering", root.data);
results.Add(root.data);
Console.Write("Current Results: ");
foreach(int i in results) {
Console.Write(i + " ");
}
Console.WriteLine("");
Traverse(root.left);
Traverse(root.right);
Console.WriteLine("Exiting", root.data);
}