Background
I have got a network like setting with nodes and edges. Both nodes and edges need to be classes, in this case Node or Arc, as in this question. In my real setup I am dealing with quite a number of subclasses of both Node and Arc. For memory management, I use this answer to the question above. 
Problem
When the constructor throws an exception, Visual Studio and g++ with MinGW on Windows cannot catch it, but exit without error handling (g++/MinGW reporting a SIGTRAP signal) while g++ and clang++ on Linux handle the exception correctly. If the Arc is created without exception Arc(n1, n2, false), all compilers work fine. In all cases, there are no relevant compiler warnings (using /W4 resp. -Wall) Can someone explain me, why this is not working on Windows? Or even give a workaround?
Code
#include <iostream>
#include <stdexcept>
#include <vector>
#include <memory>
struct Node;
struct Arc {
    Node *left,*right;
private:
    // shared pointer to self, manages the lifetime.
    std::shared_ptr<Arc> skyhook{this};
public:
    // c'tor of Arc, registers Arc with its nodes (as weak pointers of skyhook)
    explicit Arc(Node* a_, Node* b_, bool throw_exc);
    // resets skyhook to kill it self
    void free() {
        std::cout << "  Arc::free();\n" << std::flush;
        skyhook.reset();
    }
    virtual ~Arc() {
        std::cout << "  Arc::~Arc();\n" << std::flush;
    }
};
struct Node {
    explicit Node() {
        std::cout << "  Node::Node()\n" << std::flush;
    }
    std::vector<std::weak_ptr<Arc> > arcs;
    ~Node() {
        std::cout << "  Node::~Node();\n" << std::flush;
        for(const auto &w : arcs) {
            if(const auto a=w.lock()) {
                a->free();
            }
        }
    }
};
Arc::Arc(Node *a_, Node *b_, bool throw_exc) : left(a_), right(b_) {
    std::cout << "  Arc::Arc()\n" << std::flush;
    if (throw_exc) {
        throw std::runtime_error("throw in Arc::Arc(...)");
    }
    a_->arcs.push_back(skyhook);
    b_->arcs.push_back(skyhook);
}
int main(int argc, char* argv[]) {
    std::cout << "n1=new Node()\n" << std::flush;
    Node *n1 = new Node();
    std::cout << "n2=new Node()\n" << std::flush;
    Node *n2 = new Node();
    std::cout << "try a=new Arc()\n" << std::flush;
    try {
        Arc *a = new Arc(n1, n2, true);
    } catch (const std::runtime_error &e) {
        std::cout << "Failed to build Arc: " << e.what() << "\n" << std::flush;
    }
    std::cout << "delete n1\n" << std::flush;
    delete n1;
    std::cout << "delete n2\n" << std::flush;
    delete n2;
}
Output
This is what I get both on Linux as well on Windows
n1=new Node()
  Node::Node()
n2=new Node()
  Node::Node()
try a=new Arc()
  Arc::Arc()
With g++ (7.4.0 and 8.3.0) or clang++ (6.0.0) on Linux ...
it works as expected:
  Arc::~Arc();
Failed to build Arc: throw in Arc::Arc(...)
delete n1
  Node::~Node();
delete n2
  Node::~Node();
With VC++ (2017) ...
it breaks
Arc::~Arc()
and the run terminates with exit code -1073740940 (0xC0000374)
with g++ (9.1.0) MinGW 7.0
it breaks, but reports the signal
Signal: SIGTRAP (Trace/breakpoint trap)
  Arc::~Arc();
And finishes with exit code 1