Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

Exception handling and OpenMP leads to segfault.

Andreas_Klaedtke
Beginner
1,860 Views

In order to capture exception messages (from the what() method) and make sure that exceptions are not thrown past parallel OpenMP sections, the following pattern is used.

When testing the attached code using OpenMP paralellisation with the pattern, it seems to work fine all the time.
But when this pattern is run in a bigger application, it segfaults pretty much all the time:

bool abort = false; // shared variable that indicates an abort
string error_message; // shared variable that should contain the exception messages

#ifdef _OPENMP
#pragma omp parallel for collapse(2) schedule(dynamic)
#endif
for (int xl = m_area.second.m_begin; xl < m_area.second.m_end; xl += m_area.second.m_stride) {
  for (int sl = m_area.first.m_begin; sl < m_area.first.m_end; sl += m_area.first.m_stride) {
#ifdef _OPENMP
#pragma omp flush (abort)
#endif
    if (!abort) {
      try {
    throw std::runtime_error("Throwing some exception!"); // <-- this is usually a bigger mess which can throw
      } // if !abort
      catch (exception const & e) {
#ifdef _OPENMP
#pragma omp critical (VEL_ERROR_MESSAGE_WRITE)
#endif
    error_message += string(e.what()) + string("\n"); // <-- this is where the segmentation violation happens
    abort = true;
#ifdef _OPENMP
#pragma omp flush (abort)
#endif
      }
      catch (...) {
#ifdef _OPENMP
#pragma omp critical (VEL_ERROR_MESSAGE_WRITE)
#endif
    error_message = "Unknown exception!";
    abort = true;
#ifdef _OPENMP
#pragma omp flush (abort)
#endif
      }
    } // if (!abort)
  } // end of sl loop
 } // end of xl loop

#ifdef _OPENMP
#pragma omp barrier
#endif
if (abort) {
  throw runtime_error("Velocity precomputation encountered"
              " the following error: " + error_message);
}

If the bigger application is run in a debugger, the debugger reports a segmentation violation when assigning the exception string to the shared variable in the critical section. The stack trace is as follows: __kmp_release_lock <- __kmpc_end_critical <- ...537__par_loop0_2_1460 <-...

Is the pattern itself flawed?

Any advice or help on how to resolve the problem would be very much appreciated!

Best regards
Andreas

0 Kudos
22 Replies
jimdempseyatthecove
Honored Contributor III
341 Views

Intel C++ has a runtime check for stack corruption. While it will not catch all errors, it should catch those errors that disturbe memory in an inter-frame gap (trashing signature bytes stored there for this purpose).

One particular problem you should look at with respect to your code, is if you are using functors (a function you declare in line in your code and assign to variable/functor, then use this as argument to later statement). The be careful about what you pass by reference [&] or by value [=], default is reference. If you intend on (require) each thread having value then do not pass by reference.

Jim Dempsey

0 Kudos
SergeyKostrov
Valued Contributor II
341 Views
Here is a set of Intel C++ compiler options related to stack verifications, etc: /Qfp-stack-check - Enable fp stack checking after every function/procedure call /RTCs - Enable stack frame runtime checks /Qcheck-pointers-dangling: - Specifies what type of dangling pointer checking occurs. Possible values are: none - Disables dangling pointer checking. This is the default. heap - Check dangling references on heap. stack - Check dangling references on stack. all - Check dangling references on both heap and stack. This switch is only valid with Intel(R) Parallel Studio XE /check:[,,...] - Check run-time conditions. keywords: [no]conversions, [no]stack, [no]uninit /Qsfalign8 - May align stack for functions with 8 or 16 byte vars (DEFAULT) /Qsfalign16 - May align stack for functions with 16 byte vars /Qsfalign - Force stack alignment for all functions /Qsfalign- - Disable stack alignment for all functions /F - set the stack reserve amount specified to the linker
0 Kudos
Reply