Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Rust initialization macro #20

Merged
merged 6 commits into from
Oct 3, 2023
Merged
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
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,12 @@ panic = "abort"
panic = "abort"
```

2. In your program, run `chatdbg::chatdbg()` as early as possible.
2. In your program, apply the `#[chatdbg::main]` attribute to your `main`
function:

```rust
use chatdbg;

#[chatdbg::main]
fn main() {
chatdbg::chatdbg();
// Insert the above line as early as possible in your main function
```

Now you can run your Rust code with `lldb` (`gdb` is not yet supported).
Expand Down
6 changes: 6 additions & 0 deletions rust-support/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[workspace]
resolver = "2"
members = [
"chatdbg",
"chatdbg_macros",
]
1 change: 1 addition & 0 deletions rust-support/chatdbg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ homepage = "https://github.com/plasma-umass/ChatDBG/"
repository = "https://github.com/plasma-umass/ChatDBG/"

[dependencies]
chatdbg_macros = { path = "../chatdbg_macros" }
lazy_static = "1.4.0"
35 changes: 24 additions & 11 deletions rust-support/chatdbg/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
pub use chatdbg_macros::main;

use std::fs::{File, OpenOptions};
use std::io::Write;
use std::panic;
use std::sync::{Mutex, atomic::{AtomicBool, Ordering}};
use std::sync::{
atomic::{AtomicBool, Ordering},
Mutex,
};
use std::thread;

// Global Mutex to synchronize file writes across threads.
Expand All @@ -14,39 +19,47 @@ pub fn chatdbg() {
// Set a custom panic hook.
panic::set_hook(Box::new(|info| {
let _guard = FILE_MUTEX.lock().unwrap(); // Lock Mutex to synchronize access.

// Format the panic message similarly to the default panic handler.
let payload = if let Some(s) = info.payload().downcast_ref::<&str>() {
*s
} else {
"Box<Any>"
};

let location = if let Some(location) = info.location() {
format!(" at '{}' line {}", location.file(), location.line())
} else {
String::from("")
};

let message = format!("thread '{}' panicked with '{}'{}", thread::current().name().unwrap_or("<unnamed>"), payload, location);


let message = format!(
"thread '{}' panicked with '{}'{}",
thread::current().name().unwrap_or("<unnamed>"),
payload,
location
);

// Print to stderr.
eprintln!("{}", message);

// Specify the filename without including the process id.
let filename = "panic_log.txt";

// Open the file with appropriate options.
let mut file = if FILE_CREATED.swap(true, Ordering::SeqCst) {
// If the file is already created by another thread, open it in append mode.
OpenOptions::new().create(true).append(true).open(filename).expect("Unable to open file")
OpenOptions::new()
.create(true)
.append(true)
.open(filename)
.expect("Unable to open file")
} else {
// If this is the first thread to create the file, overwrite any existing file.
File::create(filename).expect("Unable to create file")
};

// Write to the file.
writeln!(file, "{}", message).expect("Unable to write to file");
}));
}

11 changes: 11 additions & 0 deletions rust-support/chatdbg_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "chatdbg_macros"
version = "0.1.3"
edition = "2021"

[dependencies]
quote = "1.0.33"
syn = { version = "2.0.37", features = ["full"] }

[lib]
proc-macro = true
25 changes: 25 additions & 0 deletions rust-support/chatdbg_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse, ItemFn};

#[proc_macro_attribute]
pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream {
emeryberger marked this conversation as resolved.
Show resolved Hide resolved
let item = match parse(input) {
Ok(i) => i,
Err(_) => return quote! {}.into(),
};
let ItemFn {
attrs,
vis,
sig,
block,
} = item;
let stmts = &block.stmts;
quote! {
#(#attrs)* #vis #sig {
::chatdbg::chatdbg();
#(#stmts)*
}
}
.into()
}
3 changes: 3 additions & 0 deletions test/rust/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
Cargo.lock
panic_log.txt
18 changes: 18 additions & 0 deletions test/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "chatdbg_rust_tests"
version = "1.0.0"
edition = "2021"

[[bin]]
name = "test-failed-assert"
path = "test-failed-assert.rs"

[dependencies]
chatdbg = { path = "../../rust-support/chatdbg" }

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

13 changes: 13 additions & 0 deletions test/rust/test-failed-assert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn fact(n: f32) -> f32 {
let mut x = 1.0;
for i in 0..n as i32 {
x *= i as f32;
}
assert!(x != 0.0);
x
}

#[chatdbg::main]
fn main() {
println!("{}", fact(100.0));
}