Skip to content

Commit bcef02e

Browse files
Allow to run tests with the address sanitizer
Co-authored-by: Dmitrii Dolgov <9erthalion6@gmail.com>
1 parent 663c948 commit bcef02e

7 files changed

Lines changed: 54 additions & 32 deletions

File tree

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ pest_derive = "2.8.1"
3131
llvm-sys = "201.0.1"
3232
docopt = "1.1.1"
3333
signal-hook = "0.3.18"
34+
35+
[features]
36+
default = []
37+
nightly = []

Containerfile

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
FROM registry.fedoraproject.org/fedora:43 as builder
22

3+
ARG RUST_VERSION=stable
4+
35
RUN dnf install -y \
4-
rust \
5-
cargo \
6-
clippy \
7-
rustfmt \
86
# for stub \
97
nasm \
108
# for script jit \
@@ -15,7 +13,19 @@ RUN dnf install -y \
1513
# for bpf \
1614
clang \
1715
kernel-devel \
18-
libbpf-devel
16+
libbpf-devel && \
17+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
18+
sh -s -- -y --default-toolchain $RUST_VERSION --profile minimal
19+
20+
# $HOME is not evaluated here, any better way of getting the toolchain
21+
# directory?
22+
ENV PATH="${PATH}:/root/.cargo/bin"
23+
24+
RUN rustup component add rustfmt clippy
25+
26+
RUN if [ "${RUST_VERSION}" == "nightly" ]; then \
27+
rustup component add rust-src --toolchain nightly; \
28+
fi
1929

2030
ADD ./ /berserker/
2131

@@ -32,7 +42,12 @@ RUN cargo build -r
3242
# Test will require stub binary to be available
3343
ENV PATH="${PATH}:/berserker:/berserker/target/release"
3444

35-
RUN cargo test
45+
RUN if [ "${RUST_VERSION}" == "nightly" ]; then \
46+
TARGET=$(rustc --version --verbose | grep host | cut -d" " -f2) && \
47+
RUSTFLAGS="-Z sanitizer=address" cargo +nightly test -Z build-std --target "$TARGET"; \
48+
else \
49+
cargo test; \
50+
fi
3651

3752
FROM registry.fedoraproject.org/fedora:43
3853

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ endif
77
.PHONY: all
88
all:
99
docker build -t berserker -f Containerfile .
10+
docker build -t berserker -f Containerfile --build-arg=RUST_VERSION=nightly .
1011
docker build -t berserker-test -f Containerfile.test .
1112
docker run --privileged berserker-test
1213

src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![cfg_attr(feature = "nightly", feature(sanitize))]
2+
13
use core_affinity::CoreId;
24
use serde::{Deserialize, Deserializer};
35
use std::{collections::HashMap, fmt::Display, net::Ipv4Addr, str::FromStr};
@@ -28,7 +30,8 @@ pub struct WorkloadConfig {
2830
/// Custom workload configuration.
2931
pub workload: Workload,
3032

31-
/// For how long to run the worker. Default value is zero, meaning no limit.
33+
/// For how long to run the worker. Default value is zero, meaning no
34+
/// limit.
3235
#[serde(default = "default_duration")]
3336
pub duration: u64,
3437
}
@@ -194,8 +197,8 @@ pub enum Workload {
194197
/// Maximum number of dynamic connections
195198
connections_dyn_max: u32,
196199

197-
// How many connections to make to the same server address and port with
198-
// different client ports
200+
/// How many connections to make to the same server address and port
201+
/// with different client ports
199202
#[serde(default = "default_conns_per_addr")]
200203
conns_per_addr: u16,
201204

@@ -211,7 +214,8 @@ pub enum Workload {
211214
/// Whether or not to wait for a connection to be removed before adding
212215
/// a new one, when the dynamic connection limit is reached.
213216
/// if true: an old connection will be forcibly removed
214-
/// if false: wait for a connection to naturally age-off before adding a new one
217+
/// if false: wait for a connection to naturally age-off before adding
218+
/// a new one
215219
preempt: bool,
216220
},
217221

src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ fn main() {
204204
.required(false),
205205
)
206206
// Add in settings from the environment (with a prefix of APP)
207-
// Eg.. `BERSERKER__WORKLOAD__ARRIVAL_RATE=1` would set the `arrival_rate` key
207+
// Eg.. `BERSERKER__WORKLOAD__ARRIVAL_RATE=1` would set the
208+
// `arrival_rate` key
208209
.add_source(
209210
config::Environment::with_prefix("BERSERKER")
210211
.try_parsing(true)
@@ -230,7 +231,8 @@ fn main() {
230231
let elapsed = duration_timer.elapsed().unwrap().as_secs();
231232

232233
// Ignore processes without specified duration -- we don't want
233-
// neither terminate them, nor count against processes to compare.
234+
// neither terminate them, nor count against processes to
235+
// compare.
234236
let watched_processes = processes
235237
.iter()
236238
.filter(|(_, duration)| *duration > 0)

src/worker/script.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,13 @@ pub static RUNTIME: LazyLock<HashMap<String, RuntimeFunc>> =
210210
});
211211

212212
impl ScriptWorker {
213-
fn jit_instruction(name: String, arg: Arg, ctx: &BuildContext) {
213+
fn jit_instruction(name: &CStr, arg: Arg, ctx: &BuildContext) {
214214
let mut arg_ptr = Self::get_arg_value(arg, ctx);
215215

216-
let (func, func_type) = ctx.module_runtime.get(&name).unwrap();
216+
let (func, func_type) = ctx
217+
.module_runtime
218+
.get(name.to_str().expect("Couldn't convert name to string"))
219+
.unwrap();
217220

218221
unsafe {
219222
LLVMBuildCall2(
@@ -222,7 +225,7 @@ impl ScriptWorker {
222225
*func,
223226
&mut arg_ptr,
224227
1,
225-
name.as_str().as_ptr() as *const _,
228+
name.as_ptr() as *const _,
226229
);
227230
}
228231
}
@@ -320,7 +323,8 @@ impl ScriptWorker {
320323
&mut err,
321324
) != 0
322325
{
323-
// In case of error, we must avoid using the uninitialized ExecutionEngineRef.
326+
// In case of error, we must avoid using the uninitialized
327+
// ExecutionEngineRef.
324328
assert!(!err.is_null());
325329
panic!(
326330
"Failed to create execution engine: {:?}",
@@ -385,8 +389,8 @@ impl ScriptWorker {
385389
function_type,
386390
);
387391

388-
// Create a basic block in the function and set our builder to generate
389-
// code in it.
392+
// Create a basic block in the function and set our builder to
393+
// generate code in it.
390394
let bb = LLVMAppendBasicBlockInContext(
391395
context,
392396
function,
@@ -425,30 +429,22 @@ impl ScriptWorker {
425429
// JIT the instruction and collect it's name
426430
let name = match instr.clone() {
427431
Instruction::Task { name, args: _ } => {
428-
Self::jit_instruction(String::from("task"), name, &ctx);
432+
Self::jit_instruction(c"task", name, &ctx);
429433
"task"
430434
}
431435

432436
Instruction::Open { path } => {
433-
Self::jit_instruction(String::from("open"), path, &ctx);
437+
Self::jit_instruction(c"open", path, &ctx);
434438
"open"
435439
}
436440

437441
Instruction::Ping { server } => {
438-
Self::jit_instruction(
439-
String::from("ping"),
440-
server,
441-
&ctx,
442-
);
442+
Self::jit_instruction(c"ping", server, &ctx);
443443
"ping"
444444
}
445445

446446
Instruction::Debug { text } => {
447-
Self::jit_instruction(
448-
String::from("debug"),
449-
text,
450-
&ctx,
451-
);
447+
Self::jit_instruction(c"debug", text, &ctx);
452448
"debug"
453449
}
454450
};

src/worker/syscalls/ioctl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub struct IoctlCall {
1414

1515
impl IoctlCall {
1616
pub fn new(_: &ArgsMap) -> Self {
17-
// Zero initialize all fields, fd will be initialized in `Syscaller::init`.
18-
// All other fields can be overridden as needed
17+
// Zero initialize all fields, fd will be initialized in
18+
// `Syscaller::init`. All other fields can be overridden as needed
1919
Default::default()
2020
}
2121
}

0 commit comments

Comments
 (0)