diff --git a/.github/workflows/test-ubsan.yml b/.github/workflows/test-ubsan.yml new file mode 100644 index 00000000000000..e2f3ddef56c45a --- /dev/null +++ b/.github/workflows/test-ubsan.yml @@ -0,0 +1,61 @@ +name: Test UBSan + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths-ignore: + - .mailmap + - '**.md' + - AUTHORS + - doc/** + - .github/** + - '!.github/workflows/ubsan-asan.yml' + push: + branches: + - main + - canary + - v[0-9]+.x-staging + - v[0-9]+.x + paths-ignore: + - .mailmap + - '**.md' + - AUTHORS + - doc/** + - .github/** + - '!.github/workflows/ubsan-asan.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + ASAN_OPTIONS: intercept_tls_get_addr=0 + PYTHON_VERSION: '3.11' + FLAKY_TESTS: keep_retrying + +permissions: + contents: read + +jobs: + test-ubsan: + if: github.event.pull_request.draft == false + runs-on: ubuntu-20.04 + env: + CC: clang + CXX: clang++ + LINK: clang++ + CONFIG_FLAGS: --enable-ubsan + steps: + - uses: actions/checkout@v3 + with: + persist-credentials: false + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@v4 + with: + python-version: ${{ env.PYTHON_VERSION }} + - name: Environment Information + run: npx envinfo + - name: Build + run: make build-ci -j2 V=1 + - name: Test + run: make run-ci -j2 V=1 TEST_CI_ARGS="-p actions -t 300 --measure-flakiness 9" diff --git a/common.gypi b/common.gypi index 0ce5c5226d9571..fbcfe5afb1e231 100644 --- a/common.gypi +++ b/common.gypi @@ -2,6 +2,7 @@ 'variables': { 'configuring_node%': 0, 'asan%': 0, + 'ubsan%': 0, 'werror': '', # Turn off -Werror in V8 build. 'visibility%': 'hidden', # V8's visibility setting 'target_arch%': 'ia32', # set v8's target architecture @@ -369,6 +370,32 @@ }], ], }], + ['ubsan == 1 and OS != "mac" and OS != "zos"', { + 'cflags+': [ + '-fno-omit-frame-pointer', + '-fsanitize=undefined', + ], + 'defines': [ 'UNDEFINED_SANITIZER'], + 'cflags!': [ '-fomit-frame-pointer' ], + 'ldflags': [ '-fsanitize=undefined' ], + }], + ['ubsan == 1 and OS == "mac"', { + 'xcode_settings': { + 'OTHER_CFLAGS+': [ + '-fno-omit-frame-pointer', + '-gline-tables-only', + '-fsanitize=undefined' + ], + 'OTHER_CFLAGS!': [ + '-fomit-frame-pointer', + ], + }, + 'target_conditions': [ + ['_type!="static_library"', { + 'xcode_settings': {'OTHER_LDFLAGS': ['-fsanitize=undefined']}, + }], + ], + }], ['v8_enable_pointer_compression == 1', { 'defines': [ 'V8_COMPRESS_POINTERS', diff --git a/configure.py b/configure.py index 4ebb5606be4f6c..49ab382c39cafe 100755 --- a/configure.py +++ b/configure.py @@ -710,6 +710,12 @@ default=None, help='compile for Address Sanitizer to find memory bugs') +parser.add_argument('--enable-ubsan', + action='store_true', + dest='enable_ubsan', + default=None, + help='compile for Undefined Behavior Sanitizer') + parser.add_argument('--enable-static', action='store_true', dest='enable_static', @@ -1407,6 +1413,7 @@ def configure_node(o): o['variables']['library_files'] = options.linked_module o['variables']['asan'] = int(options.enable_asan or 0) + o['variables']['ubsan'] = int(options.enable_ubsan or 0) if options.coverage: o['variables']['coverage'] = 'true'