【发布时间】:2009-09-04 08:02:17
【问题描述】:
我遇到了一个我无法追踪的 std::invalid_argument 异常问题。我正在使用 gcc 4.4.0 (windows)、pthreads-win32 2.8.0 和 GC2 dll。
基本上,从两个线程(主线程和一个使用 pthread_create 启动的线程),我尝试大致同时创建一个类 A 的实例。构造函数抛出一个 std::invalid_argument,但它被应该捕获异常的 try/catch 块包围。然而,这并没有发生(很少,只有一个线程可能会捕获异常 - 但没有关于哪个线程会这样做的规则)
如果我尝试仅在其中一个线程上创建对象,则创建会正常工作,并且会捕获异常。如果我在不同时间创建这两个对象,则创建会正常工作并且会捕获异常。如果我尝试同时创建它们,会调用 ::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 中缺少的东西?
【问题讨论】:
-
我找到了答案,归结为 mingw msvcrt 不是线程安全的。
标签: c++ exception error-handling