Cheng Shao pushed to branch wip/terrorjack/asan at Glasgow Haskell Compiler / GHC
Commits:
-
a160554c
by Cheng Shao at 2026-06-23T08:37:24+00:00
-
1ee9e876
by Cheng Shao at 2026-06-23T08:37:34+00:00
-
12b1c4e1
by Cheng Shao at 2026-06-23T08:37:34+00:00
-
d69db72c
by Cheng Shao at 2026-06-23T08:37:34+00:00
-
a9ba6486
by Cheng Shao at 2026-06-23T08:37:34+00:00
-
a1c625f1
by Cheng Shao at 2026-06-23T08:37:34+00:00
-
22a39627
by Cheng Shao at 2026-06-23T08:37:34+00:00
-
65d3c885
by Cheng Shao at 2026-06-23T08:37:34+00:00
-
73c0b897
by Cheng Shao at 2026-06-23T08:37:34+00:00
18 changed files:
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- hadrian/doc/flavours.md
- hadrian/src/Flavour.hs
- rts/Hash.c
- rts/Task.c
- rts/include/Stg.h
- + rts/include/rts/ASANUtils.h
- rts/rts.cabal
- rts/sm/BlockAlloc.c
- rts/sm/GCUtils.c
- rts/sm/MBlock.c
- rts/sm/Storage.c
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/tests/ffi/should_run/all.T
- testsuite/tests/rts/T18623/all.T
- testsuite/tests/rts/all.T
Changes:
| ... | ... | @@ -167,6 +167,7 @@ data BuildConfig |
| 167 | 167 | , tablesNextToCode :: Bool
|
| 168 | 168 | , threadSanitiser :: Bool
|
| 169 | 169 | , ubsan :: Bool
|
| 170 | + , asan :: Bool
|
|
| 170 | 171 | , noSplitSections :: Bool
|
| 171 | 172 | , validateNonmovingGc :: Bool
|
| 172 | 173 | , textWithSIMDUTF :: Bool
|
| ... | ... | @@ -178,7 +179,7 @@ configureArgsStr :: BuildConfig -> String |
| 178 | 179 | configureArgsStr bc = unwords $
|
| 179 | 180 | ["--enable-unregisterised"| unregisterised bc ]
|
| 180 | 181 | ++ ["--disable-tables-next-to-code" | not (tablesNextToCode bc) ]
|
| 181 | - ++ ["--with-intree-gmp" | Just _ <- [crossTarget bc] ]
|
|
| 182 | + ++ ["--with-intree-gmp" | isJust (crossTarget bc) || ubsan bc || asan bc ]
|
|
| 182 | 183 | ++ ["--with-system-libffi" | crossTarget bc == Just "wasm32-wasi" ]
|
| 183 | 184 | ++ ["--enable-ipe-data-compression" | withZstd bc ]
|
| 184 | 185 | ++ ["--enable-strict-ghc-toolchain-check"]
|
| ... | ... | @@ -193,6 +194,7 @@ mkJobFlavour BuildConfig{..} = Flavour buildFlavour opts |
| 193 | 194 | [HostFullyStatic | hostFullyStatic] ++
|
| 194 | 195 | [ThreadSanitiser | threadSanitiser] ++
|
| 195 | 196 | [UBSan | ubsan] ++
|
| 197 | + [ASan | asan] ++
|
|
| 196 | 198 | [NoSplitSections | noSplitSections, buildFlavour == Release ] ++
|
| 197 | 199 | [BootNonmovingGc | validateNonmovingGc ] ++
|
| 198 | 200 | [TextWithSIMDUTF | textWithSIMDUTF]
|
| ... | ... | @@ -206,11 +208,12 @@ data FlavourTrans = |
| 206 | 208 | | HostFullyStatic
|
| 207 | 209 | | ThreadSanitiser
|
| 208 | 210 | | UBSan
|
| 211 | + | ASan
|
|
| 209 | 212 | | NoSplitSections
|
| 210 | 213 | | BootNonmovingGc
|
| 211 | 214 | | TextWithSIMDUTF
|
| 212 | 215 | |
| 213 | -data BaseFlavour = Release | Validate | SlowValidate deriving Eq
|
|
| 216 | +data BaseFlavour = Release | QuickValidate | Validate | SlowValidate deriving Eq
|
|
| 214 | 217 | |
| 215 | 218 | -----------------------------------------------------------------------------
|
| 216 | 219 | -- Build Configurations
|
| ... | ... | @@ -236,6 +239,7 @@ vanilla = BuildConfig |
| 236 | 239 | , tablesNextToCode = True
|
| 237 | 240 | , threadSanitiser = False
|
| 238 | 241 | , ubsan = False
|
| 242 | + , asan = False
|
|
| 239 | 243 | , noSplitSections = False
|
| 240 | 244 | , validateNonmovingGc = False
|
| 241 | 245 | , textWithSIMDUTF = False
|
| ... | ... | @@ -290,8 +294,14 @@ llvm = vanilla { llvmBootstrap = True } |
| 290 | 294 | tsan :: BuildConfig
|
| 291 | 295 | tsan = vanilla { threadSanitiser = True }
|
| 292 | 296 | |
| 293 | -enableUBSan :: BuildConfig
|
|
| 294 | -enableUBSan = vanilla { withDwarf = True, ubsan = True }
|
|
| 297 | +sanitizers :: BuildConfig
|
|
| 298 | +sanitizers =
|
|
| 299 | + vanilla
|
|
| 300 | + { buildFlavour = QuickValidate,
|
|
| 301 | + withDwarf = True,
|
|
| 302 | + ubsan = True,
|
|
| 303 | + asan = True
|
|
| 304 | + }
|
|
| 295 | 305 | |
| 296 | 306 | noTntc :: BuildConfig
|
| 297 | 307 | noTntc = vanilla { tablesNextToCode = False }
|
| ... | ... | @@ -376,6 +386,7 @@ flavourString :: Flavour -> String |
| 376 | 386 | flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . flavour_string) trans
|
| 377 | 387 | where
|
| 378 | 388 | base_string Release = "release"
|
| 389 | + base_string QuickValidate = "quick-validate"
|
|
| 379 | 390 | base_string Validate = "validate"
|
| 380 | 391 | base_string SlowValidate = "slow-validate"
|
| 381 | 392 | |
| ... | ... | @@ -385,6 +396,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f |
| 385 | 396 | flavour_string HostFullyStatic = "host_fully_static"
|
| 386 | 397 | flavour_string ThreadSanitiser = "thread_sanitizer_cmm"
|
| 387 | 398 | flavour_string UBSan = "ubsan"
|
| 399 | + flavour_string ASan = "asan"
|
|
| 388 | 400 | flavour_string NoSplitSections = "no_split_sections"
|
| 389 | 401 | flavour_string BootNonmovingGc = "boot_nonmoving_gc"
|
| 390 | 402 | flavour_string TextWithSIMDUTF = "text_simdutf"
|
| ... | ... | @@ -723,6 +735,7 @@ data ValidateRule |
| 723 | 735 | | WasmBackend -- ^ Run this job when the "wasm" label is present
|
| 724 | 736 | | FreeBSDLabel -- ^ Run this job when the "FreeBSD" label is set.
|
| 725 | 737 | | NonmovingGc -- ^ Run this job when the "non-moving GC" label is set.
|
| 738 | + | Sanitizers -- ^ Run this job when the "test-sanitizers" label is set.
|
|
| 726 | 739 | | IpeData -- ^ Run this job when the "IPE" label is set
|
| 727 | 740 | | TestPrimops -- ^ Run this job when "test-primops" label is set
|
| 728 | 741 | | I386Backend -- ^ Run this job when the "i386" label is set
|
| ... | ... | @@ -770,6 +783,7 @@ validateRuleString RiscV = labelString "RISC-V" |
| 770 | 783 | validateRuleString WasmBackend = labelString "wasm"
|
| 771 | 784 | validateRuleString FreeBSDLabel = labelString "FreeBSD"
|
| 772 | 785 | validateRuleString NonmovingGc = labelString "non-moving GC"
|
| 786 | +validateRuleString Sanitizers = labelString "test-sanitizers"
|
|
| 773 | 787 | validateRuleString IpeData = labelString "IPE"
|
| 774 | 788 | validateRuleString TestPrimops = labelString "test-primops"
|
| 775 | 789 | validateRuleString I386Backend = labelString "i386"
|
| ... | ... | @@ -1231,15 +1245,25 @@ fedora_x86 = |
| 1231 | 1245 | , hackage_doc_job (disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) releaseConfig))
|
| 1232 | 1246 | , disableValidate (standardBuildsWithConfig Amd64 (Linux Fedora43) dwarf)
|
| 1233 | 1247 | , disableValidate (standardBuilds Amd64 (Linux Fedora43))
|
| 1234 | - -- For UBSan jobs, only enable for validate/nightly pipelines.
|
|
| 1235 | - -- Also disable docs since it's not the point for UBSan jobs.
|
|
| 1248 | + -- For UBSan/ASan jobs, only enable for validate/nightly
|
|
| 1249 | + -- pipelines. Disable docs and use quick-validate to skip
|
|
| 1250 | + -- linting/assertion to avoid unnecessary overhead.
|
|
| 1251 | + --
|
|
| 1252 | + -- See
|
|
| 1253 | + -- https://github.com/llvm/llvm-project/blob/llvmorg-21.1.8/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
|
|
| 1254 | + -- for ASAN options help, for now these are required to pass the
|
|
| 1255 | + -- testsuite
|
|
| 1236 | 1256 | , modifyJobs
|
| 1237 | 1257 | ( setVariable "HADRIAN_ARGS" "--docs=none"
|
| 1238 | 1258 | . addVariable
|
| 1239 | 1259 | "UBSAN_OPTIONS"
|
| 1240 | 1260 | "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions"
|
| 1261 | + . addVariable
|
|
| 1262 | + "ASAN_OPTIONS"
|
|
| 1263 | + "detect_leaks=false:handle_segv=0:handle_sigfpe=0:verify_asan_link_order=false"
|
|
| 1241 | 1264 | )
|
| 1242 | - $ validateBuilds Amd64 (Linux Fedora43) enableUBSan
|
|
| 1265 | + $ addValidateRule Sanitizers
|
|
| 1266 | + $ validateBuilds Amd64 (Linux Fedora43) sanitizers
|
|
| 1243 | 1267 | ]
|
| 1244 | 1268 | where
|
| 1245 | 1269 | hackage_doc_job = rename (<> "-hackage") . modifyJobs (addVariable "HADRIAN_ARGS" "--haddock-for-hackage")
|
| ... | ... | @@ -3142,7 +3142,7 @@ |
| 3142 | 3142 | "XZ_OPT": "-9"
|
| 3143 | 3143 | }
|
| 3144 | 3144 | },
|
| 3145 | - "nightly-x86_64-linux-fedora43-release": {
|
|
| 3145 | + "nightly-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan": {
|
|
| 3146 | 3146 | "after_script": [
|
| 3147 | 3147 | ".gitlab/ci.sh save_cache",
|
| 3148 | 3148 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -3153,7 +3153,7 @@ |
| 3153 | 3153 | "artifacts": {
|
| 3154 | 3154 | "expire_in": "8 weeks",
|
| 3155 | 3155 | "paths": [
|
| 3156 | - "ghc-x86_64-linux-fedora43-release.tar.xz",
|
|
| 3156 | + "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan.tar.xz",
|
|
| 3157 | 3157 | "junit.xml",
|
| 3158 | 3158 | "unexpected-test-output.tar.gz"
|
| 3159 | 3159 | ],
|
| ... | ... | @@ -3195,17 +3195,20 @@ |
| 3195 | 3195 | "x86_64-linux"
|
| 3196 | 3196 | ],
|
| 3197 | 3197 | "variables": {
|
| 3198 | + "ASAN_OPTIONS": "detect_leaks=false:handle_segv=0:handle_sigfpe=0:verify_asan_link_order=false",
|
|
| 3198 | 3199 | "BIGNUM_BACKEND": "gmp",
|
| 3199 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
|
|
| 3200 | - "BUILD_FLAVOUR": "release",
|
|
| 3201 | - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
|
| 3200 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
|
|
| 3201 | + "BUILD_FLAVOUR": "quick-validate+debug_info+ubsan+asan",
|
|
| 3202 | + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
|
|
| 3203 | + "HADRIAN_ARGS": "--docs=none",
|
|
| 3202 | 3204 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3203 | 3205 | "RUNTEST_ARGS": "",
|
| 3204 | - "TEST_ENV": "x86_64-linux-fedora43-release",
|
|
| 3206 | + "TEST_ENV": "x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
|
|
| 3207 | + "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions",
|
|
| 3205 | 3208 | "XZ_OPT": "-9"
|
| 3206 | 3209 | }
|
| 3207 | 3210 | },
|
| 3208 | - "nightly-x86_64-linux-fedora43-release-hackage": {
|
|
| 3211 | + "nightly-x86_64-linux-fedora43-release": {
|
|
| 3209 | 3212 | "after_script": [
|
| 3210 | 3213 | ".gitlab/ci.sh save_cache",
|
| 3211 | 3214 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -3262,14 +3265,13 @@ |
| 3262 | 3265 | "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
|
| 3263 | 3266 | "BUILD_FLAVOUR": "release",
|
| 3264 | 3267 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3265 | - "HADRIAN_ARGS": "--haddock-for-hackage",
|
|
| 3266 | 3268 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3267 | 3269 | "RUNTEST_ARGS": "",
|
| 3268 | 3270 | "TEST_ENV": "x86_64-linux-fedora43-release",
|
| 3269 | 3271 | "XZ_OPT": "-9"
|
| 3270 | 3272 | }
|
| 3271 | 3273 | },
|
| 3272 | - "nightly-x86_64-linux-fedora43-validate": {
|
|
| 3274 | + "nightly-x86_64-linux-fedora43-release-hackage": {
|
|
| 3273 | 3275 | "after_script": [
|
| 3274 | 3276 | ".gitlab/ci.sh save_cache",
|
| 3275 | 3277 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -3280,7 +3282,7 @@ |
| 3280 | 3282 | "artifacts": {
|
| 3281 | 3283 | "expire_in": "8 weeks",
|
| 3282 | 3284 | "paths": [
|
| 3283 | - "ghc-x86_64-linux-fedora43-validate.tar.xz",
|
|
| 3285 | + "ghc-x86_64-linux-fedora43-release.tar.xz",
|
|
| 3284 | 3286 | "junit.xml",
|
| 3285 | 3287 | "unexpected-test-output.tar.gz"
|
| 3286 | 3288 | ],
|
| ... | ... | @@ -3323,16 +3325,17 @@ |
| 3323 | 3325 | ],
|
| 3324 | 3326 | "variables": {
|
| 3325 | 3327 | "BIGNUM_BACKEND": "gmp",
|
| 3326 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
|
|
| 3327 | - "BUILD_FLAVOUR": "validate",
|
|
| 3328 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
|
|
| 3329 | + "BUILD_FLAVOUR": "release",
|
|
| 3328 | 3330 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3331 | + "HADRIAN_ARGS": "--haddock-for-hackage",
|
|
| 3329 | 3332 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3330 | 3333 | "RUNTEST_ARGS": "",
|
| 3331 | - "TEST_ENV": "x86_64-linux-fedora43-validate",
|
|
| 3334 | + "TEST_ENV": "x86_64-linux-fedora43-release",
|
|
| 3332 | 3335 | "XZ_OPT": "-9"
|
| 3333 | 3336 | }
|
| 3334 | 3337 | },
|
| 3335 | - "nightly-x86_64-linux-fedora43-validate+debug_info": {
|
|
| 3338 | + "nightly-x86_64-linux-fedora43-validate": {
|
|
| 3336 | 3339 | "after_script": [
|
| 3337 | 3340 | ".gitlab/ci.sh save_cache",
|
| 3338 | 3341 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -3343,7 +3346,7 @@ |
| 3343 | 3346 | "artifacts": {
|
| 3344 | 3347 | "expire_in": "8 weeks",
|
| 3345 | 3348 | "paths": [
|
| 3346 | - "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
|
|
| 3349 | + "ghc-x86_64-linux-fedora43-validate.tar.xz",
|
|
| 3347 | 3350 | "junit.xml",
|
| 3348 | 3351 | "unexpected-test-output.tar.gz"
|
| 3349 | 3352 | ],
|
| ... | ... | @@ -3386,16 +3389,16 @@ |
| 3386 | 3389 | ],
|
| 3387 | 3390 | "variables": {
|
| 3388 | 3391 | "BIGNUM_BACKEND": "gmp",
|
| 3389 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
|
|
| 3390 | - "BUILD_FLAVOUR": "validate+debug_info",
|
|
| 3392 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
|
|
| 3393 | + "BUILD_FLAVOUR": "validate",
|
|
| 3391 | 3394 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3392 | 3395 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3393 | 3396 | "RUNTEST_ARGS": "",
|
| 3394 | - "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info",
|
|
| 3397 | + "TEST_ENV": "x86_64-linux-fedora43-validate",
|
|
| 3395 | 3398 | "XZ_OPT": "-9"
|
| 3396 | 3399 | }
|
| 3397 | 3400 | },
|
| 3398 | - "nightly-x86_64-linux-fedora43-validate+debug_info+ubsan": {
|
|
| 3401 | + "nightly-x86_64-linux-fedora43-validate+debug_info": {
|
|
| 3399 | 3402 | "after_script": [
|
| 3400 | 3403 | ".gitlab/ci.sh save_cache",
|
| 3401 | 3404 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -3406,7 +3409,7 @@ |
| 3406 | 3409 | "artifacts": {
|
| 3407 | 3410 | "expire_in": "8 weeks",
|
| 3408 | 3411 | "paths": [
|
| 3409 | - "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan.tar.xz",
|
|
| 3412 | + "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
|
|
| 3410 | 3413 | "junit.xml",
|
| 3411 | 3414 | "unexpected-test-output.tar.gz"
|
| 3412 | 3415 | ],
|
| ... | ... | @@ -3449,14 +3452,12 @@ |
| 3449 | 3452 | ],
|
| 3450 | 3453 | "variables": {
|
| 3451 | 3454 | "BIGNUM_BACKEND": "gmp",
|
| 3452 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan",
|
|
| 3453 | - "BUILD_FLAVOUR": "validate+debug_info+ubsan",
|
|
| 3455 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
|
|
| 3456 | + "BUILD_FLAVOUR": "validate+debug_info",
|
|
| 3454 | 3457 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3455 | - "HADRIAN_ARGS": "--docs=none",
|
|
| 3456 | 3458 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 3457 | 3459 | "RUNTEST_ARGS": "",
|
| 3458 | - "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info+ubsan",
|
|
| 3459 | - "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions",
|
|
| 3460 | + "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info",
|
|
| 3460 | 3461 | "XZ_OPT": "-9"
|
| 3461 | 3462 | }
|
| 3462 | 3463 | },
|
| ... | ... | @@ -7051,7 +7052,7 @@ |
| 7051 | 7052 | "TEST_ENV": "x86_64-linux-deb13-zstd-validate"
|
| 7052 | 7053 | }
|
| 7053 | 7054 | },
|
| 7054 | - "x86_64-linux-fedora43-release": {
|
|
| 7055 | + "x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan": {
|
|
| 7055 | 7056 | "after_script": [
|
| 7056 | 7057 | ".gitlab/ci.sh save_cache",
|
| 7057 | 7058 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -7062,7 +7063,7 @@ |
| 7062 | 7063 | "artifacts": {
|
| 7063 | 7064 | "expire_in": "2 weeks",
|
| 7064 | 7065 | "paths": [
|
| 7065 | - "ghc-x86_64-linux-fedora43-release.tar.xz",
|
|
| 7066 | + "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan.tar.xz",
|
|
| 7066 | 7067 | "junit.xml",
|
| 7067 | 7068 | "unexpected-test-output.tar.gz"
|
| 7068 | 7069 | ],
|
| ... | ... | @@ -7088,7 +7089,7 @@ |
| 7088 | 7089 | ],
|
| 7089 | 7090 | "rules": [
|
| 7090 | 7091 | {
|
| 7091 | - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7092 | + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-quick-validate\\+debug_info\\+ubsan\\+asan(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*test-sanitizers.*/)))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7092 | 7093 | "when": "on_success"
|
| 7093 | 7094 | }
|
| 7094 | 7095 | ],
|
| ... | ... | @@ -7104,16 +7105,19 @@ |
| 7104 | 7105 | "x86_64-linux"
|
| 7105 | 7106 | ],
|
| 7106 | 7107 | "variables": {
|
| 7108 | + "ASAN_OPTIONS": "detect_leaks=false:handle_segv=0:handle_sigfpe=0:verify_asan_link_order=false",
|
|
| 7107 | 7109 | "BIGNUM_BACKEND": "gmp",
|
| 7108 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
|
|
| 7109 | - "BUILD_FLAVOUR": "release",
|
|
| 7110 | - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
|
| 7110 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
|
|
| 7111 | + "BUILD_FLAVOUR": "quick-validate+debug_info+ubsan+asan",
|
|
| 7112 | + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
|
|
| 7113 | + "HADRIAN_ARGS": "--docs=none",
|
|
| 7111 | 7114 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7112 | 7115 | "RUNTEST_ARGS": "",
|
| 7113 | - "TEST_ENV": "x86_64-linux-fedora43-release"
|
|
| 7116 | + "TEST_ENV": "x86_64-linux-fedora43-quick-validate+debug_info+ubsan+asan",
|
|
| 7117 | + "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions"
|
|
| 7114 | 7118 | }
|
| 7115 | 7119 | },
|
| 7116 | - "x86_64-linux-fedora43-release-hackage": {
|
|
| 7120 | + "x86_64-linux-fedora43-release": {
|
|
| 7117 | 7121 | "after_script": [
|
| 7118 | 7122 | ".gitlab/ci.sh save_cache",
|
| 7119 | 7123 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -7150,7 +7154,7 @@ |
| 7150 | 7154 | ],
|
| 7151 | 7155 | "rules": [
|
| 7152 | 7156 | {
|
| 7153 | - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7157 | + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && ((\"true\" == \"true\")))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7154 | 7158 | "when": "on_success"
|
| 7155 | 7159 | }
|
| 7156 | 7160 | ],
|
| ... | ... | @@ -7170,13 +7174,12 @@ |
| 7170 | 7174 | "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
|
| 7171 | 7175 | "BUILD_FLAVOUR": "release",
|
| 7172 | 7176 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7173 | - "HADRIAN_ARGS": "--haddock-for-hackage",
|
|
| 7174 | 7177 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7175 | 7178 | "RUNTEST_ARGS": "",
|
| 7176 | 7179 | "TEST_ENV": "x86_64-linux-fedora43-release"
|
| 7177 | 7180 | }
|
| 7178 | 7181 | },
|
| 7179 | - "x86_64-linux-fedora43-validate": {
|
|
| 7182 | + "x86_64-linux-fedora43-release-hackage": {
|
|
| 7180 | 7183 | "after_script": [
|
| 7181 | 7184 | ".gitlab/ci.sh save_cache",
|
| 7182 | 7185 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -7187,7 +7190,7 @@ |
| 7187 | 7190 | "artifacts": {
|
| 7188 | 7191 | "expire_in": "2 weeks",
|
| 7189 | 7192 | "paths": [
|
| 7190 | - "ghc-x86_64-linux-fedora43-validate.tar.xz",
|
|
| 7193 | + "ghc-x86_64-linux-fedora43-release.tar.xz",
|
|
| 7191 | 7194 | "junit.xml",
|
| 7192 | 7195 | "unexpected-test-output.tar.gz"
|
| 7193 | 7196 | ],
|
| ... | ... | @@ -7213,7 +7216,7 @@ |
| 7213 | 7216 | ],
|
| 7214 | 7217 | "rules": [
|
| 7215 | 7218 | {
|
| 7216 | - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7219 | + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-release(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7217 | 7220 | "when": "on_success"
|
| 7218 | 7221 | }
|
| 7219 | 7222 | ],
|
| ... | ... | @@ -7230,15 +7233,16 @@ |
| 7230 | 7233 | ],
|
| 7231 | 7234 | "variables": {
|
| 7232 | 7235 | "BIGNUM_BACKEND": "gmp",
|
| 7233 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
|
|
| 7234 | - "BUILD_FLAVOUR": "validate",
|
|
| 7236 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-release",
|
|
| 7237 | + "BUILD_FLAVOUR": "release",
|
|
| 7235 | 7238 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7239 | + "HADRIAN_ARGS": "--haddock-for-hackage",
|
|
| 7236 | 7240 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7237 | 7241 | "RUNTEST_ARGS": "",
|
| 7238 | - "TEST_ENV": "x86_64-linux-fedora43-validate"
|
|
| 7242 | + "TEST_ENV": "x86_64-linux-fedora43-release"
|
|
| 7239 | 7243 | }
|
| 7240 | 7244 | },
|
| 7241 | - "x86_64-linux-fedora43-validate+debug_info": {
|
|
| 7245 | + "x86_64-linux-fedora43-validate": {
|
|
| 7242 | 7246 | "after_script": [
|
| 7243 | 7247 | ".gitlab/ci.sh save_cache",
|
| 7244 | 7248 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -7249,7 +7253,7 @@ |
| 7249 | 7253 | "artifacts": {
|
| 7250 | 7254 | "expire_in": "2 weeks",
|
| 7251 | 7255 | "paths": [
|
| 7252 | - "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
|
|
| 7256 | + "ghc-x86_64-linux-fedora43-validate.tar.xz",
|
|
| 7253 | 7257 | "junit.xml",
|
| 7254 | 7258 | "unexpected-test-output.tar.gz"
|
| 7255 | 7259 | ],
|
| ... | ... | @@ -7275,7 +7279,7 @@ |
| 7275 | 7279 | ],
|
| 7276 | 7280 | "rules": [
|
| 7277 | 7281 | {
|
| 7278 | - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7282 | + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7279 | 7283 | "when": "on_success"
|
| 7280 | 7284 | }
|
| 7281 | 7285 | ],
|
| ... | ... | @@ -7292,15 +7296,15 @@ |
| 7292 | 7296 | ],
|
| 7293 | 7297 | "variables": {
|
| 7294 | 7298 | "BIGNUM_BACKEND": "gmp",
|
| 7295 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
|
|
| 7296 | - "BUILD_FLAVOUR": "validate+debug_info",
|
|
| 7299 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate",
|
|
| 7300 | + "BUILD_FLAVOUR": "validate",
|
|
| 7297 | 7301 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7298 | 7302 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7299 | 7303 | "RUNTEST_ARGS": "",
|
| 7300 | - "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info"
|
|
| 7304 | + "TEST_ENV": "x86_64-linux-fedora43-validate"
|
|
| 7301 | 7305 | }
|
| 7302 | 7306 | },
|
| 7303 | - "x86_64-linux-fedora43-validate+debug_info+ubsan": {
|
|
| 7307 | + "x86_64-linux-fedora43-validate+debug_info": {
|
|
| 7304 | 7308 | "after_script": [
|
| 7305 | 7309 | ".gitlab/ci.sh save_cache",
|
| 7306 | 7310 | ".gitlab/ci.sh save_test_output",
|
| ... | ... | @@ -7311,7 +7315,7 @@ |
| 7311 | 7315 | "artifacts": {
|
| 7312 | 7316 | "expire_in": "2 weeks",
|
| 7313 | 7317 | "paths": [
|
| 7314 | - "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan.tar.xz",
|
|
| 7318 | + "ghc-x86_64-linux-fedora43-validate+debug_info.tar.xz",
|
|
| 7315 | 7319 | "junit.xml",
|
| 7316 | 7320 | "unexpected-test-output.tar.gz"
|
| 7317 | 7321 | ],
|
| ... | ... | @@ -7337,7 +7341,7 @@ |
| 7337 | 7341 | ],
|
| 7338 | 7342 | "rules": [
|
| 7339 | 7343 | {
|
| 7340 | - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info\\+ubsan(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7344 | + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-fedora43-validate\\+debug_info(\\s|$).*/)) || (($ONLY_JOBS == null) && (\"disabled\" != \"disabled\"))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
|
|
| 7341 | 7345 | "when": "on_success"
|
| 7342 | 7346 | }
|
| 7343 | 7347 | ],
|
| ... | ... | @@ -7354,14 +7358,12 @@ |
| 7354 | 7358 | ],
|
| 7355 | 7359 | "variables": {
|
| 7356 | 7360 | "BIGNUM_BACKEND": "gmp",
|
| 7357 | - "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info+ubsan",
|
|
| 7358 | - "BUILD_FLAVOUR": "validate+debug_info+ubsan",
|
|
| 7361 | + "BIN_DIST_NAME": "ghc-x86_64-linux-fedora43-validate+debug_info",
|
|
| 7362 | + "BUILD_FLAVOUR": "validate+debug_info",
|
|
| 7359 | 7363 | "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7360 | - "HADRIAN_ARGS": "--docs=none",
|
|
| 7361 | 7364 | "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
|
| 7362 | 7365 | "RUNTEST_ARGS": "",
|
| 7363 | - "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info+ubsan",
|
|
| 7364 | - "UBSAN_OPTIONS": "suppressions=$CI_PROJECT_DIR/rts/.ubsan-suppressions"
|
|
| 7366 | + "TEST_ENV": "x86_64-linux-fedora43-validate+debug_info"
|
|
| 7365 | 7367 | }
|
| 7366 | 7368 | },
|
| 7367 | 7369 | "x86_64-linux-rocky8-validate": {
|
| ... | ... | @@ -218,6 +218,10 @@ The supported transformers are listed below: |
| 218 | 218 | <td><code>ubsan</code></td>
|
| 219 | 219 | <td>Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer support</td>
|
| 220 | 220 | </tr>
|
| 221 | + <tr>
|
|
| 222 | + <td><code>asan</code></td>
|
|
| 223 | + <td>Build all stage1+ C/C++ code with AddressSanitizer support</td>
|
|
| 224 | + </tr>
|
|
| 221 | 225 | <tr>
|
| 222 | 226 | <td><code>llvm</code></td>
|
| 223 | 227 | <td>Use GHC's LLVM backend (`-fllvm`) for all stage1+ compilation.</td>
|
| ... | ... | @@ -8,6 +8,7 @@ module Flavour |
| 8 | 8 | , splitSections
|
| 9 | 9 | , enableThreadSanitizer
|
| 10 | 10 | , enableUBSan
|
| 11 | + , enableASan
|
|
| 11 | 12 | , enableLateCCS
|
| 12 | 13 | , enableHashUnitIds
|
| 13 | 14 | , enableDebugInfo, enableTickyGhc
|
| ... | ... | @@ -58,6 +59,7 @@ flavourTransformers = M.fromList |
| 58 | 59 | , "thread_sanitizer" =: enableThreadSanitizer False
|
| 59 | 60 | , "thread_sanitizer_cmm" =: enableThreadSanitizer True
|
| 60 | 61 | , "ubsan" =: enableUBSan
|
| 62 | + , "asan" =: enableASan
|
|
| 61 | 63 | , "llvm" =: viaLlvmBackend
|
| 62 | 64 | , "profiled_ghc" =: enableProfiledGhc
|
| 63 | 65 | , "no_dynamic_ghc" =: disableDynamicGhcPrograms
|
| ... | ... | @@ -304,6 +306,28 @@ enableUBSan = |
| 304 | 306 | builder Testsuite ? arg "--config=have_ubsan=True"
|
| 305 | 307 | ]
|
| 306 | 308 | |
| 309 | +-- | Build all stage1+ C/C++ code with AddressSanitizer support:
|
|
| 310 | +-- https://clang.llvm.org/docs/AddressSanitizer.html
|
|
| 311 | +enableASan :: Flavour -> Flavour
|
|
| 312 | +enableASan =
|
|
| 313 | + addArgs $
|
|
| 314 | + notStage0
|
|
| 315 | + ? mconcat
|
|
| 316 | + [ package rts
|
|
| 317 | + ? builder (Cabal Flags)
|
|
| 318 | + ? arg "+asan"
|
|
| 319 | + <> (staged needSharedLibSAN ? arg "+shared-libsan"),
|
|
| 320 | + builder (Ghc CompileHs) ? arg "-optc-fsanitize=address",
|
|
| 321 | + builder (Ghc CompileCWithGhc) ? arg "-optc-fsanitize=address",
|
|
| 322 | + builder (Ghc CompileCppWithGhc) ? arg "-optcxx-fsanitize=address",
|
|
| 323 | + builder (Ghc LinkHs)
|
|
| 324 | + ? pure ["-optc-fsanitize=address", "-optl-fsanitize=address"]
|
|
| 325 | + <> (staged needSharedLibSAN ? arg "-optl-shared-libsan"),
|
|
| 326 | + builder (Cc CompileC) ? arg "-fsanitize=address",
|
|
| 327 | + builder Testsuite
|
|
| 328 | + ? pure ["--config=have_asan=True", "-e", "config.timeout=1800"]
|
|
| 329 | + ]
|
|
| 330 | + |
|
| 307 | 331 | -- | Use the LLVM backend in target stages
|
| 308 | 332 | viaLlvmBackend :: Flavour -> Flavour
|
| 309 | 333 | viaLlvmBackend = addArgs $ staged buildingForTarget ? builder Ghc ? arg "-fllvm"
|
| ... | ... | @@ -283,6 +283,7 @@ allocHashList (HashTable *table) |
| 283 | 283 | if (table->freeList != NULL) {
|
| 284 | 284 | HashList *hl = table->freeList;
|
| 285 | 285 | table->freeList = hl->next;
|
| 286 | + __ghc_asan_unpoison_memory_region(hl, offsetof(HashList, next));
|
|
| 286 | 287 | return hl;
|
| 287 | 288 | } else {
|
| 288 | 289 | /* We allocate one block of memory which contains:
|
| ... | ... | @@ -302,8 +303,11 @@ allocHashList (HashTable *table) |
| 302 | 303 | |
| 303 | 304 | table->freeList = hl + 1;
|
| 304 | 305 | HashList *p = table->freeList;
|
| 305 | - for (; p < hl + HCHUNK - 1; p++)
|
|
| 306 | + for (; p < hl + HCHUNK - 1; p++) {
|
|
| 307 | + __ghc_asan_poison_memory_region(p, offsetof(HashList, next));
|
|
| 306 | 308 | p->next = p + 1;
|
| 309 | + }
|
|
| 310 | + __ghc_asan_poison_memory_region(p, offsetof(HashList, next));
|
|
| 307 | 311 | p->next = NULL;
|
| 308 | 312 | return hl;
|
| 309 | 313 | }
|
| ... | ... | @@ -318,6 +322,7 @@ freeHashList (HashTable *table, HashList *hl) |
| 318 | 322 | // HashListChunks.
|
| 319 | 323 | hl->next = table->freeList;
|
| 320 | 324 | table->freeList = hl;
|
| 325 | + __ghc_asan_poison_memory_region(hl, offsetof(HashList, next));
|
|
| 321 | 326 | }
|
| 322 | 327 | |
| 323 | 328 | STATIC_INLINE void
|
| ... | ... | @@ -388,9 +393,10 @@ removeHashTable_inlined(HashTable *table, StgWord key, const void *data, |
| 388 | 393 | table->dir[segment][index] = hl->next;
|
| 389 | 394 | else
|
| 390 | 395 | prev->next = hl->next;
|
| 396 | + void *hl_data = (void*)hl->data;
|
|
| 391 | 397 | freeHashList(table,hl);
|
| 392 | 398 | table->kcount--;
|
| 393 | - return (void *) hl->data;
|
|
| 399 | + return hl_data;
|
|
| 394 | 400 | }
|
| 395 | 401 | prev = hl;
|
| 396 | 402 | }
|
| ... | ... | @@ -183,6 +183,7 @@ freeTask (Task *task) |
| 183 | 183 | stgFree(incall);
|
| 184 | 184 | }
|
| 185 | 185 | for (incall = task->spare_incalls; incall != NULL; incall = next) {
|
| 186 | + __ghc_asan_unpoison_memory_region(incall, sizeof(InCall));
|
|
| 186 | 187 | next = incall->next;
|
| 187 | 188 | stgFree(incall);
|
| 188 | 189 | }
|
| ... | ... | @@ -252,6 +253,7 @@ newInCall (Task *task) |
| 252 | 253 | |
| 253 | 254 | if (task->spare_incalls != NULL) {
|
| 254 | 255 | incall = task->spare_incalls;
|
| 256 | + __ghc_asan_unpoison_memory_region(incall, sizeof(InCall));
|
|
| 255 | 257 | task->spare_incalls = incall->next;
|
| 256 | 258 | task->n_spare_incalls--;
|
| 257 | 259 | } else {
|
| ... | ... | @@ -283,6 +285,7 @@ endInCall (Task *task) |
| 283 | 285 | stgFree(incall);
|
| 284 | 286 | } else {
|
| 285 | 287 | incall->next = task->spare_incalls;
|
| 288 | + __ghc_asan_poison_memory_region(incall, sizeof(InCall));
|
|
| 286 | 289 | task->spare_incalls = incall;
|
| 287 | 290 | task->n_spare_incalls++;
|
| 288 | 291 | }
|
| ... | ... | @@ -331,6 +331,7 @@ external prototype return neither of these types to workaround #11395. |
| 331 | 331 | #include "stg/MachRegsForHost.h"
|
| 332 | 332 | #include "stg/Regs.h"
|
| 333 | 333 | #include "stg/Ticky.h"
|
| 334 | +#include "rts/ASANUtils.h"
|
|
| 334 | 335 | #include "rts/TSANUtils.h"
|
| 335 | 336 | |
| 336 | 337 | #if IN_STG_CODE
|
| 1 | +#pragma once
|
|
| 2 | + |
|
| 3 | +#if defined(__SANITIZE_ADDRESS__)
|
|
| 4 | +#define ASAN_ENABLED
|
|
| 5 | +#elif defined(__has_feature)
|
|
| 6 | +#if __has_feature(address_sanitizer)
|
|
| 7 | +#define ASAN_ENABLED
|
|
| 8 | +#endif
|
|
| 9 | +#endif
|
|
| 10 | + |
|
| 11 | +#if defined(ASAN_ENABLED)
|
|
| 12 | +#include <sanitizer/asan_interface.h>
|
|
| 13 | +#define USED_IF_ASAN
|
|
| 14 | +#else
|
|
| 15 | +#include <stdlib.h>
|
|
| 16 | +#define USED_IF_ASAN __attribute__((unused))
|
|
| 17 | +#endif
|
|
| 18 | + |
|
| 19 | +static inline void
|
|
| 20 | +__ghc_asan_poison_memory_region(void const volatile *addr USED_IF_ASAN,
|
|
| 21 | + size_t size USED_IF_ASAN) {
|
|
| 22 | +#if defined(ASAN_ENABLED)
|
|
| 23 | + __asan_poison_memory_region(addr, size);
|
|
| 24 | +#endif
|
|
| 25 | +}
|
|
| 26 | + |
|
| 27 | +static inline void
|
|
| 28 | +__ghc_asan_unpoison_memory_region(void const volatile *addr USED_IF_ASAN,
|
|
| 29 | + size_t size USED_IF_ASAN) {
|
|
| 30 | +#if defined(ASAN_ENABLED)
|
|
| 31 | + __asan_unpoison_memory_region(addr, size);
|
|
| 32 | +#endif
|
|
| 33 | +} |
| ... | ... | @@ -97,6 +97,12 @@ flag ubsan |
| 97 | 97 | UndefinedBehaviorSanitizer.
|
| 98 | 98 | default: False
|
| 99 | 99 | manual: True
|
| 100 | +flag asan
|
|
| 101 | + description:
|
|
| 102 | + Link with -fsanitize=address, to be enabled when building with
|
|
| 103 | + AddressSanitizer.
|
|
| 104 | + default: False
|
|
| 105 | + manual: True
|
|
| 100 | 106 | flag shared-libsan
|
| 101 | 107 | description:
|
| 102 | 108 | Link with -shared-libsan, to guarantee only one copy of the
|
| ... | ... | @@ -205,6 +211,9 @@ library |
| 205 | 211 | if flag(ubsan)
|
| 206 | 212 | ld-options: -fsanitize=undefined
|
| 207 | 213 | |
| 214 | + if flag(asan)
|
|
| 215 | + ld-options: -fsanitize=address
|
|
| 216 | + |
|
| 208 | 217 | if flag(shared-libsan)
|
| 209 | 218 | ld-options: -shared-libsan
|
| 210 | 219 | |
| ... | ... | @@ -283,6 +292,7 @@ library |
| 283 | 292 | -- ^ generated
|
| 284 | 293 | rts/ghc_ffi.h
|
| 285 | 294 | rts/Adjustor.h
|
| 295 | + rts/ASANUtils.h
|
|
| 286 | 296 | rts/ExecPage.h
|
| 287 | 297 | rts/BlockSignals.h
|
| 288 | 298 | rts/Bytecodes.h
|
| ... | ... | @@ -261,6 +261,8 @@ initGroup(bdescr *head) |
| 261 | 261 | head[i].flags = 0;
|
| 262 | 262 | }
|
| 263 | 263 | #endif
|
| 264 | + |
|
| 265 | + __ghc_asan_unpoison_memory_region(head->start, (W_)head->blocks * BLOCK_SIZE);
|
|
| 264 | 266 | }
|
| 265 | 267 | |
| 266 | 268 | #if SIZEOF_VOID_P == SIZEOF_LONG
|
| ... | ... | @@ -474,6 +476,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks) |
| 474 | 476 | bd = alloc_mega_group_from_free_list(&deferred_free_mblock_list[node], n, &best);
|
| 475 | 477 | if(bd)
|
| 476 | 478 | {
|
| 479 | + __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
|
|
| 477 | 480 | return bd;
|
| 478 | 481 | }
|
| 479 | 482 | else if(!best)
|
| ... | ... | @@ -490,6 +493,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks) |
| 490 | 493 | |
| 491 | 494 | if (bd)
|
| 492 | 495 | {
|
| 496 | + __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
|
|
| 493 | 497 | return bd;
|
| 494 | 498 | }
|
| 495 | 499 | else if (best)
|
| ... | ... | @@ -500,6 +504,7 @@ alloc_mega_group (uint32_t node, StgWord mblocks) |
| 500 | 504 | (best_mblocks-mblocks)*MBLOCK_SIZE);
|
| 501 | 505 | |
| 502 | 506 | best->blocks = MBLOCK_GROUP_BLOCKS(best_mblocks - mblocks);
|
| 507 | + __ghc_asan_unpoison_memory_region(MBLOCK_ROUND_DOWN(bd), mblocks * MBLOCK_SIZE);
|
|
| 503 | 508 | initMBlock(MBLOCK_ROUND_DOWN(bd), node);
|
| 504 | 509 | }
|
| 505 | 510 | else
|
| ... | ... | @@ -880,6 +885,8 @@ free_mega_group (bdescr *mg) |
| 880 | 885 | |
| 881 | 886 | IF_DEBUG(sanity, checkFreeListSanity());
|
| 882 | 887 | }
|
| 888 | + |
|
| 889 | + __ghc_asan_poison_memory_region(mg->start, (W_)mg->blocks * BLOCK_SIZE);
|
|
| 883 | 890 | }
|
| 884 | 891 | |
| 885 | 892 | static void
|
| ... | ... | @@ -927,6 +934,8 @@ free_deferred_mega_groups (uint32_t node) |
| 927 | 934 | // coalesce forwards
|
| 928 | 935 | coalesce_mblocks(mg);
|
| 929 | 936 | |
| 937 | + __ghc_asan_poison_memory_region(mg->start, (W_)mg->blocks * BLOCK_SIZE);
|
|
| 938 | + |
|
| 930 | 939 | // initialize search for next round
|
| 931 | 940 | prev = mg;
|
| 932 | 941 | bd = prev->link;
|
| ... | ... | @@ -1050,6 +1059,8 @@ freeGroup(bdescr *p) |
| 1050 | 1059 | setup_tail(p);
|
| 1051 | 1060 | free_list_insert(node,p);
|
| 1052 | 1061 | |
| 1062 | + __ghc_asan_poison_memory_region(p->start, (W_)p->blocks * BLOCK_SIZE);
|
|
| 1063 | + |
|
| 1053 | 1064 | IF_DEBUG(sanity, checkFreeListSanity());
|
| 1054 | 1065 | }
|
| 1055 | 1066 |
| ... | ... | @@ -348,6 +348,7 @@ alloc_todo_block (gen_workspace *ws, uint32_t size) |
| 348 | 348 | } else {
|
| 349 | 349 | if (gct->free_blocks) {
|
| 350 | 350 | bd = gct->free_blocks;
|
| 351 | + __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
|
|
| 351 | 352 | gct->free_blocks = bd->link;
|
| 352 | 353 | } else {
|
| 353 | 354 | // We allocate in chunks of at most 16 blocks, use one
|
| ... | ... | @@ -357,6 +358,9 @@ alloc_todo_block (gen_workspace *ws, uint32_t size) |
| 357 | 358 | StgWord n_blocks = stg_min(chunk_size, 1 << (MBLOCK_SHIFT - BLOCK_SHIFT - 1));
|
| 358 | 359 | allocBlocks_sync(n_blocks, &bd);
|
| 359 | 360 | gct->free_blocks = bd->link;
|
| 361 | + for (bdescr *bd = gct->free_blocks; bd; bd = bd->link) {
|
|
| 362 | + __ghc_asan_poison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
|
|
| 363 | + }
|
|
| 360 | 364 | }
|
| 361 | 365 | }
|
| 362 | 366 | initBdescr(bd, ws->gen, ws->gen->to);
|
| ... | ... | @@ -641,6 +641,8 @@ getMBlocks(uint32_t n) |
| 641 | 641 | |
| 642 | 642 | ret = getCommittedMBlocks(n);
|
| 643 | 643 | |
| 644 | + __ghc_asan_unpoison_memory_region(ret, (W_)n * MBLOCK_SIZE);
|
|
| 645 | + |
|
| 644 | 646 | debugTrace(DEBUG_gc, "allocated %d megablock(s) at %p",n,ret);
|
| 645 | 647 | |
| 646 | 648 | mblocks_allocated += n;
|
| ... | ... | @@ -673,6 +675,8 @@ freeMBlocks(void *addr, uint32_t n) |
| 673 | 675 | |
| 674 | 676 | mblocks_allocated -= n;
|
| 675 | 677 | |
| 678 | + __ghc_asan_poison_memory_region(addr, (W_)n * MBLOCK_SIZE);
|
|
| 679 | + |
|
| 676 | 680 | decommitMBlocks(addr, n);
|
| 677 | 681 | }
|
| 678 | 682 |
| ... | ... | @@ -1242,6 +1242,10 @@ start_new_pinned_block(Capability *cap) |
| 1242 | 1242 | ACQUIRE_SM_LOCK;
|
| 1243 | 1243 | bd = allocNursery(cap->node, NULL, PINNED_EMPTY_SIZE);
|
| 1244 | 1244 | RELEASE_SM_LOCK;
|
| 1245 | + |
|
| 1246 | + for (bdescr *pbd = bd; pbd; pbd = pbd->link) {
|
|
| 1247 | + __ghc_asan_poison_memory_region(pbd->start, (W_)pbd->blocks * BLOCK_SIZE);
|
|
| 1248 | + }
|
|
| 1245 | 1249 | }
|
| 1246 | 1250 | |
| 1247 | 1251 | // Bump up the nursery pointer to avoid the pathological situation
|
| ... | ... | @@ -1267,6 +1271,7 @@ start_new_pinned_block(Capability *cap) |
| 1267 | 1271 | }
|
| 1268 | 1272 | |
| 1269 | 1273 | cap->pinned_object_empty = bd->link;
|
| 1274 | + __ghc_asan_unpoison_memory_region(bd->start, (W_)bd->blocks * BLOCK_SIZE);
|
|
| 1270 | 1275 | newNurseryBlock(bd);
|
| 1271 | 1276 | if (bd->link != NULL) {
|
| 1272 | 1277 | bd->link->u.back = cap->pinned_object_empty;
|
| ... | ... | @@ -197,6 +197,9 @@ class TestConfig: |
| 197 | 197 | # Are we running with UndefinedBehaviorSanitizer enabled?
|
| 198 | 198 | self.have_ubsan = False
|
| 199 | 199 | |
| 200 | + # Are we running with AddressSanitizer enabled?
|
|
| 201 | + self.have_asan = False
|
|
| 202 | + |
|
| 200 | 203 | # Do symbols use leading underscores?
|
| 201 | 204 | self.leading_underscore = False
|
| 202 | 205 |
| ... | ... | @@ -1118,6 +1118,9 @@ def have_thread_sanitizer( ) -> bool: |
| 1118 | 1118 | def have_ubsan( ) -> bool:
|
| 1119 | 1119 | return config.have_ubsan
|
| 1120 | 1120 | |
| 1121 | +def have_asan( ) -> bool:
|
|
| 1122 | + return config.have_asan
|
|
| 1123 | + |
|
| 1121 | 1124 | def gcc_as_cmmp() -> bool:
|
| 1122 | 1125 | return config.cmm_cpp_is_gcc
|
| 1123 | 1126 |
| ... | ... | @@ -192,6 +192,9 @@ test('rts_clearMemory', [ |
| 192 | 192 | extra_ways(['g1', 'nursery_chunks', 'nonmoving', 'compacting_gc', 'sanity']),
|
| 193 | 193 | # On windows, nonmoving way fails with bad exit code (2816)
|
| 194 | 194 | when(opsys('mingw32'), fragile(23091)),
|
| 195 | + # For simplicity, ASAN poisoning/unpoisoning logic is omitted
|
|
| 196 | + # from rts_clearMemory implementation
|
|
| 197 | + when(have_asan(), skip),
|
|
| 195 | 198 | req_c,
|
| 196 | 199 | pre_cmd('$MAKE -s --no-print-directory rts_clearMemory_setup') ],
|
| 197 | 200 | # Same hack as ffi023
|
| ... | ... | @@ -8,6 +8,8 @@ test('T18623', |
| 8 | 8 | # Recent versions of osx report an error when running `ulimit -v`
|
| 9 | 9 | when(opsys('darwin'), skip),
|
| 10 | 10 | when(arch('powerpc64le'), skip),
|
| 11 | + # ASan can't allocate shadow memory
|
|
| 12 | + when(have_asan(), skip),
|
|
| 11 | 13 | cmd_prefix('ulimit -v ' + str(8 * 1024 ** 2) + ' && '),
|
| 12 | 14 | ignore_stdout],
|
| 13 | 15 | run_command,
|
| ... | ... | @@ -105,6 +105,8 @@ def remove_parenthesis(s): |
| 105 | 105 | return re.sub(r'\s+\([^)]*\)', '', s)
|
| 106 | 106 | |
| 107 | 107 | test('outofmem', [ when(opsys('darwin'), skip),
|
| 108 | + # ASan shadow memory allocation blows up
|
|
| 109 | + when(have_asan(), skip),
|
|
| 108 | 110 | # this is believed to cause other processes to die
|
| 109 | 111 | # that happen concurrently while the outofmem test
|
| 110 | 112 | # runs in CI. As such we'll need to disable it on
|