【问题标题】:Programs hangs while throwing an exception [closed]抛出异常时程序挂起[关闭]
【发布时间】:2016-06-05 00:07:49
【问题描述】:

我在共享主机上运行 C++ 程序(网络服务器)时遇到问题。

该程序在我的开发机器上运行良好,但是当我尝试在托管机器上运行它时,它在尝试抛出异常时挂起。

它试图抛出异常不是问题;如果它成功抛出异常,该异常将在几个堆栈帧上被捕获,并且 Web 服务器将继续运行。

这是挂起线程的堆栈跟踪:

#0  __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
#1  0x00007f18e559669a in _L_lock_1088 () from /home/nr/lib/glibc-2.14.1/lib/libpthread.so.0
#2  0x00007f18e55964fa in __pthread_mutex_lock (mutex=0x7f18e66b6930) at pthread_mutex_lock.c:82
#3  0x00007f18e530f3db in __dl_iterate_phdr (callback=0x970100 <_Unwind_IteratePhdrCallback>, data=0x7f18e2fe9040) at dl-iteratephdr.c:42
#4  0x00000000009714e3 in _Unwind_Find_FDE ()
#5  0x000000000096daf6 in uw_frame_state_for ()
#6  0x000000000096ed40 in uw_init_context_1 ()
#7  0x000000000096f53e in _Unwind_RaiseException ()
#8  0x00000000008dfe7b in __cxa_throw () at ../../../../gcc-5.1/libstdc++-v3/libsupc++/eh_throw.cc:82
#9  0x000000000054ff6e in Wt::WEnvironment::getCookie(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const () at /home/nr/dev/libraries/wt-3.3.4/src/Wt/WEnvironment.C:435
#10 0x000000000069a372 in Wt::WebSession::handleRequest(Wt::WebSession::Handler&) () at /home/nr/dev/libraries/wt-3.3.4/src/web/WebSession.C:1388
#11 0x000000000068a21c in Wt::WebController::handleRequest(Wt::WebRequest*) () at /home/nr/dev/libraries/wt-3.3.4/src/web/WebController.C:713
#12 0x00000000004d815b in boost::asio::detail::completion_handler<boost::_bi::bind_t<void, boost::_mfi::mf1<void, Wt::WebController, Wt::WebRequest*>, boost::_bi::list2<boost::_bi::value<Wt::WebController*>, boost::_bi::value<http::server::HTTPRequest*> > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) () at /home/nr/dev/dist/boost/include/boost/bind/mem_fn_template.hpp:165
#13 0x000000000056e4a2 in Wt::WIOService::run() () at /home/nr/dev/dist/boost/include/boost/asio/detail/task_io_service_operation.hpp:38
#14 0x0000000000810ff3 in thread_proxy ()
#15 0x00007f18e5593cea in start_thread (arg=0x7f18e2fec700) at pthread_create.c:301
#16 0x00007f18e52d8fcd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

由于它在开发机器上运行良好,我怀疑问题可能与开发机器上存在的共享库版本与托管机器上的不同版本有关,但我不知道具体是什么。我会静态链接所有我能做到的东西,包括 libstdc++,正是为了避免这样的问题。

感谢任何有关如何进一步诊断此问题的建议。

编辑:如果有帮助,开发机器运行 Debian Jessie,而主机运行 CentOS 6.8

【问题讨论】:

  • 未定义行为的典型结果。而且,是的,除非您确定主机+开发机器上不同版本的共享库之间的 C++ ABI 相同,否则这肯定是问题所在。
  • 在抛出异常之前你是否锁定了任何东西?在我看来,您已经锁定了一个互斥体,但在抛出异常时没有释放它。
  • @SamVarshavchik:我静态链接所有 C++ 库。唯一保持动态链接的库是 C 库,例如 glibclibssl
  • > 这是挂起线程的堆栈跟踪: 这不足以说明问题所在。我们只能说这个线程正在等待加载器锁。百万美元的问题是:哪个线程持有该锁?
  • @EmployedRussian 有趣的是,我使用您对另一个问题的答案中描述的技术解决了这个问题:stackoverflow.com/a/851229/141719

标签: c++ exception glibc freeze libstdc++


【解决方案1】:

我发现了问题所在。这确实与开发与托管机器上存在的不同版本的共享库有关。

我已经静态链接了所有 C++ 库,只有 C 库保持动态链接。值得注意的是,glibc 保持动态链接,因为它不能很好地支持静态链接。

开发机上安装的glibc版本是2.19;在主机上,它是 2.12。

当我最初尝试在主机上运行程序时,我收到了以下形式的错误:

./myapp: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./myapp)

(它要求 2.14 而不是 2.19 的原因是我的程序实际使用的功能存在于 2.14 及更高版本中,并且 glibc 版本向后兼容。)

为了解决这个问题,我构建了 glibc 2.14,将其二进制文件上传到主机,并使用 LD_LIBRARY_PATH 将我的程序指向它们。这使上述错误消失了,但我现在遇到了提示我发布此问题的问题。

事实证明,挂起的原因是有一个 glibc 组件的路径在编译时被烘焙到可执行文件中,并且不会被 LD_LIBRARY_PATH 覆盖 - 加载器 (ld-linux.so)。

所以,我使用了主机的 glibc 2.12 加载器,以及 glibc 2.14 中的其余库 - 这不起作用。

我通过更改在开发机器上生成程序的链接器命令解决了这个问题,硬编码到主机上 glibc 2.14 加载器的路径,如this answer 中所述(非常感谢@EmployedRussian 编写!)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    相关资源
    最近更新 更多