So I've declared a local function:
  extern(C) void _d_assert_msg (string msg, string file, uint line)

Intent is to replace the druntime assert handler.
I declared this function and the program builds and links, but it still calls the druntime function.

1. I'm not sure exactly why linking succeeds... I would have expected a link error with multiple defined symbols...
2. That said, #1 shouldn't actually happen because the druntime symbol should be marked with weak linkage such that a user-override will be accepted when supplied, but that seems not to be the  case right now...?

Have people done this in their own programs? What is the best practice?

On a related note; _d_assert_msg is missing an argument; it supplies msg, line, file, but it also needs to receive another argument which is the stringified assert expression that failed.