首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法捕获std::invalid_argument

无法捕获std::invalid_argument
EN

Stack Overflow用户
提问于 2009-09-04 08:02:17
回答 4查看 7.5K关注 0票数 1

我遇到了一个问题,捕捉到一个无法跟踪的std::invalid_argument异常。我使用gcc 4.4.0 (windows),32 2.8.0的GC2动态链接库.

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

如果我试图仅在其中一个线程上创建对象,则create按其应有的方式工作,并捕获异常。如果我在不同的时间创建这两个对象,则create按其应有的方式工作,并捕获异常。如果我试图同时创建它们,则调用::terminate()。

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

代码语言:javascript
复制
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是:

代码语言:javascript
复制
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”实例后调用终止 什么():无效!

对我应该做什么我没有什么想法吗?或者是我错过了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-08 07:33:00

在这里张贴最后的答案,以防有人在未来寻找它。这个问题是gcc 4.4中的一个关键问题:

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

票数 2
EN

Stack Overflow用户

发布于 2009-09-04 15:34:53

您已经得出结论,这是与MinGW链接到的单线程库连接的。我找到了一个关于将NetBeans配置为使用MinGW的页面,它在“使用Posix线程的多线程”部分中提供了以下建议:

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

GCC文献 for x86选项中也对此进行了描述:

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

在编写自己的线程安全异常之前,请尝试这样做。

票数 3
EN

Stack Overflow用户

发布于 2009-09-04 08:31:40

尝试使用pthreadGCE2而不是pthreadGC2链接。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1377833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档