Skip to content

Commit 88aa15a

Browse files
authored
add windows crash_dump support & sys split (#713)
* add windows crash_dump support & sys split * fix: replace WRITE_PIPE_FD with HIGH_PRIORIT_FD in unix get_high_writer
1 parent 49c5a1a commit 88aa15a

File tree

6 files changed

+273
-92
lines changed

6 files changed

+273
-92
lines changed

plugins/lib/rust/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.vscode/
2+
dev.sh
3+
target/

plugins/lib/rust/Cargo.toml

+18-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "plugins"
33
version = "0.1.0"
44
authors = ["zhanglei.sec <zhanglei.sec@bytedance.com>"]
5-
edition = "2018"
5+
edition = "2021"
66

77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88
[features]
@@ -23,9 +23,24 @@ serde_json = "1"
2323
protobuf-codegen-pure = "2.3"
2424

2525
[dependencies.windows]
26-
version = "0.48.0"
26+
version = "0.58.0"
2727
features = [
28-
"Win32_System_Diagnostics_ToolHelp",
2928
"Win32_Foundation",
29+
"Win32_Security",
30+
"Win32_Storage_FileSystem",
3031
"Win32_System_Console",
32+
"Win32_System_Services",
33+
"Win32_System_Kernel",
34+
"Win32_System_JobObjects",
35+
"Win32_System_Memory",
36+
"Win32_System_Threading",
37+
"Win32_System_Diagnostics",
38+
"Win32_System_Diagnostics_ToolHelp",
39+
"Win32_System_Diagnostics_Debug_Extensions",
3140
]
41+
42+
43+
# Library dependencies (Windows)
44+
[target.'cfg(target_os = "windows")'.dependencies]
45+
anyhow = "1.0"
46+
zip = "2.2"

plugins/lib/rust/src/lib.rs

+25-89
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
pub mod bridge;
2-
pub mod logger;
3-
4-
pub use bridge::*;
5-
use crossbeam::channel::{select, tick};
6-
use log::{debug, info};
7-
use parking_lot::Mutex;
8-
use protobuf::Message;
9-
use signal_hook::consts::SIGTERM;
101
use std::{
112
env,
123
fs::File,
@@ -16,15 +7,17 @@ use std::{
167
time::Duration,
178
};
189

19-
#[cfg(target_family = "unix")]
20-
use signal_hook::{consts::SIGUSR1, iterator::Signals};
21-
#[cfg(target_family = "unix")]
22-
use std::os::unix::prelude::FromRawFd;
10+
use crossbeam::channel::{select, tick};
11+
use log::debug;
12+
use parking_lot::Mutex;
13+
use protobuf::Message;
14+
15+
pub mod logger;
2316

24-
#[cfg(target_family = "windows")]
25-
use std::os::windows::prelude::{FromRawHandle, RawHandle};
26-
#[cfg(target_family = "windows")]
27-
use windows::Win32::System::Console::{GetStdHandle, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
17+
pub mod bridge;
18+
pub use bridge::*;
19+
20+
pub mod sys;
2821

2922
#[derive(Clone)]
3023
pub enum EncodeType {
@@ -37,62 +30,26 @@ pub struct Client {
3730
writer: Arc<Mutex<BufWriter<File>>>,
3831
reader: Arc<Mutex<BufReader<File>>>,
3932
}
40-
#[cfg(feature = "debug")]
41-
const READ_PIPE_FD: i32 = 0;
42-
#[cfg(not(feature = "debug"))]
43-
const READ_PIPE_FD: i32 = 3;
44-
#[cfg(feature = "debug")]
45-
const WRITE_PIPE_FD: i32 = 1;
46-
#[cfg(not(feature = "debug"))]
47-
const WRITE_PIPE_FD: i32 = 4;
48-
const HIGH_PRIORIT_FD: i32 = 5;
4933

5034
impl Client {
51-
5235
pub fn can_use_high() -> bool {
5336
match env::var("ELKEID_PLUGIN_HIGH_PRIORITY_PIPE") {
5437
Ok(value) => {
5538
if !value.is_empty() {
5639
return true;
5740
}
58-
5941
}
6042
Err(_) => {
6143
return false;
6244
}
63-
6445
}
6546
false
6647
}
6748
pub fn new(ignore_terminate: bool) -> Self {
68-
69-
let writer = Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
70-
#[cfg(target_family = "unix")]
71-
{
72-
File::from_raw_fd(WRITE_PIPE_FD)
73-
}
74-
75-
#[cfg(target_family = "windows")]
76-
{
77-
let raw_handle = GetStdHandle(STD_OUTPUT_HANDLE).unwrap();
78-
File::from_raw_handle(raw_handle.0 as _)
79-
}
80-
})));
49+
let writer = sys::get_writer();
8150
let mut high_writer = writer.clone();
82-
if Self::can_use_high() {
83-
high_writer = Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
84-
#[cfg(target_family = "unix")]
85-
{
86-
File::from_raw_fd(HIGH_PRIORIT_FD)
87-
}
88-
89-
#[cfg(target_family = "windows")]
90-
{
91-
let raw_handle = GetStdHandle(STD_OUTPUT_HANDLE).unwrap();
92-
File::from_raw_handle(raw_handle.0 as _)
93-
}
94-
})));
95-
51+
if Self::can_use_high() {
52+
high_writer = sys::get_high_writer();
9653
let high_writer_c = high_writer.clone();
9754
thread::spawn(move || {
9855
let ticker = tick(Duration::from_millis(200));
@@ -109,19 +66,8 @@ impl Client {
10966
});
11067
}
11168

112-
let reader = Arc::new(Mutex::new(BufReader::new(unsafe {
113-
#[cfg(target_family = "unix")]
114-
{
115-
File::from_raw_fd(READ_PIPE_FD)
116-
}
69+
let reader = sys::get_reader();
11770

118-
#[cfg(target_family = "windows")]
119-
{
120-
let raw_handle = GetStdHandle(STD_INPUT_HANDLE).unwrap();
121-
File::from_raw_handle(raw_handle.0 as _)
122-
}
123-
})));
124-
12571
let writer_c = writer.clone();
12672
thread::spawn(move || {
12773
let ticker = tick(Duration::from_millis(200));
@@ -136,26 +82,18 @@ impl Client {
13682
}
13783
}
13884
});
139-
#[cfg(target_family = "unix")]
85+
86+
sys::regist_exception_handler();
87+
14088
if ignore_terminate {
141-
let mut signals = Signals::new(&[SIGTERM, SIGUSR1]).unwrap();
142-
thread::spawn(move || {
143-
for sig in signals.forever() {
144-
if sig == SIGTERM {
145-
info!("received signal: {:?}, wait 3 secs to exit", sig);
146-
thread::sleep(Duration::from_secs(3));
147-
unsafe {
148-
if Self::can_use_high() {
149-
libc::close(HIGH_PRIORIT_FD);
150-
}
151-
libc::close(WRITE_PIPE_FD);
152-
libc::close(READ_PIPE_FD);
153-
}
154-
}
155-
}
156-
});
89+
sys::ignore_terminate()
90+
}
91+
92+
Self {
93+
high_writer,
94+
writer,
95+
reader,
15796
}
158-
Self { high_writer, writer, reader }
15997
}
16098
pub fn send_record(&mut self, rec: &Record) -> Result<(), Error> {
16199
let mut w = self.writer.lock();
@@ -176,7 +114,6 @@ impl Client {
176114
}
177115
}
178116
pub fn send_record_high_priority(&mut self, rec: &Record) -> Result<(), Error> {
179-
180117
let mut w = self.high_writer.lock();
181118
#[cfg(not(feature = "debug"))]
182119
{
@@ -209,7 +146,6 @@ impl Client {
209146
}
210147
#[cfg(feature = "debug")]
211148
{
212-
213149
for rec in recs.iter() {
214150
w.write_all(b"{\"data_type\":")?;
215151
w.write_all(rec.data_type.to_string().as_bytes())?;
@@ -220,7 +156,7 @@ impl Client {
220156
w.write_all(b"}\n")?
221157
}
222158
Ok(())
223-
}
159+
}
224160
}
225161

226162
pub fn send_records(&mut self, recs: &Vec<Record>) -> Result<(), Error> {

plugins/lib/rust/src/sys/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[cfg(target_family = "windows")]
2+
pub mod windows;
3+
#[cfg(target_family = "windows")]
4+
pub use windows::*;
5+
6+
#[cfg(target_family = "unix")]
7+
pub mod unix;
8+
#[cfg(target_family = "unix")]
9+
pub use unix::*;

plugins/lib/rust/src/sys/unix.rs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use std::os::unix::prelude::FromRawFd;
2+
3+
#[cfg(feature = "debug")]
4+
const READ_PIPE_FD: i32 = 0;
5+
#[cfg(not(feature = "debug"))]
6+
const READ_PIPE_FD: i32 = 3;
7+
#[cfg(feature = "debug")]
8+
const WRITE_PIPE_FD: i32 = 1;
9+
#[cfg(not(feature = "debug"))]
10+
const WRITE_PIPE_FD: i32 = 4;
11+
const HIGH_PRIORIT_FD: i32 = 5;
12+
13+
use std::{
14+
fs::File,
15+
io::{BufReader, BufWriter},
16+
sync::Arc,
17+
};
18+
19+
use parking_lot::Mutex;
20+
21+
pub fn get_writer() -> Arc<Mutex<BufWriter<File>>> {
22+
Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
23+
File::from_raw_fd(WRITE_PIPE_FD)
24+
})))
25+
}
26+
27+
pub fn get_high_writer() -> Arc<Mutex<BufWriter<File>>> {
28+
Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
29+
File::from_raw_fd(HIGH_PRIORIT_FD)
30+
})))
31+
}
32+
33+
pub fn get_reader() -> Arc<Mutex<BufReader<File>>> {
34+
Arc::new(Mutex::new(BufReader::with_capacity(512 * 1024, unsafe {
35+
File::from_raw_fd(READ_PIPE_FD)
36+
})))
37+
}
38+
39+
extern "C" fn signal_handler(signal: i32) {
40+
eprintln!("catched signal {:?}, wait 3 seconds and exit", signal);
41+
unsafe {
42+
libc::sleep(3);
43+
libc::close(WRITE_PIPE_FD);
44+
libc::close(READ_PIPE_FD);
45+
if libc::fcntl(HIGH_PRIORIT_FD, libc::F_GETFD) != -1
46+
|| std::io::Error::last_os_error().kind() != std::io::ErrorKind::InvalidInput
47+
{
48+
libc::close(READ_PIPE_FD);
49+
}
50+
}
51+
}
52+
53+
pub fn ignore_terminate() {
54+
unsafe {
55+
libc::signal(libc::SIGINT, libc::SIG_IGN);
56+
libc::signal(libc::SIGUSR1, libc::SIG_IGN);
57+
libc::signal(libc::SIGTERM, signal_handler as _);
58+
}
59+
}
60+
61+
pub fn regist_exception_handler() {}

0 commit comments

Comments
 (0)