概述JVM信号链接SIGPIPE
我们有一个embedded式JVM(Sun\’s)的C ++应用程序。 因为我们注册了自己的信号处理程序,所以build议我们在初始化JVM之前这样做,因为它安装了自己的处理程序( 参见这里 )。
根据我的理解,JVM在内部知道信号源自它自己的代码,如果不是它传递给我们的处理程序。
我们开始看到的是,我们获得了SIGPIPE,调用堆栈看起来大致如此(顶部条目是我们的信号处理程序):
/…/libos_independent_utilitIEs.so(_ZN2os32smart_synchronous_signal_handlerEiP7siginfoPv+0x9) [0x2b124f7a3989] /…/jvm/jre/lib/amd64/server/libjvm.so [0x2aaaab05dc6c] /…/jvm/jre/lib/amd64/server/libjvm.so [0x2aaaab05bffb] /…/jvm/jre/lib/amd64/server/libjvm.so(JVM_handle_linux_signal+0x718) [0x2aaaab05e878] /…/jvm/jre/lib/amd64/server/libjvm.so [0x2aaaab05bf0e] /lib64/libpthread.so.0 [0x3c2140e4c0] /lib64/libpthread.so.0(send+0x91) [0x3c2140d841] /…/jvm/jre/lib/amd64/libnet.so [0x2aaabd360269] /…/jvm/jre/lib/amd64/libnet.so(Java_java_net_SocketoutputStream_socketWrite0+0xee) [0x2aaabd35cf4e] [0x2aaaaeb3bf7f]
看起来JVM正在决定从send引发的SIGPIPE应该传递给我们的信号手。 这样做是对的吗?
C信号处理程序中的竞态条件
错误:“struct sigevent”没有成员名为“sigev_notify_thread_ID”
当subprocess运行时更好的方法来中断我的Python代码?
Perl:closures信号处理程序中的subprocesspipe道挂起?
SIGStop如何在linux内核中工作?
另外,为什么调用堆栈不完整? 我的意思是显然它不能在socketWrite0之前显示我的Java代码,但为什么我不能看到Java代码之前的堆栈?
如何以编程方式获取sigterm在自定义信号处理程序中的默认行为?
释放信号处理程序中的内存
检查安装的信号处理程序
linux从文件中读取奇怪的行为
如何确定unix信号队列(linux)中未决信号的数量
JVM无法判断SIGPIPE是来自它自己的代码还是代码。 信息不是由信号给出的。 因为它不希望你错过任何你可能感兴趣的事件,它必须把所有的SIGPIPE都传给你,即使是那些它自己的代码。
Unix信号有两种口味 – “同步”和“异步”。 执行代码时的一些特殊情况会导致陷阱并导致“同步”信号。 这些是诸如未对齐的存储器访问(SIGBUS),非法的存储器访问,通常为NulL,(SIGSEGV),除零和其他数学错误(SIGFPE),不可译码指令(SIGILL)等等。 这些具有精确的执行上下文,并直接传递给导致它们的线程。 信号处理程序可以查找堆栈,并看到“嘿,我得到了一个非法的内存访问执行java代码,指针是一个NulL,让我去解决这个问题。
相比之下,与外界交互的信号是“异步”变种,包括诸如SIGTERM,SIGQUIT,SIGUSR1等。这些信号没有固定的执行上下文。 对于线程程序,它们几乎随机地传递给任何线程。 重要的是,SIGPIPE就是其中之一。 是的,从某种意义上讲,它通常与一个系统调用相关联。 但是很有可能(例如)有两个线程监听两个单独的连接,这两个连接在两个线程都被调度之前关闭。 内核只是确保有一个SIGPIPE挂起(通常的实现是挂起信号的位掩码),并在重新调度进程中的任何线程时处理它。 这只是JVM可能没有足够的信息来排除客户代码对这个信号感兴趣的简单情况之一。
(至于读取调用会发生什么,它们返回“EINTR出现错误”并继续,此时,JVM可以将其变为异常,但是在信号传递和信号处理程序触发后发生返回。)
结果是你只需要处理误报。 (处理只得到一个信号,其中两个可能已经预期。)
总结
以上是内存溢出为你收集整理的JVM信号链接SIGPIPE全部内容,希望文章能够帮你解决JVM信号链接SIGPIPE所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
请登录后查看评论内容