From 9f202c6f1e991a986da225a0155ad10c0aea682c Mon Sep 17 00:00:00 2001 From: David Tellenbach Date: Fri, 2 Oct 2020 00:41:01 +0200 Subject: [PATCH] Fix undefined behaviour caused by uncaught exceptions in OMP section An OpenMP parallel section must have a single entry and a single point of exit. Leaving such a section by throwing an exception is undefined. This patch fixes this by catching possible exceptions on the parallel section and throwing right we left it. --- Eigen/src/Core/products/Parallelizer.h | 12 +++++++++--- test/exceptions.cpp | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Eigen/src/Core/products/Parallelizer.h b/Eigen/src/Core/products/Parallelizer.h index 3123dc94a..67b2442b5 100644 --- a/Eigen/src/Core/products/Parallelizer.h +++ b/Eigen/src/Core/products/Parallelizer.h @@ -132,7 +132,8 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, Index depth, ei_declare_aligned_stack_constructed_variable(GemmParallelInfo,info,threads,0); - #pragma omp parallel num_threads(threads) + int errorCount = 0; + #pragma omp parallel num_threads(threads) reduction(+: errorCount) { Index i = omp_get_thread_num(); // Note that the actual number of threads might be lower than the number of request ones. @@ -151,9 +152,14 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, Index depth, info[i].lhs_start = r0; info[i].lhs_length = actualBlockRows; - if(transpose) func(c0, actualBlockCols, 0, rows, info); - else func(0, rows, c0, actualBlockCols, info); + EIGEN_TRY { + if(transpose) func(c0, actualBlockCols, 0, rows, info); + else func(0, rows, c0, actualBlockCols, info); + } EIGEN_CATCH(...) { + ++errorCount; + } } + if (errorCount) EIGEN_THROW_X(Eigen::eigen_assert_exception()); #endif } diff --git a/test/exceptions.cpp b/test/exceptions.cpp index b83fb82ba..015b9fd33 100644 --- a/test/exceptions.cpp +++ b/test/exceptions.cpp @@ -109,5 +109,7 @@ void memoryleak() void test_exceptions() { - CALL_SUBTEST( memoryleak() ); + EIGEN_TRY { + CALL_SUBTEST( memoryleak() ); + } EIGEN_CATCH(...) {} }