Then use a good one! :)
This is tongue in cheek, of course, but think about steps 2 and 3; this is where you want to verify that you understand when the method is called and what it gets as input. The method might receive six nested structs as arguments, how many tries does it take you to print all the relevant information? Does what you're trying to print have a useful string representation?
Set a breakpoint in your Invoke method. Inspect the arguments as deeply as you need to. Check the stack to see where the method is actually being called from. Verify that you can access any other objects you need and that they are in a sensible state. One good breakpoint can save you dozens of edit-compile-run cycles.
printf debugging shines when you need to investigate a property over many individual calls - What array sizes is this function being called with? At what point does this optimized calculation diverge from the reference implementation? Are functions A and C ever called in succession without B being called in between?