为什么在SIGSEGV之后继续Rsession过程及其含义

时间:2017-06-30 18:00:56

标签: r debugging lldb

我正在为自己开发一个R包,它使用Rcpp和使用Rcpp的C ++代码与两个Java代码交互。在使用lldb在Rstudio下工作时尝试调试Rsession崩溃时,我注意到当我尝试加载正在开发的包时,lddb输出以下消息:

(lldb) Process 19030 stopped
* thread #1, name = 'rsession', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
    frame #0: 0x00007fe6c7b872b4
->  0x7fe6c7b872b4: movl   (%rsi), %eax
    0x7fe6c7b872b6: leaq   0xf8(%rbp), %rsi
    0x7fe6c7b872bd: vmovdqu %ymm0, (%rsi)
    0x7fe6c7b872c1: vmovdqu %ymm7, 0x20(%rsi)

(19030年是rsession的pid)。此时,Rstudio停止等待lldb继续执行,但是没有得到可怕的“R会话中止”弹出窗口,在lldb中输入'c'命令恢复了rsession进程并且Rstudio继续一直很好地使用,我可以使用加载包没有问题。即:

c
Process 19030 resuming

这里发生了什么?如果lldb说它已“停止”,为什么Rstudio的会话没有崩溃?这是由于R(或Rstudio的?)SIGSEGV处理机制?这是否意味着最初的SIGSEGV是虚假的,不应该引起关注?当然(但可能不在这个问题的主题):我如何理解lldb的输出,以确定加载我的包的SIGSEGV是否应该进一步调试?

1 个答案:

答案 0 :(得分:0)

SIGSEGV不会出现在Rsession的进程中,而是出现在rJava对包加载启动的JVM进程中。这种行为是已知的,并且由于JVM的内存管理,如here所述:

  

Java使用推测性负载。如果指针指向可寻址   内存,负载成功。很少指针不指向   可寻址内存,并尝试加载生成SIGSEGV ...其中   java运行时拦截,使内存可以再次寻址,和   重新启动加载指令。

建议的gdb解决方法很好用:

(gdb) handle SIGSEGV nostop noprint pass