Created
December 20, 2022 04:07
-
-
Save ocadaruma/24d305b739c55b7c04dd711972a8e965 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "sighandler-study" | |
version = "0.1.0" | |
edition = "2021" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[dependencies] | |
signal-hook = "0.3.14" | |
libc = "0.2.126" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use libc::pid_t; | |
use std::fs::OpenOptions; | |
use std::io::Write; | |
use std::os::unix::fs::OpenOptionsExt; | |
use std::sync::mpsc::channel; | |
use std::time::{Duration, SystemTime}; | |
use std::{process, thread, time}; | |
const SYS_TGKILL: i64 = 234; | |
const SYS_GETTID: i64 = 186; | |
fn main() { | |
let args: Vec<String> = std::env::args().collect(); | |
let path = args[1].clone(); | |
unsafe { | |
signal_hook::low_level::register(signal_hook::consts::SIGVTALRM, || { | |
println!("{}: SIGVTALRM called. tid={}", unix_millis(), gettid()); | |
}) | |
.unwrap(); | |
} | |
let (tx_tid1, rx_tid1) = channel(); | |
let (tx_tid2, rx_tid2) = channel(); | |
let handle1 = thread::spawn(move || { | |
let mut file = OpenOptions::new() | |
.append(true) | |
.create(true) | |
.custom_flags(libc::O_SYNC) | |
.open(path) | |
.unwrap(); | |
let mut buf = [0u8; 64]; | |
tx_tid1.send(gettid()).unwrap(); | |
file.write(&buf).unwrap(); | |
thread::sleep(Duration::from_millis(2000)); | |
}); | |
let handle2 = thread::spawn(move || { | |
tx_tid2.send(gettid()).unwrap(); | |
thread::sleep(Duration::from_millis(2000)); | |
}); | |
let tid1 = rx_tid1.recv().unwrap(); | |
let tid2 = rx_tid2.recv().unwrap(); | |
println!("tid1={}, tid2={}", tid1, tid2); | |
// sleep for a bit to expect syscall starts | |
thread::sleep(Duration::from_millis(100)); | |
println!("{}: gonna send signals", unix_millis()); | |
unsafe { | |
libc::syscall( | |
SYS_TGKILL, | |
process::id(), | |
tid1, | |
signal_hook::consts::SIGVTALRM, | |
); | |
libc::syscall( | |
SYS_TGKILL, | |
process::id(), | |
tid2, | |
signal_hook::consts::SIGVTALRM, | |
); | |
} | |
handle1.join().unwrap(); | |
handle2.join().unwrap(); | |
} | |
fn unix_millis() -> u64 { | |
SystemTime::now() | |
.duration_since(time::UNIX_EPOCH) | |
.unwrap() | |
.as_millis() as u64 | |
} | |
fn gettid() -> pid_t { | |
unsafe { libc::syscall(SYS_GETTID) as pid_t } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Inject write delay into the device to simulate slow disk | |
$ echo 3000 | sudo tee /sys/fs/ddi/8\:17/write_delay | |
$ ./sighandler-study-bin /path/to/test.bin | |
file path: /path/to/test.bin | |
tid1=1693, tid2=1694 | |
1658217824684: gonna send signals | |
1658217824684: SIGVTALRM called. tid=1694 | |
1658217832317: SIGVTALRM called. tid=1693 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment