I've tried your script and it does call the save_map method after pressing CTRL-C. When you press CTRL-C, the signal SIGINT is sent to end all the running nodes.
Your problem is that you have redirected what should happen when this signal is sent with rospy.on_shutdown(save_map). You manually define how to exit the node BUT you launch a new process within this method. The process launched is map_server which is waiting indefinitely to receive something on the topic /map to exit itself. Since the map_server is called during the ros shutdown, all your previous nodes have been exited, meaning there is no node publishing to /map anymore. The map_server will never get a map so you never exit the method save_map. When the SIGINT signal is sent, if all the nodes aren't closed after a defined timeout (15 seconds by default) the signal SIGTERM is sent to kill all the remaining running nodes, including your current node.