Skip to content

cpp11::warning(const char*) crashes but cpp11::warning(const std::string&) does not #295

Closed as not planned
@paleolimbot

Description

@paleolimbot

This is a very odd error and is difficult to reproduce; however, I haven't been able to isolate any change in Arrow's code that may have caused this to occur. The PR where this is observed is apache/arrow#14271. Feel free to close this as obscure...I just thought it may be useful to document this somewhere in case anybody runs into this problem again.

Basically, on that one PR, all calls to cpp11::warning(const char*, ...) crash with a bad memory access in std::tuple::get(). cpp11::warning(const std::string&, ...) does not crash, nor does cpp11::safe[R_warningcall](R_NilValue, const char*, ...). This is not the case anywhere except that PR; however, I don't need to invoke any changed code in that PR to make the crash happen (the PR is about ALTREP, but you can cause a crash with just a single function that only calls cpp11::warning(const char*, ...)

A reprex to illustrate the alternatives that work and the call that causes a crash:

# May or may not be important, but Arrow is on C++17
Sys.setenv("CXX_STD" = "CXX17")

cpp11::cpp_source(code = '

#include <cpp11.hpp>

// Not sure if this is related, but the crash always seems to be on
// tuple::get() and I wonder if two versions of this header are somehow
// finding their way into the objects
#include <tuple>

void my_safe_warningcall() {
  cpp11::safe[Rf_warningcall](R_NilValue, "some message");
}

void my_warning_string() {
  cpp11::warning(std::string("some message"));
}

void my_warning_const_char() {
  cpp11::warning("some message");
}


[[cpp11::register]]
void my_warning_call_wrapper(std::string opt) {
  if (opt == "safe_warningcall") {
    my_safe_warningcall();
  } else if (opt == "warning_string") {
    my_warning_string();
  } else {
    my_warning_const_char();
  }
}
')

# works!
my_warning_call_wrapper("safe_warningcall")
#> Warning: some message
# works!
my_warning_call_wrapper("warning_string")
#> Warning: some message
# crashes (on that one branch)!
my_warning_call_wrapper("warning_const_char")
#> Warning: some message

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions