Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuickJS may throw erroneous exceptions if address and undefined behaviour sanitises are both enabled #59

Closed
Anthony-Nicholls opened this issue Oct 25, 2024 · 3 comments

Comments

@Anthony-Nicholls
Copy link
Contributor

I've only encountered this in Xcode (tested with 15.4 and 16.0) on macOS Sonoma (14.5), running on an M2 Max. However, others in the JUCE team have reproduced the issue on other configurations, including on an Intel processor. However, it seems different javascript code may be required to induce the problem with Intel processors. The test code included below was all tested with

  • Xcode 16.0
  • macOS Sonoma 14.5
  • M2 Max

I haven't explored reproducing this with other compilers such as GCC yet.

To reproduce the issue all the following must be true

  • Compiler optimisations are disabled
  • Undefined Behaviour Sanitiser is enabled
  • Address Sanitiser is enabled
  • Detect use of stack after return is disabled

I've tried to reproduce this with just QuickJS and I succeeded when using the version bundled with CHOC but not with the latest version of QuickJS on the official GitHub mirror. However, I think it's very likely the issue still exists in that version but I was likely missing something. As far as I can tell the code relating to this issue has not changed. I suspect most people wouldn't hit this using QuickJS directly as they would dynamically or statically link to the library built with different flags.

The code below should help in reproducing the issue.

#include "choc/javascript/choc_javascript_QuickJS.h"

static const std::string example = R"(
function f1() { return 0 }
function f2() { return f1() }
f2()
)";

int main()
{
    auto context = choc::javascript::createQuickJSContext();
    context.evaluateExpression (example);
    return 0;
}

One possible solution I've explored is simply to not define CONFIG_STACK_CHECK if either of the sanitisers are enabled. For example adding something like this...

#if defined (__has_feature)
 #if __has_feature (address_sanitizer) && __has_feature (undefined_behavior_sanitizer)
  #undef CONFIG_STACK_CHECK
 #endif
#endif

If the issue occurs in GCC you can apparently check for the address sanitiser using the __SANITIZE_ADDRESS__ preprocessor definition, but as far as I can tell you can't check for the undefined behaviour sanitiser.

@julianstorer
Copy link
Collaborator

Hi Anthony

Yeah, turning it off if the sanitiser is enabled seems pretty pragmatic. I'm happy to chuck your

#if defined (__has_feature)
 #if __has_feature (address_sanitizer) && __has_feature (undefined_behavior_sanitizer)
  #undef CONFIG_STACK_CHECK
 #endif
#endif

suggestion in there if that does the trick

@Anthony-Nicholls
Copy link
Contributor Author

Hey Jules,

Thanks for the fast reply I wanted to do a little more testing before committing to saying yes. The code I've provided appears to work in clang 8.0.0+ (which maps to Xcode 8.0+) and gcc 14.1+. I think it should be safe to go ahead with that.

Thanks again.

@julianstorer
Copy link
Collaborator

OK, will do, cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants