Skip to content

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

Closed
@Anthony-Nicholls

Description

@Anthony-Nicholls

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.

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