web-dev-qa-db-fra.com

Comment planter R?

Existe-t-il un moyen simple de déclencher un crash dans R? Ceci est uniquement à des fins de test, pour voir comment un certain programme qui utilise R en arrière-plan réagit à un crash et aide à déterminer si certains problèmes rares sont dus à des plantages ou non.

66
Szabolcs

Le moyen le plus simple est d'appeler C- code. C fournit une fonction standard abort()[1] qui fait ce que vous voulez. Vous devez appeler: .Call("abort").

Comme l'a souligné @Phillip, vous devrez peut-être charger libc via:

  • sous Linux, dyn.load("/lib/x86_64-linux-gnu/libc.so.6") avant d'émettre .Call("abort"). Le chemin peut bien sûr varier en fonction de votre système.

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

  • sous Windows (je viens de le tester sur XP car je n'ai pas pu me procurer une version plus récente.) vous devrez installer Rtools[2] . Après cela, vous devez charger dyn.load("C:/.../Rtools/bin/cygwin1.dll").

48
lord.garbage

Il y a tout un package sur GitHub dédié à cela:

crash

Package R qui plante intentionnellement une session R. AVERTISSEMENT: destiné au test.

Comment installer un paquet depuis github est traité dans d'autres questions.

47
Dirk Eddelbuettel

Je vais voler une idée de @Spacedman, mais je lui donne un crédit conceptuel complet en copiant depuis son flux Twitter:

Segfault #rstats en une seule étape facile: options(device=function(){});plot(1) a signalé Danger, plantera votre session R. - Barry Rowlingson (@geospacedman) 16 juillet 2014

15
Thomas

Comme mentionné dans un commentaire à votre question, l'approche minimale est un simple appel à la fonction système abort(). Une façon de procéder en une seule ligne consiste à

R> Rcpp::cppFunction('int crashMe(int ignored) { ::abort(); }'); 
R> crashMe(123)
Aborted (core dumped)
$ 

ou vous pouvez utiliser le package en ligne:

R> library(inline)
R> crashMe <- cfunction(body="::abort();")
R> crashMe()
Aborted (core dumped)
$ 

Vous pouvez bien sûr également le faire en dehors de Rcpp ou en ligne, mais vous devez ensuite gérer les méthodes de compilation, de liaison et de chargement dépendant du système.

14
Dirk Eddelbuettel

Je vais le faire en C simple parce que mon C++ - foo n'est pas Dirkian:

Créez un fichier C, segv.c:

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

Compilez-le sur la ligne de commande (les utilisateurs de Windows devront le faire eux-mêmes):

R CMD SHLIB segv.c

Dans R, chargez et exécutez:

dyn.load("segv.so") # or possibly .dll for Windows users
.C("crashme")

Produire un segfault:

> .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

C'est le même comportement que celui référencé par Thomas dans le rapport de bogue du système graphique que j'ai déposé et qui pourrait être corrigé un jour. Cependant ce deux-liner soulèvera toujours une faute de segmentation ...

Peut-être que Dirk peut le faire en une seule ligne?

6
Spacedman

Si vous voulez planter votre R, essayez ceci

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

(Enregistrez tout avant d'exécuter, car cela se traduit immédiatement par "R Session abandonnée")

Edit: cela fonctionne pour moi sur Windows 10.

0
machine