无法捕获std :: invalid_argument

时间:2009-09-04 08:02:17

标签: c++ exception error-handling

我遇到一个问题,捕获一个我无法追踪的std :: invalid_argument异常。我正在使用gcc 4.4.0(windows),pthreads-win32 2.8.0 GC2 dll。

基本上,从两个线程(主线程和使用pthread_create开始的线程),我尝试在大致相同的时间创建一个A类的实例。构造函数抛出一个std :: invalid_argument,但是它被try / catch块包围,它们应该捕获异常。但是,这种情况不会发生(很少发生,只有一个线程可能会捕获异常 - 尽管没有规则可以做到这一点)

如果我尝试仅在其中一个线程上创建对象,则create将按预期工作,并捕获异常。如果我在不同的时间创建两个对象,则create将按预期工作并捕获异常。如果我尝试同时创建它们,则会调用:: terminate()。

也许有人知道为什么会这种情况发生(我已经排除了标题):

void *run(void *ptr)
{
    Sleep(5000);
    try
    {
        A *a = new A(5);
        a->a = 12;
    }
    catch (std::exception &ex)
    {
        printf("t - %s\n", ex.what());
    }
    return NULL;
}

int main(void) {
    pthread_t t;
    if (pthread_create(&t, NULL, run, NULL) != 0)
    {
        printf("No thread\n");
    }
    else
    {
        Sleep(5000);
        try
        {
            A *a = new A(5);
            a->a = 13;
        } catch (std::exception &ex)
        {
            printf("M - %s\n", ex.what());
        }
        pthread_join(t, NULL);
    }
    return 0;
}

class A
{
public:
    A(int a);
    virtual ~A();
    int a;
};
A::A(int a)
{
    throw std::invalid_argument("Invalid!");
}
A::~A(){}

makefile是:

CXXFLAGS = -O0 -g -Wall -Werror -fmessage-length=0
OBJS =  WOpenTest.o A.o
INCL = -I../pthreads-win32/include 
LIBS =   -lws2_32 -lgdi32 -lpthreadGC2 
LIB_DIRS =  -L ../pthreads-win32/lib 
TARGET = WOpenTest.exe
$(TARGET): $(OBJS)
 $(CXX) -o $(TARGET) $(OBJS) $(LIBS) $(LIB_DIRS) $(INCL)
WOpenTest.o : WOpenTest.cpp
 g++ $(CXXFLAGS) -c WOpenTest.cpp $(INCL)  
A.o : A.cpp A.h
 g++ $(CXXFLAGS) -c A.cpp $(INCL)
all: $(TARGET)
clean:
 rm -f $(OBJS) $(TARGET)

我看到的输出是:

  

(最常见的)$ ./WOpenTest.exe

     

此应用程序已请求   运行时以异常方式终止它   办法。请联系申请表   支持团队获取更多信息。

     

此应用程序已请求   运行时以异常方式终止它   办法。请联系申请表   支持团队获取更多信息。   投掷后终止调用   'std :: invalid_argument'的实例   终止被称为递归

  

$ ./WOpenTest.exe

     

此应用程序已请求   运行时以异常方式终止它   办法。请联系申请表   支持团队获取更多信息。   M - 无效!

  

$ ./WOpenTest.exe

     

此应用程序已请求   运行时以异常方式终止它   办法。请联系申请表   支持团队获取更多信息。   t - 无效!

  

此应用程序已请求   运行时以异常方式终止它   办法。请联系申请表   支持团队获取更多信息。

     

此应用程序已请求   运行时以异常方式终止它   办法。请联系申请表   支持团队获取更多信息。   投掷后终止调用   'std :: invalid_argument'的实例   what():无效!

关于我应该做什么的任何想法,我不是?或者pthreads我缺少的东西?

4 个答案:

答案 0 :(得分:2)

您已得出结论,这与MinGW链接到的单线程库有关。我找到了一个关于configuring NetBeans to use MinGW的页面,它在“使用Posix线程进行多线程处理”部分提供了以下建议:

  
      
  • 如果使用异常处理,则很重要:使用其他编译器开关“-mthreads”编译应用程序。否则,异常处理将无法正常工作,并且可能会发生非特定的崩溃。将异常从DLL传播到应用程序时可能会出现其他问题。我在网上找到了一些关于此的提示,但没有经验,因为我的DLL不会抛出异常。
  •   

GCC documentation中也为x86选项进行了描述:

  

-mthreads

     

支持“Mingw32”上的线程安全异常处理。依赖于线程安全异常处理的代码必须使用-mthreads选项编译和链接所有代码。编译时,-mthreads定义-D_MT;链接时,它链接在一个特殊的线程帮助程序库-lmingwthrd中,它清除每个线程的异常处理数据。

请在尝试编写自己的线程安全例外之前尝试。

答案 1 :(得分:2)

在此处发布最终答案,以防将来有人查找。这个问题是gcc 4.4中的一个关键错误:

http://n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-thread-specifier-not-working-td3440749.html

答案 2 :(得分:1)

尝试与pthreadGCE2而不是pthreadGC2进行关联。

答案 3 :(得分:1)

我看不出任何错误。

尝试添加一个catch(...)以查看是否还有其他奇怪的事情发生 如果异常转义了线程(即run()),则pthreads将终止应用程序。但我看不出发生了什么。

正如旁注:
  尝试通过const引用捕获异常。