【问题标题】:How to crash R?如何使 R 崩溃?
【发布时间】:2014-09-28 03:22:48
【问题描述】:

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

【问题讨论】:

  • 我试过 options(expressions=300000) 然后运行无限递归,但 R 写得很好,不会崩溃 :)
  • @StephanKolassa 我在 OS X 上,但为了未来的读者,我宁愿保持一般性的问题。任何平台的特定答案都是可以接受的。
  • 投反对票的人能否解释他们认为这个问题有什么问题? @DirkEddelbuettel 请宽容,这并不能使每个人都明白解决方案。指向手册页的链接并不清楚如何执行此操作。
  • 一定是崩溃吗?你能用非零状态简单地 quit 代替吗?

标签: r crash


【解决方案1】:

最简单的方法是调用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")

【讨论】:

  • 从命令行运行 R 或使用官方 GUI 时,我得到 Error in .Call("abort") : C symbol name "abort" not in load table。使用 RStudio 时会崩溃。
  • 你必须先加载 libc:dyn.load("/lib/x86_64-linux-gnu/libc.so.6")。路径可能因您的系统而异,请使用locate libc.so.6 查找。
  • crash 包也调用abort。至少据我所知,但我的经验远不如你!
  • 所以它永远不会上 CRAN :)
  • 您可能指的是 Rtools 包,因为 Cygwin 从未支持 R。约书亚太客气而不能直接提及的是,您的答案不能以这种方式完全移植。但是,是的,abort() 是关键。
【解决方案2】:

我打算从 @Spacedman 那里窃取一个想法,但我通过从他的 Twitter 提要中复制来给予他完整的概念性功劳:

Segfault #rstats 一步到位: options(device=function(){});plot(1) 报告危险,将使您的 R 会话崩溃。 — 巴里·罗林森 (@geospacedman) July 16, 2014

【讨论】:

  • 这很有用,因为它不会立即退出,而是会显示一个提示并询问下一步该做什么。这是一种不同的行为,这也可能是我自己的项目中出了什么问题...
【解决方案3】:

有一个完整的package on GitHub 专门用于此:

崩溃

故意使 R 会话崩溃的 R 包。警告:有意 进行测试。

如何install a package from github 已在其他问题中介绍。

【讨论】:

  • 它调用abort,很好。
  • 假设您安装了所需的工具(*nixWindows),从 github 安装此软件包的一种方法是:library(devtools); install_github('jdanielnd/crash')。然后您可以使用library(crash); crash() 使您的 R 会话崩溃
【解决方案4】:

正如在对您的问题的评论中提到的,最小的方法是对系统函数 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 之外执行此操作,但是您需要处理依赖于系统的编译、链接和加载方式。

【讨论】:

  • 上述 sn-p 在第一行之后崩溃到桌面(在低内存环境中)。这里是龙。
  • @DeerHunter。我还注意到,在五分之一的尝试中。一定有比赛的地方。再说一次,R 并不是完全设计为abort()ed。
【解决方案5】:

我会用纯 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——我在C模式下使用cfunction()i。你可以在这里做同样的事情,让你的答案更容易/更简洁/更少依赖操作系统。 Rcpp 的使用“仅仅”用于部署更简单的构建机制,本身并没有 C++。
  • spacedman &lt;- inline::cfunction(body="raise(SIGSEGV);", include="#include &lt;signal.h&gt;") -- 没有 C++ 受到伤害^Hused 在这个答案中。
  • spacedman &lt;- Rcpp::cppFunction("void crashme() { ::raise(SIGSEGV); }", includes="#include &lt;signal.h&gt;") -- 就是这样。
【解决方案6】:

如果你想让你的 R 崩溃,试试这个

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

(在运行之前保存所有内容,因为这会立即导致“R Session Aborted”)

编辑:这适用于我在 Windows 10 上。

【讨论】:

  • 至少在 macOS 上似乎有一些防止堆栈溢出的保护措施。这会导致“错误:C 堆栈使用 7971744 太接近限制”,但不会崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 2015-07-07
  • 2016-01-17
  • 2015-11-04
  • 1970-01-01
相关资源
最近更新 更多