Skip to content

Plan mode "terminate called without an active exception" #478

@jcoupey

Description

@jcoupey

Handling exceptions from worker threads is broken when multiple routes are checked in several threads in plan mode. Multi-threading happens here:

std::vector<std::exception_ptr> thread_exceptions(nb_buckets, nullptr);
auto run_check = [&](unsigned bucket,
const std::vector<Index>& vehicle_ranks) {
for (auto v : vehicle_ranks) {
auto search = v_rank_to_actual_route_rank.find(v);
assert(search != v_rank_to_actual_route_rank.end());
const auto route_rank = search->second;
try {
routes[route_rank] = choose_ETA(input, v, input.vehicles[v].steps);
} catch (...) {
thread_exceptions[bucket] = std::current_exception();
}
}
};
std::vector<std::thread> solving_threads;
for (unsigned i = 0; i < nb_buckets; ++i) {
solving_threads.emplace_back(run_check, i, thread_ranks[i]);
}
for (unsigned i = 0; i < nb_buckets; ++i) {
solving_threads[i].join();
if (thread_exceptions[i] != nullptr) {
std::rethrow_exception(thread_exceptions[i]);
}
}

The puzzling part is that the exception is properly rethrown and handled in main when running a single worker thread. Using a version of the docs example where I added service_after and service_before keys to force an infeasible route (example_3.txt):

$ vroom -c -i example_3.txt -t 2
terminate called without an active exception
Aborted (core dumped)
$ vroom -c -i example_3.txt -t 1
[Error] Infeasible route for vehicle 1.
{"code":2,"error":"Infeasible route for vehicle 1."}

I've used a std::vector<std::exception_ptr>> to store one std::exception_ptr per thread and be able to rethrow the exception. The same problem applies to the latest commits in #450 and my current attempts for #417.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions