2011-06-06 38 views
2

我一直在做一个游戏的线程化网络,但服务器随机死亡,而我一直在测试网络,以便我有几个客户端连接和发送一堆数据包和断开连接然后再次连接。线程终止被调用没有一个活跃的异常

我正在使用c + +与SFML /网络和SFML /系统线程。一旦连接建立,我就有侦听服务器连接的线程,它会创建两个用于发送和接收数据包的新线程。事件处理程序和发送/接收线程与两个std ::队列共享数据。我一直在试图用gdb调试崩溃,但我没有那种经验,所以我在寻求帮助。

这是发生崩溃时的gdb控制台输入。

OUT: 10 1 HELLO 
IN: 10 0 LOLOLOL 
OUT: 10 1 HELLO 
IN: 10 0 LOLOLOL 
OUT: 10 1 HELLO 
Out thread killed by in thread! 
In thread died! 
New client connected! 
[Thread 0x34992b70 (LWP 16167) exited] 
[New Thread 0x3118bb70 (LWP 16186)] 
terminate called without an active exception 

Program received signal SIGABRT, Aborted. 
[Switching to Thread 0x35193b70 (LWP 16166)] 
0x00110416 in __kernel_vsyscall() 

这里是回溯:

(gdb) backtrace 
#0 0x00110416 in __kernel_vsyscall() 
#1 0x46a0967f in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 
#2 0x46a0afb5 in abort() at abort.c:92 
#3 0x47b8af0d in __gnu_cxx::__verbose_terminate_handler() at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95 
#4 0x47b88c84 in __cxxabiv1::__terminate (handler=0x47b8adc0 <__gnu_cxx::__verbose_terminate_handler()>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:40 
#5 0x47b88cc0 in std::terminate() at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:50 
#6 0x47b8878f in __cxxabiv1::__gxx_personality_v0 (version=1, actions=10, exception_class=890844228, ue_header=0x35193dc0, context=0x35192ea0) 
    at ../../../../libstdc++-v3/libsupc++/eh_personality.cc:669 
#7 0x46bdbfbe in _Unwind_ForcedUnwind_Phase2 (exc=0x35193dc0, context=0x35192ea0) at ../../../gcc/unwind.inc:175 
#8 0x46bdc3a9 in _Unwind_ForcedUnwind (exc=0x35193dc0, stop=0x46b76fc0 <unwind_stop>, stop_argument=0x35193444) at ../../../gcc/unwind.inc:207 
#9 0x46b794e2 in _Unwind_ForcedUnwind (exc=0x35193dc0, stop=0x46b76fc0 <unwind_stop>, stop_argument=0x35193444) at ../nptl/sysdeps/pthread/unwind-forcedunwind.c:132 
#10 0x46b77141 in __pthread_unwind (buf=<optimized out>) at unwind.c:130 
#11 0x46b6f5bb in __do_cancel() at ../nptl/pthreadP.h:265 
#12 sigcancel_handler (sig=<optimized out>, si=<optimized out>, ctx=<optimized out>) at nptl-init.c:202 
#13 sigcancel_handler (sig=32, si=0x35192f7c, ctx=0x35192ffc) at nptl-init.c:155 
#14 <signal handler called> 
#15 0x08049930 in out (data=0xb761c798) at src/layer7.cpp:40 
#16 0x0804b8d7 in sf::priv::ThreadFunctorWithArg<void (*)(networkdata*), networkdata*>::Run (this=0xb761c7c8) at /usr/local/include/SFML/System/Thread.inl:48 
#17 0x00116442 in sf::Thread::Run()() from /home/toni/ProjectRepos/sfml/build/lib/libsfml-system.so.2 
#18 0x001166df in sf::priv::ThreadImpl::EntryPoint(void*)() from /home/toni/ProjectRepos/sfml/build/lib/libsfml-system.so.2 
#19 0x46b70c5e in start_thread (arg=0x35193b70) at pthread_create.c:305 
#20 0x46ab4b4e in clone() at ../sysdeps/unix/sysv/linux/i386/clone.S:133 

下面是从SRC/layer7.cpp线程代码40

void out(networkdata * data) { 
    bool running = true; 
    while(running) { 
     if(data->pipe_out->pipe_empty() == false) { 
      sf::Packet packet = data->pipe_out->pop_message(); 
      if(data->socket->Send(packet) == sf::Socket::Disconnected) { 
       data->thread_in->Terminate(); 
       std::cout << "In thread killed by out thread!" << std::endl; 
       running = false; 
      } 
     } 
    } 
    std::cout << "Out thread died!" << std::endl; 
} 
  • 行是第一个,如果一段时间后的关键字(运行)。
  • data-> pipe_out-> pipe_empty()调用队列 - > empty()
  • data-> pipe_out-> pop_message()是从队列中弹出前面的调用。
  • 然后发送数据包并检查连接是否没有断开
  • 如果套接字断开连接,它将终止“in”线程并停止自己的线程。
+2

'data'周围的锁在哪里? – 2011-06-06 20:15:48

+0

在'gdb'中切换线程以获得不同的回溯,也许。 – 2011-06-06 20:16:29

+0

其实我刚才在检查你的评论前意识到我应该锁定数据。 :P – TMKCodes 2011-06-06 20:20:00

回答

3

您需要锁定data以防止从多个线程并发访问相同的数据结构。

0

一个可能的原因是异常:异常应该被捕获线程。此外,看起来像data-> thread_in-> Terminate()发送取消请求,确保所有建立的取消处理程序在这种情况下正常工作。

相关问题