1 /*
2 * RExec.cpp
3 *
4 * Copyright (C) 2021 by RStudio, PBC
5 *
6 * Unless you have received this program directly from RStudio pursuant
7 * to the terms of a commercial license agreement with RStudio, then
8 * this program is licensed to you under the terms of version 3 of the
9 * GNU Affero General Public License. This program is distributed WITHOUT
10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13 *
14 */
15
16 #define R_INTERNAL_FUNCTIONS
17 #include <r/RExec.hpp>
18
19 #include <shared_core/FilePath.hpp>
20 #include <core/Log.hpp>
21 #include <core/StringUtils.hpp>
22 #include <core/system/Environment.hpp>
23
24 #include <r/RErrorCategory.hpp>
25 #include <r/RSourceManager.hpp>
26 #include <r/RInterface.hpp>
27 #include <r/RCntxt.hpp>
28 #include <r/ROptions.hpp>
29
30 #include <R_ext/Parse.h>
31
32 #include <R_ext/libextern.h>
33
34 extern "C" {
35 LibExtern Rboolean R_interrupts_suspended;
36 LibExtern int R_interrupts_pending;
37 #ifdef _WIN32
38 LibExtern int UserBreak;
39 #endif
40 }
41
42 using namespace rstudio::core;
43
44 namespace rstudio {
45 namespace r {
46
47 namespace exec {
48
49 namespace {
50
51 bool s_wasInterrupted;
52
53 MainThreadFunction s_mainThreadFunction;
54
55 // create a scope for disabling any installed error handlers (e.g. recover)
56 // we need to do this so that recover isn't invoked while we are running
57 // R code within an r::exec scope -- when the user presses 0 to exit
58 // from recover and jump_to_top it gets eaten by the R_ToplevelExecute
59 // context so the console becomes unresponsive
60 class DisableErrorHandlerScope : boost::noncopyable
61 {
62 public:
DisableErrorHandlerScope()63 DisableErrorHandlerScope()
64 : didDisable_(false)
65 {
66 // allow users to enable / disable suppression of error handlers
67 // (primarily for debugging when behind-the-scenes R code emits an error
68 // that we'd like to learn a bit more about)
69 bool suppressed = r::options::getOption("rstudio.errors.suppressed", true, false);
70 if (!suppressed)
71 return;
72
73 SEXP handlerSEXP = r::options::setErrorOption(R_NilValue);
74 if (handlerSEXP != R_NilValue)
75 {
76 preservedSEXP_.set(handlerSEXP);
77 didDisable_ = true;
78 }
79 }
~DisableErrorHandlerScope()80 virtual ~DisableErrorHandlerScope()
81 {
82 try
83 {
84 if (didDisable_)
85 r::options::setErrorOption(preservedSEXP_.get());
86 }
87 catch(...)
88 {
89 }
90 }
91
92 private:
93 bool didDisable_;
94 r::sexp::PreservedSEXP preservedSEXP_;
95 };
96
97
parseString(const std::string & str,SEXP * pSEXP,sexp::Protect * pProtect)98 Error parseString(const std::string& str, SEXP* pSEXP, sexp::Protect* pProtect)
99 {
100 // string to parse
101 SEXP cv = sexp::create(str, pProtect);
102
103 // do the parse and protect the result
104 ParseStatus ps;
105 *pSEXP=R_ParseVector(cv, 1, &ps, R_NilValue);
106 pProtect->add(*pSEXP);
107
108 // check error/success
109 if (ps != PARSE_OK)
110 {
111 Error error(errc::ExpressionParsingError, ERROR_LOCATION);
112 error.addProperty("code", str);
113 return error;
114 }
115 else
116 {
117 return Success();
118 }
119 }
120
121
122 // evaluate expressions without altering the error handler (use with caution--
123 // a user-supplied error handler may be invoked if the expression raises
124 // an error!)
125 enum EvalType {
126 EvalTry, // use R_tryEval
127 EvalDirect // use Rf_eval directly
128 };
evaluateExpressionsUnsafe(SEXP expr,SEXP envir,SEXP * pSEXP,sexp::Protect * pProtect,EvalType evalType)129 Error evaluateExpressionsUnsafe(SEXP expr,
130 SEXP envir,
131 SEXP* pSEXP,
132 sexp::Protect* pProtect,
133 EvalType evalType)
134 {
135 // detect if an error occurred (only relevant for EvalTry)
136 int errorOccurred = 0;
137
138 if (!isMainThread())
139 {
140 LOG_ERROR_MESSAGE("evaluateExpression called from thread other than main");
141 return rCodeExecutionError("Attempt to eval R on thread other than main", ERROR_LOCATION);
142 }
143
144 // if we have an entire expression list, evaluate its contents one-by-one
145 // and return only the last one
146 if (TYPEOF(expr) == EXPRSXP)
147 {
148 DisableDebugScope disableStepInto(envir);
149
150 for (int i = 0, n = LENGTH(expr); i < n; i++)
151 {
152 if (evalType == EvalTry)
153 {
154 SEXP result = R_tryEval(VECTOR_ELT(expr, i), envir, &errorOccurred);
155 if (errorOccurred == 0)
156 *pSEXP = result;
157 }
158 else
159 {
160 *pSEXP = Rf_eval(VECTOR_ELT(expr, i), envir);
161 }
162 }
163 }
164
165 // otherwise, evaluate a single expression / call
166 else
167 {
168 DisableDebugScope disableStepInto(envir);
169
170 if (evalType == EvalTry)
171 {
172 SEXP result = R_tryEval(expr, envir, &errorOccurred);
173 if (errorOccurred == 0)
174 *pSEXP = result;
175 }
176 else
177 {
178 *pSEXP = Rf_eval(expr, envir);
179 }
180 }
181
182 // protect the result
183 pProtect->add(*pSEXP);
184
185 if (errorOccurred)
186 {
187 // get error message -- note this results in a recursive call to
188 // evaluate expressions during the fetching of the error. if this
189 // call yielded an error then this could infinitely recurse. it doesn't
190 // appears as if geterrmessage will ever return an error state so
191 // this is likely not an issue. still, if we were concerned about it
192 // then we could simply read the error buffer directly from the module
193 // where do_geterrmessage is defined (errors.c)
194 return rCodeExecutionError(getErrorMessage(), ERROR_LOCATION);
195 }
196 else
197 {
198 return Success();
199 }
200 }
201
evaluateExpressions(SEXP expr,SEXP env,SEXP * pSEXP,sexp::Protect * pProtect)202 Error evaluateExpressions(SEXP expr,
203 SEXP env,
204 SEXP* pSEXP,
205 sexp::Protect* pProtect)
206 {
207 // disable custom error handlers while we execute code
208 DisableErrorHandlerScope disableErrorHandler;
209
210 return evaluateExpressionsUnsafe(expr, env, pSEXP, pProtect, EvalTry);
211 }
212
evaluateExpressions(SEXP expr,SEXP * pSEXP,sexp::Protect * pProtect)213 Error evaluateExpressions(SEXP expr, SEXP* pSEXP, sexp::Protect* pProtect)
214 {
215 return evaluateExpressions(expr, R_GlobalEnv, pSEXP, pProtect);
216 }
217
topLevelExec(void * data)218 void topLevelExec(void *data)
219 {
220 boost::function<void()>* pFunction = (boost::function<void()>*)data;
221 pFunction->operator()();
222 }
223
224 struct SEXPTopLevelExecContext
225 {
226 boost::function<SEXP()> function;
227 SEXP* pReturnSEXP;
228 };
229
SEXPTopLevelExec(void * data)230 void SEXPTopLevelExec(void *data)
231 {
232 SEXPTopLevelExecContext* pContext = (SEXPTopLevelExecContext*)data;
233 *(pContext->pReturnSEXP) = pContext->function();
234 }
235
236 } // anonymous namespace
237
executeSafely(boost::function<void ()> function)238 Error executeSafely(boost::function<void()> function)
239 {
240 if (!isMainThread())
241 {
242 LOG_ERROR_MESSAGE("executeSafely called from thread other than main");
243 return rCodeExecutionError("execute function called from thread other than main", ERROR_LOCATION);
244 }
245 // disable custom error handlers while we execute code
246 DisableErrorHandlerScope disableErrorHandler;
247 DisableDebugScope disableStepInto(R_GlobalEnv);
248
249 Rboolean success = R_ToplevelExec(topLevelExec, (void*)&function);
250 if (!success)
251 {
252 return rCodeExecutionError(getErrorMessage(), ERROR_LOCATION);
253 }
254 else
255 {
256 return Success();
257 }
258 }
259
executeSafely(boost::function<SEXP ()> function,SEXP * pSEXP)260 core::Error executeSafely(boost::function<SEXP()> function, SEXP* pSEXP)
261 {
262 // disable custom error handlers while we execute code
263 DisableErrorHandlerScope disableErrorHandler;
264 DisableDebugScope disableStepInto(R_GlobalEnv);
265
266 SEXPTopLevelExecContext context;
267 context.function = function;
268 context.pReturnSEXP = pSEXP;
269 Rboolean success = R_ToplevelExec(SEXPTopLevelExec, (void*)&context);
270 if (!success)
271 {
272 return rCodeExecutionError(getErrorMessage(), ERROR_LOCATION);
273 }
274 else
275 {
276 return Success();
277 }
278 }
279
executeCallUnsafe(SEXP callSEXP,SEXP envirSEXP,SEXP * pResultSEXP,sexp::Protect * pProtect)280 Error executeCallUnsafe(SEXP callSEXP,
281 SEXP envirSEXP,
282 SEXP *pResultSEXP,
283 sexp::Protect *pProtect)
284 {
285 return evaluateExpressionsUnsafe(callSEXP,
286 envirSEXP,
287 pResultSEXP,
288 pProtect,
289 EvalDirect);
290 }
291
executeStringUnsafe(const std::string & str,SEXP envirSEXP,SEXP * pSEXP,sexp::Protect * pProtect)292 Error executeStringUnsafe(const std::string& str,
293 SEXP envirSEXP,
294 SEXP* pSEXP,
295 sexp::Protect* pProtect)
296 {
297 SEXP parsedSEXP = R_NilValue;
298 Error error = r::exec::parseString(str, &parsedSEXP, pProtect);
299 if (error)
300 return error;
301
302 return evaluateExpressionsUnsafe(parsedSEXP, envirSEXP, pSEXP, pProtect, EvalDirect);
303 }
304
executeStringUnsafe(const std::string & str,SEXP * pSEXP,sexp::Protect * pProtect)305 Error executeStringUnsafe(const std::string& str,
306 SEXP* pSEXP,
307 sexp::Protect* pProtect)
308 {
309 return executeStringUnsafe(str, R_GlobalEnv, pSEXP, pProtect);
310 }
311
executeString(const std::string & str)312 Error executeString(const std::string& str)
313 {
314 sexp::Protect rProtect;
315 SEXP ignoredSEXP;
316 return evaluateString(str, &ignoredSEXP, &rProtect);
317 }
318
evaluateString(const std::string & str,SEXP * pSEXP,sexp::Protect * pProtect,EvalFlags flags)319 Error evaluateString(const std::string& str,
320 SEXP* pSEXP,
321 sexp::Protect* pProtect,
322 EvalFlags flags)
323 {
324 if (!isMainThread())
325 {
326 LOG_ERROR_MESSAGE("evaluateString called from thread other than main: " + str);
327 return rCodeExecutionError("Attempt to eval R off of main thread", ERROR_LOCATION);
328 }
329 // refresh source if necessary (no-op in production)
330 r::sourceManager().reloadIfNecessary();
331
332 // surround the string with try in silent mode so we can capture error text
333 std::string rCode = "base::try(" + str + ", silent = TRUE)";
334
335 // suppress warnings if requested
336 if (flags & EvalFlagsSuppressWarnings)
337 rCode = "base::suppressWarnings(" + rCode + ")";
338
339 if (flags & EvalFlagsSuppressMessages)
340 rCode = "base::suppressMessages(" + rCode + ")";
341
342 // parse expression
343 SEXP ps;
344 Error parseError = parseString(rCode, &ps, pProtect);
345 if (parseError)
346 return parseError;
347
348 // evaluate the expression
349 Error evalError = evaluateExpressions(ps, pSEXP, pProtect);
350 if (evalError)
351 {
352 evalError.addProperty("code", str);
353 return evalError;
354 }
355
356 // check for try-error
357 if (Rf_inherits(*pSEXP, "try-error"))
358 {
359 // get error message (merely log on failure so we can continue
360 // and return the real error)
361 std::string errorMsg;
362 Error extractError = sexp::extract(*pSEXP, &errorMsg);
363 if (extractError)
364 LOG_ERROR(extractError);
365
366 // add it to the error
367 return rCodeExecutionError(errorMsg, ERROR_LOCATION);
368 }
369
370 return Success();
371 }
372
atTopLevelContext()373 bool atTopLevelContext()
374 {
375 return context::RCntxt::begin()->callflag() == CTXT_TOPLEVEL;
376 }
377
378 // Returns true for all threads unless initMainThread was called from the main one
isMainThread()379 bool isMainThread()
380 {
381 if (!s_mainThreadFunction)
382 return true; // Not determined
383 return s_mainThreadFunction();
384 }
385
386 // Call this from the main thread to enable main-thread diagnostic checks.
initMainThread(MainThreadFunction fun)387 void initMainThread(MainThreadFunction fun)
388 {
389 s_mainThreadFunction = fun;
390 }
391
RFunction(SEXP functionSEXP)392 RFunction::RFunction(SEXP functionSEXP)
393 {
394 functionSEXP_ = functionSEXP;
395 preserver_.add(functionSEXP_);
396 }
397
~RFunction()398 RFunction::~RFunction()
399 {
400 }
401
commonInit(const std::string & functionName)402 void RFunction::commonInit(const std::string& functionName)
403 {
404 // refresh source if necessary (no-op in production)
405 r::sourceManager().reloadIfNecessary();
406
407 // record functionName (used later for diagnostics)
408 functionName_ = functionName;
409
410 // handle empty function names up front
411 if (functionName.empty())
412 {
413 functionSEXP_ = R_UnboundValue;
414 return;
415 }
416
417 // otherwise, build call to function
418 // check for namespace qualifier and handle that if set
419 auto pos = functionName.find(":::");
420 if (pos == std::string::npos)
421 {
422 functionSEXP_ = Rf_install(functionName.c_str());
423 }
424 else
425 {
426 functionSEXP_ = Rf_lang3(
427 Rf_install(":::"),
428 Rf_install(functionName.substr(0, pos).c_str()),
429 Rf_install(functionName.substr(pos + 3).c_str()));
430 preserver_.add(functionSEXP_);
431 }
432 }
433
callUnsafe()434 Error RFunction::callUnsafe()
435 {
436 return call(R_GlobalEnv, false);
437 }
438
call(SEXP evalNS,bool safely)439 Error RFunction::call(SEXP evalNS, bool safely)
440 {
441 sexp::Protect rProtect;
442 SEXP ignoredResultSEXP;
443 return call(evalNS, safely, &ignoredResultSEXP, &rProtect);
444 }
445
call(SEXP * pResultSEXP,sexp::Protect * pProtect)446 Error RFunction::call(SEXP* pResultSEXP, sexp::Protect* pProtect)
447 {
448 return call(R_GlobalEnv, pResultSEXP, pProtect);
449 }
450
call(SEXP evalNS,SEXP * pResultSEXP,sexp::Protect * pProtect)451 Error RFunction::call(SEXP evalNS, SEXP* pResultSEXP, sexp::Protect* pProtect)
452 {
453 return call(evalNS, true, pResultSEXP, pProtect);
454 }
455
call(SEXP evalNS,bool safely,SEXP * pResultSEXP,sexp::Protect * pProtect)456 Error RFunction::call(SEXP evalNS,
457 bool safely,
458 SEXP* pResultSEXP,
459 sexp::Protect* pProtect)
460 {
461 // check that the function exists
462 if (functionSEXP_ != R_UnboundValue)
463 {
464 Error existsError = safely ?
465 evaluateExpressions(functionSEXP_, evalNS, pResultSEXP, pProtect) :
466 evaluateExpressionsUnsafe(functionSEXP_, evalNS, pResultSEXP, pProtect, EvalTry);
467
468 if (existsError)
469 functionSEXP_ = R_UnboundValue;
470 }
471
472 // verify the function
473 if (functionSEXP_ == R_UnboundValue)
474 {
475 Error error(errc::SymbolNotFoundError, ERROR_LOCATION);
476 if (!functionName_.empty())
477 error.addProperty("symbol", functionName_);
478 return error;
479 }
480
481 if (!isMainThread())
482 {
483 LOG_ERROR_MESSAGE("Attempt to call R function: " + functionName_ + " on thread other than main");
484 return rCodeExecutionError("Attempt to call R function on thread other than main", ERROR_LOCATION);
485 }
486
487 // create the call object (LANGSXP) with the correct number of elements
488 SEXP callSEXP;
489 pProtect->add(callSEXP = Rf_allocVector(LANGSXP, 1 + params_.size()));
490 SET_TAG(callSEXP, R_NilValue); // just like do_ascall() does
491
492 // assign the function to the first element of the call
493 SETCAR(callSEXP, functionSEXP_);
494
495 // assign parameters to the subseqent elements of the call
496 SEXP nextSlotSEXP = CDR(callSEXP);
497 for (std::vector<Param>::const_iterator
498 it = params_.begin(); it != params_.end(); ++it)
499 {
500 SETCAR(nextSlotSEXP, it->valueSEXP);
501 // parameters can optionally be named
502 if (!(it->name.empty()))
503 SET_TAG(nextSlotSEXP, Rf_install(it->name.c_str()));
504 nextSlotSEXP = CDR(nextSlotSEXP);
505 }
506
507 // call the function
508 Error error = safely ?
509 evaluateExpressions(callSEXP, evalNS, pResultSEXP, pProtect) :
510 evaluateExpressionsUnsafe(callSEXP, evalNS, pResultSEXP, pProtect,
511 EvalTry);
512 if (error)
513 return error;
514
515 // return success
516 return Success();
517 }
518
rBinaryPath()519 FilePath rBinaryPath()
520 {
521 FilePath binPath = FilePath(R_HomeDir()).completePath("bin");
522 #ifdef _WIN32
523 return binPath.completePath("Rterm.exe");
524 #else
525 return binPath.completePath("R");
526 #endif
527 }
528
system(const std::string & command,std::string * pOutput)529 Error system(const std::string& command, std::string* pOutput)
530 {
531 r::exec::RFunction system("system", command);
532 system.addParam("intern", true);
533 system.addParam("ignore.stderr", true);
534
535 // call it
536 Error error = system.call(pOutput);
537 if (error)
538 {
539 // if it is NoDataAvailable this means empty output
540 if (error == r::errc::NoDataAvailableError)
541 {
542 pOutput->clear();
543 return Success();
544 }
545 else
546 {
547 return error;
548 }
549 }
550 else
551 {
552 return Success();
553 }
554 }
555
556
error(const std::string & message)557 void error(const std::string& message)
558 {
559 Rf_error("%s", message.c_str());
560 }
561
errorCall(SEXP call,const std::string & message)562 void errorCall(SEXP call, const std::string& message)
563 {
564 Rf_errorcall(call, "%s", message.c_str());
565 }
566
getErrorMessage()567 std::string getErrorMessage()
568 {
569 return R_curErrorBuf();
570 }
571
572
warning(const std::string & warning)573 void warning(const std::string& warning)
574 {
575 Rf_warning("%s", warning.c_str());
576 }
577
message(const std::string & message)578 void message(const std::string& message)
579 {
580 Error error = r::exec::RFunction("message", message).call();
581 if (error)
582 LOG_ERROR(error);
583 }
584
interruptsPending()585 bool interruptsPending()
586 {
587 #ifdef _WIN32
588 return UserBreak == 1 ? true : false;
589 #else
590 return R_interrupts_pending == 1 ? true : false;
591 #endif
592 }
593
setInterruptsPending(bool pending)594 void setInterruptsPending(bool pending)
595 {
596 setWasInterrupted(pending);
597
598 #ifdef _WIN32
599 UserBreak = pending ? 1 : 0;
600 #else
601 R_interrupts_pending = pending ? 1 : 0;
602 #endif
603 }
604
checkUserInterrupt()605 void checkUserInterrupt()
606 {
607 R_CheckUserInterrupt();
608 }
609
IgnoreInterruptsScope()610 IgnoreInterruptsScope::IgnoreInterruptsScope()
611 : pSignalBlocker_(new core::system::SignalBlocker())
612 {
613 // save suspend state and set suspend flag
614 previousInterruptsSuspended_ = (R_interrupts_suspended == TRUE);
615 R_interrupts_suspended = TRUE;
616
617 // clear existing
618 setInterruptsPending(false);
619
620 // enable signal blocker
621 Error error = pSignalBlocker_->block(core::system::SigInt);
622 if (error)
623 LOG_ERROR(error);
624 }
625
~IgnoreInterruptsScope()626 IgnoreInterruptsScope::~IgnoreInterruptsScope()
627 {
628 try
629 {
630 // delete signal blocker (may cause delivery of one of the blocked
631 // interrupts, but we restore the previous interrupt state below
632 // so this is no problem)
633 pSignalBlocker_.reset();
634
635 // restore suspended state
636 R_interrupts_suspended = previousInterruptsSuspended_ ? TRUE : FALSE;
637
638 // clear state
639 setInterruptsPending(false);
640 }
641 catch(...)
642 {
643 }
644 }
645
DisableDebugScope(SEXP env)646 DisableDebugScope::DisableDebugScope(SEXP env)
647 : rdebug_(0),
648 env_(nullptr)
649 {
650 // nothing to do if no environment
651 if (env == nullptr)
652 return;
653
654 // check to see whether there's a debug flag set on this environment
655 rdebug_ = RDEBUG(env);
656
657 // if there is, turn it off and save the old flag for restoration
658 if (rdebug_ != 0)
659 {
660 SET_RDEBUG(env, 0);
661 env_ = env;
662 }
663 }
664
~DisableDebugScope()665 DisableDebugScope::~DisableDebugScope()
666 {
667 // if we disabled debugging and debugging didn't end during the command
668 // evaluation, restore debugging
669 if (env_ != nullptr && !atTopLevelContext())
670 {
671 SET_RDEBUG(env_, rdebug_);
672 }
673 }
674
getWasInterrupted()675 bool getWasInterrupted()
676 {
677 return s_wasInterrupted;
678 }
679
setWasInterrupted(bool wasInterrupted)680 void setWasInterrupted(bool wasInterrupted)
681 {
682 s_wasInterrupted = wasInterrupted;
683 }
684
685 } // namespace exec
686 } // namespace r
687 } // namespace rstudio
688
689
690
691