简体   繁体   中英

Throwing a C++ exception inside an omp critical section

I'm wondering if it is safe to throw an C++ exception inside an OMP critical section.

#pragma omp critical (my_critical_section)
{
    ...
    throw my_exception("failed")
    ...       
}

g++ does not complain. I'm puzzled because it complains about return statements inside the critical section. It returns the error: invalid exit from OpenMP structured block when I write

#pragma omp critical (my_critical_section)
{
    ...
    return;
    ...       
}

So, why is it OK to leave the critical section with an exception, but it is not OK to leave it with a return statement?

No, it is not OK to leave a critical section with exceptions. g++ does not complain in this case but it silently inserts an implicit try/catch around the block of the critical section. For example the following code:

#pragma omp critical (my_crit)
{
   throw 3;
}

gets lowered by the OpenMP processor of GCC 4.7 into:

#pragma omp critical (my_crit)
__builtin_GOMP_critical_name_start (&.gomp_critical_user_my_crit);
try
  {
    D.20639 = __cxa_allocate_exception (4);
    try
      {
        MEM[(int *)D.20639] = 3;
      }
    catch
      {
        __cxa_free_exception (D.20639);
      }
    __cxa_throw (D.20639, &_ZTIi, 0B);
  }
catch
  {
    <<<eh_must_not_throw (terminate)>>>
  }
__builtin_GOMP_critical_name_end (&.gomp_critical_user_my_crit);

Reaching the implicit built-in catch-all handler <<<eh_must_not_throw (terminate)>>> results in quite ungraceful termination:

terminate called after throwing an instance of 'int'
Abort trap: 6

The implicit try/catch is inserted regardless of the presence of an outer try/catch construct, ie the exception would never ever leave the critical section.

The OpenMP standard mandates, that if an exception is thrown within most OpenMP constructs ( parallel , section , master , single , for , critical , task , etc.), execution must resume within the same construct and that the same thread must catch the exception. Violation of this restriction leads to non-conformant OpenMP code and g++ simply enforces the conformance by inserting try/catch blocks with termination handlers inside all such constructs.

As for the error when a return statement is present, OpenMP defines a strcutured block in C/C++ as:

For C/C++, an executable statement, possibly compound, with a single entry at the top and a single exit at the bottom, or an OpenMP construct.

and also (for all languages):

The point of exit cannot be a branch out of the structured block .

Obviously return constitutes a branch ouf of the block, different from simply falling of the bottom of the block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM