0

the code below crashes with

terminate called after throwing an instance of 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >'
Aborted                    (core dumped) ./a.out

when compiled with g++ -fopenmp

#include <string>
#include <vector>
#include <iostream>
void bla2(){
  try{
    throw std::string("bla2");
  }catch(std::string x){
    throw std::string("error ")+x;
  }
}
void bla1(){
  try{
    std::vector<std::string> y;
    y.resize(10);
#pragma omp parallel for ordered schedule(static) num_threads(10)
    for(int i=0;i<10;++i){
      try{
#pragma omp ordered
        {
          bla2();
        }
      }catch(std::string x){
        y[i]=x;
      }
    }
    for(auto &x:y) if(x.size()>0) throw x;
  }catch(std::string x){
    throw std::string("error ")+x;
  }
}

int main(){
  try{
    bla1();
  }catch(std::string x){
    std::cout<<x<<std::endl;
  }
}

Note that the segmentation fault can be avoid by omitting #pragma omp ordered

OS: Linux kernel 6.17.5

g++: 15.2.1

Any suggestions?

7
  • 3
    Put the ordered around the whole try/catch? Commented Oct 31 at 15:00
  • 4
    The standard spells it out: "A throw executed inside a ordered region must cause execution to resume within the same ordered region, and the same thread that threw the exception must catch it." Commented Oct 31 at 15:09
  • 2
    By the way, throwing a std::string is not a good idea. Moreover, you should catch object by reference so to avoid necessary copies in this case. Catching an exception from a parallel section seems a red flag to me (I highly doubt this is supported), independently of the ordered construct. Finally, a parallel for with only an ordered construct is useless performance wise (no actual parallelism). Please note that using num_threads(10) is also a bad idea in real-world application (OK for a prototype). Commented Oct 31 at 15:25
  • 1
    Side note: Exceptions should generally be caught by const & (const reference). Commented Oct 31 at 19:53
  • @JérômeRichard Catching exceptions from another thread can't be supported without code that's OMP almost certainly doesn't have. Exceptions merely unwind a thread's call stack in a way that's different from return. Commented Oct 31 at 20:19

1 Answer 1

1

This works:

#include <string>
#include <vector>
#include <iostream>
void bla2(){
  try{
    throw std::string("bla2");
  }catch(std::string x){
    throw std::string("error ")+x;
  }
}
void bla1(){
  try{
    std::vector<std::string> y;
    y.resize(10);
#pragma omp parallel for ordered schedule(static) num_threads(10)
    for(int i=0;i<10;++i){
      try{
         //do some heavy work here 
#pragma omp ordered
        {
          try{
            bla2();
          }catch(std::string x){
            y[i]=x;
          }
        }
      }catch(std::string x){
        y[i]=x;
      }
    }
    for(auto &x:y) if(x.size()>0) throw x;
  }catch(std::string x){
    throw std::string("error ")+x;
  }
}

int main(){
  try{
    bla1();
  }catch(std::string x){
    std::cout<<x<<std::endl;
  }
}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.