镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

warning can longjmp when condition handlers are on the stack, causing leaks #1474

Closed

Description

@kevinushey

Originally from the Rcpp-devel mailing list:

R -d "valgrind --tool=memcheck --leak-check=full --track-origins=yes" \
	-e "Rcpp::cppFunction('Rcpp::DataFrame test(SEXP a, SEXP b) { \
	      Rcpp::DataFrame DF; \
	      DF.push_back(a);    \
	      DF.push_back(b);    \
	      return DF; }');     \
            tryCatch( test(1:4, 11:15), warning = function(w) {} )"

This gives the leak report:

==307332== 78 bytes in 1 blocks are definitely lost in loss record 37 of 1,605
==307332==    at 0x48859FC: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==307332==    by 0x8923B7B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.33)
==307332==    by 0x8924ED3: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.33)
==307332==    by 0x2462C4AF: replace (basic_string.h:2208)
==307332==    by 0x2462C4AF: replace (basic_string.h:2405)
==307332==    by 0x2462C4AF: assign<char*> (basic_string.h:1719)
==307332==    by 0x2462C4AF: str (sstream:253)
==307332==    by 0x2462C4AF: str (sstream:931)
==307332==    by 0x2462C4AF: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > tinyformat::format<>(char const*) (tinyformat.h:976)
==307332==    by 0x2462C88F: warning<> (exceptions.h:189)
==307332==    by 0x2462C88F: Rcpp::DataFrame_Impl<Rcpp::PreserveStorage>::set_type_after_push() (DataFrame.h:142)
==307332==    by 0x24625CFB: push_back<SEXPREC*> (DataFrame.h:77)
==307332==    by 0x24625CFB: test(SEXPREC*, SEXPREC*) (file4b0845e6c9e5c.cpp:6)
==307332==    by 0x24625F23: sourceCpp_1_test (file4b0845e6c9e5c.cpp:23)
==307332==    by 0x49C0167: ??? (in /usr/lib/R/lib/libR.so)
==307332==    by 0x49C0733: ??? (in /usr/lib/R/lib/libR.so)
==307332==    by 0x4A18C0B: Rf_eval (in /usr/lib/R/lib/libR.so)
==307332==    by 0x4A1A96B: ??? (in /usr/lib/R/lib/libR.so)
==307332==    by 0x4A1B7D3: Rf_applyClosure (in /usr/lib/R/lib/libR.so)

which comes specifically from here:

template <typename... Args>
inline void warning(const char* fmt, Args&&... args ) {
Rf_warning("%s", tfm::format(fmt, std::forward<Args>(args)... ).c_str());
} // #nocov end

We're creating a std::string from tfm::format, but that string is getting lost after Rf_warning() causes a longjmp (by virtue of being used with a calling handler from tryCatch being active).

Activity

  1. added a commit that references this issue on Jun 28, 2026
    d582dd4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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