Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions .github/workflows/sanitizers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
name: Sanitizers

on:
push:
branches: [master]
paths-ignore:
- "**.md"
- "docs/**"
- "LICENSE*"
- ".gitignore"
pull_request:
branches: [master]
paths-ignore:
- "**.md"
- "docs/**"
- "LICENSE*"
- ".gitignore"
workflow_dispatch:

jobs:
asan:
name: AddressSanitizer (macOS)
runs-on: macOS-latest
steps:
- uses: actions/checkout@v5

- name: Install dependencies
run: brew install llvm

- name: Install nightly Rust with rust-src
uses: dtolnay/rust-toolchain@nightly
with:
components: rust-src

- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
key: asan-macos

- name: Run tests with AddressSanitizer
env:
RUSTFLAGS: -Zsanitizer=address
RUSTDOCFLAGS: -Zsanitizer=address
run: |
cargo +nightly test \
-Zbuild-std \
--target aarch64-apple-darwin \
--lib \
--verbose

- name: Upload ASAN logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: asan-logs-macos
path: |
asan.log.*
/tmp/asan.*
if-no-files-found: ignore

tsan:
name: ThreadSanitizer (macOS)
runs-on: macOS-latest
steps:
- uses: actions/checkout@v5

- name: Install dependencies
run: brew install llvm

- name: Install nightly Rust with rust-src
uses: dtolnay/rust-toolchain@nightly
with:
components: rust-src

- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
key: tsan-macos

- name: Run tests with ThreadSanitizer
env:
RUSTFLAGS: -Zsanitizer=thread
RUSTDOCFLAGS: -Zsanitizer=thread
TSAN_OPTIONS: second_deadlock_stack=1
run: |
cargo +nightly test \
-Zbuild-std \
--target aarch64-apple-darwin \
--lib \
--verbose

- name: Upload TSAN logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: tsan-logs-macos
path: |
tsan.log.*
/tmp/tsan.*
if-no-files-found: ignore

asan-linux:
name: AddressSanitizer (Linux)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Cache Linux audio packages
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libasound2-dev libjack-jackd2-dev libjack-jackd2-0 libdbus-1-dev

- name: Install nightly Rust with rust-src
uses: dtolnay/rust-toolchain@nightly
with:
components: rust-src

- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
key: asan-linux

- name: Run tests with AddressSanitizer
env:
RUSTFLAGS: -Zsanitizer=address
RUSTDOCFLAGS: -Zsanitizer=address
run: |
cargo +nightly test \
-Zbuild-std \
--target x86_64-unknown-linux-gnu \
--lib \
--verbose

- name: Upload ASAN logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: asan-logs-linux
path: |
asan.log.*
/tmp/asan.*
if-no-files-found: ignore

tsan-linux:
name: ThreadSanitizer (Linux)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Cache Linux audio packages
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libasound2-dev libjack-jackd2-dev libjack-jackd2-0 libdbus-1-dev

- name: Install nightly Rust with rust-src
uses: dtolnay/rust-toolchain@nightly
with:
components: rust-src

- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
key: tsan-linux

- name: Run tests with ThreadSanitizer
env:
RUSTFLAGS: -Zsanitizer=thread
RUSTDOCFLAGS: -Zsanitizer=thread
TSAN_OPTIONS: second_deadlock_stack=1
run: |
cargo +nightly test \
-Zbuild-std \
--target x86_64-unknown-linux-gnu \
--lib \
--verbose

- name: Upload TSAN logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: tsan-logs-linux
path: |
tsan.log.*
/tmp/tsan.*
if-no-files-found: ignore
34 changes: 17 additions & 17 deletions src/host/coreaudio/macos/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ fn set_sample_rate(
mElement: kAudioObjectPropertyElementMaster,
};
let mut sample_rate: f64 = 0.0;
let data_size = mem::size_of::<f64>() as u32;
let mut data_size = mem::size_of::<f64>() as u32;
let status = unsafe {
AudioObjectGetPropertyData(
audio_device_id,
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::from(&mut sample_rate).cast(),
)
};
Expand All @@ -78,14 +78,14 @@ fn set_sample_rate(
if sample_rate as u32 != target_sample_rate.0 {
// Get available sample rate ranges.
property_address.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
let data_size = 0u32;
let mut data_size = 0u32;
let status = unsafe {
AudioObjectGetPropertyDataSize(
audio_device_id,
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
)
};
coreaudio::Error::from_os_status(status)?;
Expand All @@ -98,7 +98,7 @@ fn set_sample_rate(
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::new(ranges.as_mut_ptr()).unwrap().cast(),
)
};
Expand All @@ -125,15 +125,15 @@ fn set_sample_rate(
// Send sample rate updates back on a channel.
let sample_rate_handler = move || {
let mut rate: f64 = 0.0;
let data_size = mem::size_of::<f64>() as u32;
let mut data_size = mem::size_of::<f64>() as u32;

let result = unsafe {
AudioObjectGetPropertyData(
audio_device_id,
NonNull::from(&sample_rate_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::from(&mut rate).cast(),
)
};
Expand Down Expand Up @@ -373,7 +373,7 @@ impl Device {

// CFString is copied from the audio object, use wrap_under_create_rule
let mut uid: *mut CFString = std::ptr::null_mut();
let data_size = size_of::<*mut CFString>() as u32;
let mut data_size = size_of::<*mut CFString>() as u32;

// SAFETY: AudioObjectGetPropertyData is documented to write a CFString pointer
// for kAudioDevicePropertyDeviceUID. We check the status code before use.
Expand All @@ -383,7 +383,7 @@ impl Device {
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::from(&mut uid).cast(),
)
};
Expand Down Expand Up @@ -417,13 +417,13 @@ impl Device {

unsafe {
// Retrieve the devices audio buffer list.
let data_size = 0u32;
let mut data_size = 0u32;
let status = AudioObjectGetPropertyDataSize(
self.audio_device_id,
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
);
check_os_status(status)?;

Expand All @@ -434,7 +434,7 @@ impl Device {
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::new(audio_buffer_list.as_mut_ptr()).unwrap().cast(),
);
check_os_status(status)?;
Expand Down Expand Up @@ -468,13 +468,13 @@ impl Device {
// See https://github.com/thestk/rtaudio/blob/master/RtAudio.cpp#L1369C1-L1375C39

property_address.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
let data_size = 0u32;
let mut data_size = 0u32;
let status = AudioObjectGetPropertyDataSize(
self.audio_device_id,
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
);
check_os_status(status)?;

Expand All @@ -486,7 +486,7 @@ impl Device {
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::new(ranges.as_mut_ptr()).unwrap().cast(),
);
check_os_status(status)?;
Expand Down Expand Up @@ -595,13 +595,13 @@ impl Device {

unsafe {
let mut asbd: AudioStreamBasicDescription = mem::zeroed();
let data_size = mem::size_of::<AudioStreamBasicDescription>() as u32;
let mut data_size = mem::size_of::<AudioStreamBasicDescription>() as u32;
let status = AudioObjectGetPropertyData(
self.audio_device_id,
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::from(&mut asbd).cast(),
);
default_config_error_from_os_status(status)?;
Expand Down
6 changes: 3 additions & 3 deletions src/host/coreaudio/macos/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ unsafe fn audio_devices() -> Result<Vec<AudioDeviceID>, OSStatus> {
};
}

let data_size = 0u32;
let mut data_size = 0u32;
let status = AudioObjectGetPropertyDataSize(
kAudioObjectSystemObject as AudioObjectID,
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
);
try_status_or_return!(status);

Expand All @@ -45,7 +45,7 @@ unsafe fn audio_devices() -> Result<Vec<AudioDeviceID>, OSStatus> {
NonNull::from(&property_address),
0,
null(),
NonNull::from(&data_size),
NonNull::from(&mut data_size),
NonNull::new(audio_devices.as_mut_ptr()).unwrap().cast(),
);
try_status_or_return!(status);
Expand Down
Loading