Skip to content

Commit a74a4a2

Browse files
committed
build: Try to get ASan much greener, fix minor memory leaks
1 parent 07d08ad commit a74a4a2

38 files changed

Lines changed: 353 additions & 146 deletions

File tree

‎bin/ci-builder‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ fi
4747
cmd=$1 && shift
4848
flavor=$1 && shift
4949

50+
if [[ ${CI_SANITIZER:-none} != none && $flavor = stable ]]; then
51+
flavor=nightly
52+
fi
53+
5054
rust_date=
5155
case "$flavor" in
5256
min)

‎ci/builder/Dockerfile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ RUN apt-get update --fix-missing && TZ=UTC DEBIAN_FRONTEND=noninteractive apt-ge
141141
libc6-dbg \
142142
libclang-common-18-dev \
143143
libclang-dev \
144-
libclang-rt-18-dev \
144+
libclang-rt-19-dev \
145145
libpq-dev \
146146
libxml2 \
147147
lld \

‎ci/builder/sanshim/aarch64/c++‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,4 @@
1212
exec /usr/bin/clang++ -fsanitize="$CI_SANITIZER" \
1313
-fuse-ld=lld \
1414
--target=aarch64-unknown-linux-gnu \
15-
--gcc-toolchain=/opt/x-tools/aarch64-unknown-linux-gnu/ \
16-
--sysroot=/opt/x-tools/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot \
17-
-L/opt/x-tools/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot/lib \
1815
"$@"

‎ci/builder/sanshim/aarch64/cc‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,4 @@
1212
exec /usr/bin/clang -fsanitize="$CI_SANITIZER" \
1313
-fuse-ld=lld \
1414
--target=aarch64-unknown-linux-gnu \
15-
--gcc-toolchain=/opt/x-tools/aarch64-unknown-linux-gnu/ \
16-
--sysroot=/opt/x-tools/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot \
17-
-L/opt/x-tools/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot/lib \
1815
"$@"

‎ci/builder/sanshim/x86_64/c++‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,4 @@
1212
exec /usr/bin/clang++ -fsanitize="$CI_SANITIZER" \
1313
-fuse-ld=lld \
1414
--target=x86_64-unknown-linux-gnu \
15-
--gcc-toolchain=/opt/x-tools/x86_64-unknown-linux-gnu/ \
16-
--sysroot=/opt/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot \
17-
-L/opt/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot/lib \
1815
"$@"

‎ci/builder/sanshim/x86_64/cc‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,4 @@
1212
exec /usr/bin/clang -fsanitize="$CI_SANITIZER" \
1313
-fuse-ld=lld \
1414
--target=x86_64-unknown-linux-gnu \
15-
--gcc-toolchain=/opt/x-tools/x86_64-unknown-linux-gnu/ \
16-
--sysroot=/opt/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot \
17-
-L/opt/x-tools/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot/lib \
1815
"$@"

‎ci/mkpipeline.py‎

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,12 @@ def fetch_hashes() -> None:
381381
)
382382
truncate_skip_length(pipeline)
383383
handle_sanitizer_skip(pipeline, args.sanitizer)
384-
increase_agents_timeouts(pipeline, args.sanitizer, args.coverage)
385384
prioritize_pipeline(pipeline, args.priority)
386385
switch_jobs_to_aws(pipeline, args.priority)
386+
# After `switch_jobs_to_aws`, so that the queue a step ends up on is the one
387+
# that gets sized up. The other order lets the aarch64 to x86_64 fallback
388+
# land on a smaller machine than the size-up asked for.
389+
increase_agents_timeouts(pipeline, args.sanitizer, args.coverage)
387390
permit_rerunning_successful_steps(pipeline)
388391
set_retry_on_agent_lost(pipeline)
389392
set_default_agents_queue(pipeline)
@@ -496,56 +499,55 @@ def handle_sanitizer_skip(pipeline: Any, sanitizer: Sanitizer) -> None:
496499
step["skip"] = True
497500

498501

502+
# The next size up for each agent queue, used when a run needs more machine
503+
# than the pipeline asks for.
504+
NEXT_LARGER_AGENT = {
505+
"linux-aarch64-small": "linux-aarch64",
506+
"linux-aarch64": "linux-aarch64-medium",
507+
"linux-aarch64-medium": "linux-aarch64-large",
508+
"linux-aarch64-large": "builder-linux-aarch64-mem",
509+
"linux-x86_64-small": "linux-x86_64",
510+
"linux-x86_64": "linux-x86_64-medium",
511+
"linux-x86_64-medium": "linux-x86_64-large",
512+
"linux-x86_64-large": "builder-linux-x86_64",
513+
"hetzner-aarch64-2cpu-4gb": "hetzner-aarch64-4cpu-8gb",
514+
"hetzner-aarch64-4cpu-8gb": "hetzner-aarch64-8cpu-16gb",
515+
"hetzner-aarch64-8cpu-16gb": "hetzner-aarch64-16cpu-32gb",
516+
"hetzner-x86-64-2cpu-4gb": "hetzner-x86-64-4cpu-8gb",
517+
"hetzner-x86-64-4cpu-8gb": "hetzner-x86-64-8cpu-16gb",
518+
"hetzner-x86-64-8cpu-16gb": "hetzner-x86-64-16cpu-32gb",
519+
"hetzner-x86-64-12cpu-24gb": "hetzner-x86-64-dedi-16cpu-64gb",
520+
"hetzner-x86-64-16cpu-32gb": "hetzner-x86-64-dedi-16cpu-64gb",
521+
"hetzner-x86-64-16cpu-64gb": "hetzner-x86-64-dedi-32cpu-128gb",
522+
"hetzner-x86-64-dedi-8cpu-32gb": "hetzner-x86-64-dedi-16cpu-64gb",
523+
"hetzner-x86-64-dedi-16cpu-64gb": "hetzner-x86-64-dedi-32cpu-128gb",
524+
"hetzner-x86-64-dedi-32cpu-128gb": "hetzner-x86-64-dedi-48cpu-192gb",
525+
}
526+
527+
499528
def increase_agents_timeouts(
500529
pipeline: Any, sanitizer: Sanitizer, coverage: bool
501530
) -> None:
502-
if sanitizer != Sanitizer.none or os.getenv("CI_SYSTEM_PARAMETERS", "") == "random":
531+
# Most sanitizer runs, as well as random permutations of system parameters,
532+
# are slower and need more memory. The default system parameters in CI are
533+
# chosen to be efficient for execution, while a random permutation might
534+
# take way longer and use more memory.
535+
if sanitizer != Sanitizer.none:
536+
sizes_up = 2
537+
elif os.getenv("CI_SYSTEM_PARAMETERS", "") == "random":
538+
sizes_up = 1
539+
else:
540+
sizes_up = 0
541+
542+
if sizes_up:
503543
for step in steps(pipeline):
504-
# Most sanitizer runs, as well as random permutations of system
505-
# parameters, are slower and need more memory. The default system
506-
# parameters in CI are chosen to be efficient for execution, while
507-
# a random permutation might take way longer and use more memory.
508544
if "timeout_in_minutes" in step:
509545
step["timeout_in_minutes"] *= 10
510546

511547
if "agents" in step:
512548
agent = step["agents"].get("queue", None)
513-
if agent == "linux-aarch64-small":
514-
agent = "linux-aarch64"
515-
elif agent == "linux-aarch64":
516-
agent = "linux-aarch64-medium"
517-
elif agent == "linux-aarch64-medium":
518-
agent = "linux-aarch64-large"
519-
elif agent == "linux-aarch64-large":
520-
agent = "builder-linux-aarch64-mem"
521-
elif agent == "linux-x86_64-small":
522-
agent = "linux-x86_64"
523-
elif agent == "linux-x86_64":
524-
agent = "linux-x86_64-medium"
525-
elif agent == "linux-x86_64-medium":
526-
agent = "linux-x86_64-large"
527-
elif agent == "linux-x86_64-large":
528-
agent = "builder-linux-x86_64"
529-
elif agent == "hetzner-aarch64-2cpu-4gb":
530-
agent = "hetzner-aarch64-4cpu-8gb"
531-
elif agent == "hetzner-aarch64-4cpu-8gb":
532-
agent = "hetzner-aarch64-8cpu-16gb"
533-
elif agent == "hetzner-aarch64-8cpu-16gb":
534-
agent = "hetzner-aarch64-16cpu-32gb"
535-
elif agent == "hetzner-x86-64-2cpu-4gb":
536-
agent = "hetzner-x86-64-4cpu-8gb"
537-
elif agent == "hetzner-x86-64-4cpu-8gb":
538-
agent = "hetzner-x86-64-8cpu-16gb"
539-
elif agent == "hetzner-x86-64-8cpu-16gb":
540-
agent = "hetzner-x86-64-16cpu-32gb"
541-
elif agent == "hetzner-x86-64-12cpu-24gb":
542-
agent = "hetzner-x86-64-dedi-16cpu-64gb"
543-
elif agent == "hetzner-x86-64-16cpu-32gb":
544-
agent = "hetzner-x86-64-dedi-16cpu-64gb"
545-
elif agent == "hetzner-x86-64-16cpu-64gb":
546-
agent = "hetzner-x86-64-dedi-32cpu-128gb"
547-
elif agent == "hetzner-x86-64-dedi-32cpu-128gb":
548-
agent = "hetzner-x86-64-dedi-48cpu-192gb"
549+
for _ in range(sizes_up):
550+
agent = NEXT_LARGER_AGENT.get(agent, agent)
549551
step["agents"] = {"queue": agent}
550552

551553
if coverage:

‎ci/nightly/pipeline.template.yml‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ steps:
3636

3737
- id: build-x86_64-asan
3838
label: ":rust: Build x86_64 (ASan)"
39-
command: bin/ci-builder run min bin/pyactivate -m ci.test.build
39+
command: bin/ci-builder run nightly bin/pyactivate -m ci.test.build
4040
inputs:
4141
- "*"
4242
depends_on: []
@@ -45,14 +45,12 @@ steps:
4545
queue: builder-linux-x86_64
4646
env:
4747
CI_SANITIZER: address
48-
4948
sanitizer: skip
5049
branches: "main"
51-
skip: "currently broken"
5250

5351
- id: build-aarch64-asan
5452
label: ":rust: Build aarch64 (ASan)"
55-
command: bin/ci-builder run min bin/pyactivate -m ci.test.build
53+
command: bin/ci-builder run nightly bin/pyactivate -m ci.test.build
5654
inputs:
5755
- "*"
5856
depends_on: []
@@ -63,7 +61,6 @@ steps:
6361
CI_SANITIZER: address
6462
sanitizer: skip
6563
branches: "main"
66-
skip: "currently broken"
6764

6865
- id: build-rust-latest-beta
6966
label: "Build with Latest Rust Beta"
@@ -179,6 +176,7 @@ steps:
179176
- id: feature-benchmark
180177
topics: [cockroach, copy-to-s3, iceberg, kafka, kafka-sink, mysql, postgres, sql-server]
181178
label: "Feature benchmark against merge base or 'latest'"
179+
sanitizer: skip
182180
depends_on: build-x86_64
183181
timeout_in_minutes: 120
184182
parallelism: 12
@@ -194,6 +192,7 @@ steps:
194192
- id: scalability-benchmark-dml-dql
195193
topics: [postgres]
196194
label: "Scalability benchmark (read & write) against merge base or 'latest'"
195+
sanitizer: skip
197196
depends_on: build-x86_64
198197
timeout_in_minutes: 120
199198
env:
@@ -220,6 +219,7 @@ steps:
220219
- id: scalability-benchmark-ddl
221220
topics: [postgres]
222221
label: "Scalability benchmark (DDL) against merge base or 'latest'"
222+
sanitizer: skip
223223
depends_on: build-x86_64
224224
timeout_in_minutes: 120
225225
env:
@@ -249,6 +249,7 @@ steps:
249249
- id: scalability-benchmark-connection
250250
topics: [postgres]
251251
label: "Scalability benchmark (connection) against merge base or 'latest'"
252+
sanitizer: skip
252253
depends_on: build-x86_64
253254
timeout_in_minutes: 120
254255
parallelism: 2
@@ -277,6 +278,7 @@ steps:
277278
- id: parallel-benchmark
278279
topics: [cockroach, kafka, mysql, postgres]
279280
label: "Parallel Benchmark"
281+
sanitizer: skip
280282
depends_on: build-x86_64
281283
timeout_in_minutes: 120
282284
parallelism: 5
@@ -296,6 +298,7 @@ steps:
296298
- id: workload-replay
297299
topics: [iceberg, kafka, mysql, postgres, sql-server, ssh-tunnel]
298300
label: "Workload Replay (1% initial data)"
301+
sanitizer: skip
299302
depends_on: build-x86_64
300303
timeout_in_minutes: 120
301304
parallelism: 5
@@ -314,6 +317,7 @@ steps:
314317
- id: console-scalability
315318
topics: [iceberg, kafka, mysql, postgres, sql-server, ssh-tunnel]
316319
label: "Console scalability (workload replay)"
320+
sanitizer: skip
317321
depends_on: build-x86_64
318322
timeout_in_minutes: 120
319323
parallelism: 3
@@ -389,6 +393,7 @@ steps:
389393
- id: testdrive-replicas-4
390394
topics: [copy-to-s3, kafka, kafka-sink, mysql, postgres]
391395
label: ":racing_car: testdrive 4 replicas"
396+
sanitizer: skip
392397
depends_on: build-aarch64
393398
timeout_in_minutes: 60
394399
parallelism: 2
@@ -415,6 +420,7 @@ steps:
415420
- id: testdrive-size-8
416421
topics: [copy-to-s3, kafka, kafka-sink, mysql, postgres]
417422
label: ":racing_car: testdrive with SIZE 8"
423+
sanitizer: skip
418424
depends_on: build-aarch64
419425
timeout_in_minutes: 60
420426
parallelism: 2
@@ -456,6 +462,7 @@ steps:
456462
- id: azurite-testdrive-size-8
457463
topics: [azurite, copy-to-s3, kafka, kafka-sink, mysql, postgres]
458464
label: ":racing_car: testdrive with SIZE 8 and :azure: blob store"
465+
sanitizer: skip
459466
depends_on: build-aarch64
460467
timeout_in_minutes: 60
461468
parallelism: 2
@@ -529,6 +536,7 @@ steps:
529536
- id: bounded-memory
530537
topics: [copy-to-s3, iceberg, kafka, mysql, postgres]
531538
label: "Bounded Memory"
539+
sanitizer: skip
532540
depends_on: build-aarch64
533541
timeout_in_minutes: 60
534542
parallelism: 2
@@ -540,6 +548,7 @@ steps:
540548
- id: bounded-memory-search
541549
topics: [copy-to-s3, iceberg, kafka, mysql, postgres]
542550
label: "Bounded Memory Search (materialized only)"
551+
sanitizer: skip
543552
depends_on: build-aarch64
544553
timeout_in_minutes: 60
545554
parallelism: 8

‎ci/test/cargo-test/mzcompose.py‎

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,6 @@
8686
]
8787

8888

89-
def flatten(xss):
90-
return [x for xs in xss for x in xs]
91-
92-
9389
def pull_image(image: str) -> None:
9490
# Check if image exists locally before pulling
9591
image_exists = subprocess.run(
@@ -280,12 +276,9 @@ def run_sanitizer(
280276
):
281277
cflags = [
282278
f"--target={target(Arch.host())}",
283-
f"--gcc-toolchain=/opt/x-tools/{target(Arch.host())}/",
284-
f"--sysroot=/opt/x-tools/{target(Arch.host())}/{target(Arch.host())}/sysroot",
285279
] + rustc_flags.sanitizer_cflags[sanitizer]
286280
ldflags = cflags + [
287281
"-fuse-ld=lld",
288-
f"-L/opt/x-tools/{target(Arch.host())}/{target(Arch.host())}/lib64",
289282
]
290283
extra_env = {
291284
"CFLAGS": " ".join(cflags),
@@ -294,21 +287,26 @@ def run_sanitizer(
294287
"CXXSTDLIB": "stdc++",
295288
"CC": "cc",
296289
"CXX": "c++",
297-
"CPP": "clang-cpp-18",
290+
"CPP": "clang-cpp-19",
298291
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER": "cc",
299292
"CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER": "cc",
300-
"PATH": f"/sanshim:/opt/x-tools/{target(Arch.host())}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
293+
"PATH": "/sanshim:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
301294
"RUSTFLAGS": (
302295
env.get("RUSTFLAGS", "") + " " + " ".join(rustc_flags.sanitizer[sanitizer])
303296
),
304297
"TSAN_OPTIONS": "report_bugs=0", # build-scripts fail
305298
}
299+
# `bin/ci-builder run` forwards only an allowlist of host variables, so the
300+
# sanitizer environment has to be set inside the container. `env` also
301+
# resolves `cargo` through the `PATH` it just set, which is what puts the
302+
# `/sanshim` compiler wrappers ahead of the real ones.
303+
env_prefix = ["env", *(f"{key}={val}" for key, val in extra_env.items())]
306304
spawn.runv(
307305
[
308306
"bin/ci-builder",
309307
"run",
310308
"nightly",
311-
*flatten([["--env", f"{key}={val}"] for key, val in extra_env.items()]),
309+
*env_prefix,
312310
"cargo",
313311
"build",
314312
"--workspace",
@@ -330,9 +328,7 @@ def run_sanitizer(
330328
"bin/ci-builder",
331329
"run",
332330
"nightly",
333-
*flatten(
334-
[["--env", f"{key}={val}"] for key, val in extra_env.items()]
335-
),
331+
*env_prefix,
336332
"cargo",
337333
"nextest",
338334
"run",

‎ci/test/dev_tag.py‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212
import os
1313
from pathlib import Path
1414

15-
from materialize import ci_util, git, mzbuild
15+
from materialize import ci_util, mzbuild
1616
from materialize.rustc_flags import Sanitizer
1717
from materialize.xcompile import Arch
1818

1919

2020
def main() -> None:
21-
mz_version = ci_util.get_mz_version()
2221
sanitizer = Sanitizer[os.getenv("CI_SANITIZER", "none")]
2322

2423
repos = [
@@ -42,12 +41,7 @@ def main() -> None:
4241
repo.resolve_dependencies(image for image in repo if image.publish)
4342
for repo in repos
4443
]
45-
# Ideally we'd use SemVer metadata (e.g., `v1.0.0+metadata`), but `+` is not
46-
# a valid character in Docker tags, so we use `--` instead.
47-
suffix = "pr" if sanitizer == Sanitizer.none else f"pr-{sanitizer}"
48-
mzbuild.publish_multiarch_images(
49-
f'v{mz_version}--{suffix}.g{git.rev_parse("HEAD")}', deps
50-
)
44+
mzbuild.publish_multiarch_images(ci_util.dev_docker_tag(), deps)
5145

5246

5347
if __name__ == "__main__":

0 commit comments

Comments
 (0)