有没有一种简单的方法来触发R中的崩溃?这仅用于测试目的,以查看某个后台使用R的程序在崩溃情况下的反应,并帮助确定某些罕见问题是否由崩溃引起。
有没有一种简单的方法来触发R中的崩溃?这仅用于测试目的,以查看某个后台使用R的程序在崩溃情况下的反应,并帮助确定某些罕见问题是否由崩溃引起。
最简单的方法是调用C
代码。 C
提供了一个标准函数abort()
[1],可以实现您想要的功能。您需要调用:.Call("abort")
。
正如@Phillip所指出的,您可能需要通过以下方式加载libc
:
在 Linux 上,在发出 .Call("abort")
命令之前,需要使用 dyn.load("/lib/x86_64-linux-gnu/libc.so.6")
。当然,路径会因您的系统而异。
在 OS X 上,需要使用 dyn.load("/usr/lib/libc.dylib")
。
在 Windows 上(我只在 XP 上测试过,因为我无法获得更新版本),您需要安装Rtools
[2]。安装后,应加载dyn.load("C:/.../Rtools/bin/cygwin1.dll")
。
Error in .Call("abort") : C symbol name "abort" not in load table
的错误提示。而在使用RStudio时,则会崩溃。 - Szabolcsdyn.load("/lib/x86_64-linux-gnu/libc.so.6")
。路径在你的系统上可能会有所不同,使用 locate libc.so.6
来查找它。 - Phillipcrash
软件包也调用了 abort
函数,至少就我所见,但我远不如您经验丰富! - lord.garbageabort()
是关键。 - Dirk Eddelbuettel我要从@Spacedman那里偷个主意,但我会通过复制他的Twitter动态来全面认可他的概念:
一步骤导致#rstats出现故障:
options(device=function(){});plot(1)
报告危险,将使您的R会话崩溃。 — Barry Rowlingson (@geospacedman) 2014年7月16日
正如在评论中提到您的问题一样,最简单的方法是调用系统函数abort()
。一种在一行中执行此操作的方法是
R> Rcpp::cppFunction('int crashMe(int ignored) { ::abort(); }');
R> crashMe(123)
Aborted (core dumped)
$
或者您可以使用内联包:
R> library(inline)
R> crashMe <- cfunction(body="::abort();")
R> crashMe()
Aborted (core dumped)
$
当然,您也可以在Rcpp或inline之外完成此操作,但那样的话就需要处理编译、链接和加载方面因系统而异的问题。
abort()
而设计的。 - Dirk Eddelbuettel由于我的C++水平不够,所以我将使用普通的C语言:
创建一个名为segv.c
的C文件:
#include <signal.h>
void crashme(){raise(SIGSEGV);}
在命令行编译它(Windows用户需要自行解决):
R CMD SHLIB segv.c
dyn.load("segv.so") # or possibly .dll for Windows users
.C("crashme")
产生段错误:
> .C("crashme")
*** caught segfault ***
address 0x1d9e, cause 'unknown'
Traceback:
1: .C("crashme")
Possible actions:
1: abort (with core dump, if enabled)
2: normal R exit
3: exit R without saving workspace
4: exit R saving workspace
Selection: 1
aborting ...
Segmentation fault
这与Thomas在图形系统错误报告中提到的行为相同,我已经提交了该报告,也许有一天会得到修复。然而,这两行代码始终会引发一个段错误...
也许Dirk可以将其压缩成一行Rcpp代码吗?
cfunction() i
。你可以在这里做同样的事情,使你的答案更容易/更简洁/不那么依赖于操作系统。Rcpp的使用仅仅是为了部署更简单的构建机制,本质上没有C++。 - Dirk Eddelbuettelspacedman <- inline::cfunction(body="raise(SIGSEGV);", include="#include <signal.h>")
-- 这个答案没有使用任何C++。 - Dirk Eddelbuettellapply("", function(x) eval(sys.call(1)))
(在运行之前保存所有内容,因为这会立即导致“R会话中止”)
编辑:这对我在Windows 10上有效。