You can do the same thing with malloc/realloc/strdup wrappers by having the wrapper log a stack backtrace, e.g., using GNU libc backtrace().
Alternatively, for platforms without backtrace() or equivalent, write your wrappers to accept additional arguments for the message to log for failure. If desired, you could use macros to make that a compile-time conditional, though I personally don't ever turn off any low-overhead debugging code.
Either approach seems far better than littering the source code with explict tests after each allocation. That just makes the code harder to read and maintain.