如何崩溃R?


68

有没有简单的方法来触发R崩溃?这仅出于测试目的,目的是查看在后台使用R的某个程序对崩溃的反应,并帮助确定某些罕见问题是否由崩溃引起。


3
我尝试过options(expressions=300000)运行无限递归,但R写得足够好,不会崩溃:)
Szabolcs


1
@StephanKolassa我使用的是OS X,但为了将来的读者,我宁愿将此问题笼统地保留下来。任何平台的特定答案都是可以接受的。
Szabolcs 2014年

4
拒绝投票的人可以解释他们认为该问题的错吗?@DirkEddelbuettel请宽容,这并不能使解决方案对所有人都显而易见。手册页上的链接并未明确说明如何执行此操作。
Szabolcs 2014年

4
一定要崩溃吗?您能简单地quit使用非零状态吗?
2014年

Answers:


52

最简单的方法是调用C-code。C提供了您想要的功能的标准功能abort()[1]。您需要致电:.Call("abort")

正如@Phillip指出的那样,您可能需要libc通过以下方式加载:

  • 在Linux上dyn.load("/lib/x86_64-linux-gnu/libc.so.6")发行.Call("abort")。当然,该路径可能会因您的系统而异。

  • 在OS X上, dyn.load("/usr/lib/libc.dylib")

  • 在Windows上(我刚刚在XP上进行了测试,因为我无法获得较新的版本。)您将需要安装Rtools[2]。之后,您应该加载dyn.load("C:/.../Rtools/bin/cygwin1.dll")


1
从命令行运行R或使用官方GUI时,我得到Error in .Call("abort") : C symbol name "abort" not in load table。使用RStudio时会崩溃。
Szabolcs 2014年

2
你有之前加载的libc: dyn.load("/lib/x86_64-linux-gnu/libc.so.6")。该路径在您的系统上可能会有所不同,请使用locate libc.so.6它来查找。
菲利普(Phillip)2014年

3
crash包装要求abort也是如此。至少据我所知,但我的经验远不如您!
lord.garbage 2014年

1
所以它永远不会上CRAN :)
Dirk Eddelbuettel 2014年

3
您可能是说Rtools软件包,因为Cygwin从未支持R。约书亚(Joshua)太客气而不能直接提及的是,您的答案并不是完全可以移植的。但是,abort()是的。
Dirk Eddelbuettel 2014年

49

GitHub上有一个专用于此的完整软件包

崩溃

故意使R会话崩溃的R软件包。警告:用于测试。

其他问题涵盖了如何从github安装软件包


21
它呼唤abort,很好。
lord.garbage 2014年

8
假设您已经安装了必需的工具(* nixWindows),从github安装此软件包的一种方法是:library(devtools); install_github('jdanielnd/crash')。然后,您可以与library(crash); crash()
Joshua Ulrich

17

我打算从@Spacedman窃取一个想法,但是我要通过从他的Twitter feed中复制来给予他全部概念上的信任:

一步即可完成Segfault #rstats: options(device=function(){});plot(1) 报告为Danger,将使您的R会话崩溃。— Barry Rowlingson(@geospacedman)2014年7月16日


1
这很有用,因为它不会立即退出,而是会提示您并询问下一步该怎么做。这是另一种行为,也可能是我自己的项目出了什么问题……
Szabolcs

15

如您对问题的评论中所述,最小方法是对system函数的简单调用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或内联之外执行此操作,但是随后您需要处理依赖于系统的编译,链接和加载方式。


上面的代码段在第一行之后崩溃到桌面(在低内存环境中)。这是龙。
猎鹿人2014年

1
@DeerHunter。我还注意到,可能只有五分之一的尝试。某个地方一定有比赛。再说一遍,R并非完全被设计用于abort()ed。
德克·埃德比布特

6

我将在纯C语言中执行此操作,因为我的C ++-foo不是Dirkian:

创建一个C文件segv.c

#include <signal.h>
void crashme(){raise(SIGSEGV);}

在命令行上编译它(Windows用户必须自己解决这个问题):

R CMD SHLIB segv.c

在R中,加载并运行:

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-ise吗?


重新阅读我的文章,内联使用完全是C -我cfunction()在C模式下使用i。您可以在此处执行相同的操作,以使您的答案更容易/更简洁/与操作系统无关。Rcpp的用途仅仅是部署更简单的构建机制,本身不存在C ++。
Dirk Eddelbuettel 2014年

3
spacedman <- inline::cfunction(body="raise(SIGSEGV);", include="#include <signal.h>") -并且没有C ++受到伤害^使用了这个答案。
Dirk Eddelbuettel 2014年

spacedman <- Rcpp::cppFunction("void crashme() { ::raise(SIGSEGV); }", includes="#include <signal.h>")-在那里。
Dirk Eddelbuettel 2014年

0

如果您想使R崩溃,请尝试此操作

lapply("", function(x) eval(sys.call(1)))

(在运行之前保存所有内容,因为这会立即导致“ R会话异常终止”)

编辑:这在Windows 10上对我有效。


至少在macOS上,似乎有一些针对堆栈溢出的保护措施。这将导致“错误:C堆栈使用7971744太接近限制”,但没有崩溃。
Szabolcs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.