About debugging, it is somewhat different from normal debugging since macros are a second layer of abstraction. You have a compile-time phase in which the macros are resolved (receiving code and returning code until there is no macro left) and a runtime in which the final generated code is run. If you only consider the runtime, then you're looking at code that is not the same as you wrote, which makes it indeed hard to see mistakes. But if you separate the concerns of compile and run time you can evaluate both separately most of the time.
Also, Ruby does not have macros. It has a very simple syntax in which everything is an object and all function calls are actually messages that can be interpreted in runtime which allows you to extend the syntax very easily by controlling the dispatch rules. What causes trouble is that classes are open and can be extended freely during runtime, so you cannot know that an object you're calling is not modified by any part of the code (including any library), a practice called monkey patching and usually considered bad practice since it makes code hard to reason about.