mirror of
https://github.com/plasma-umass/coz.git
synced 2024-08-15 16:00:32 +03:00
commit
cb12a722db
@ -65,16 +65,6 @@ finally you can run it with `coz run --- ./target/release/$your_binary`.
|
||||
|
||||
Known caveats so far to generate a report that collects information are:
|
||||
|
||||
* Rust programs by default segfault when run with `coz` with an issue related to
|
||||
[plasma-umass/coz#110](https://github.com/plasma-umass/coz/issues/110). Rust
|
||||
programs set up a `sigaltstack` to run segfault handlers to print "you ran out
|
||||
of stack", but this alternate stack is too small to run the `SIGPROF` handler
|
||||
that `coz` installs. To handle this this crate provides a `coz::thread_init()`
|
||||
function which will increase the `sigaltstack` size that Rust installs by
|
||||
default to something large enough to run `coz`. If you see segfaults, or
|
||||
corrupt reports, you may wish to manually call `coz::thread_init()` instead of
|
||||
waiting for this crate to automatically call it for you.
|
||||
|
||||
* Debug information looks to be critical to get a report from `coz`. Make sure
|
||||
that your program is compiled with at least line-table information (`debug =
|
||||
1`) to ensure you get the best experience using `coz`.
|
||||
|
@ -2,16 +2,12 @@ const A: usize = 2_000_000_000;
|
||||
const B: usize = (A as f64 * 1.2) as usize;
|
||||
|
||||
fn main() {
|
||||
coz::thread_init();
|
||||
|
||||
let a = std::thread::spawn(move || {
|
||||
coz::thread_init();
|
||||
for _ in 0..A {
|
||||
coz::progress!("a");
|
||||
}
|
||||
});
|
||||
let b = std::thread::spawn(move || {
|
||||
coz::thread_init();
|
||||
for _ in 0..B {
|
||||
coz::progress!("b");
|
||||
}
|
||||
|
@ -12,10 +12,8 @@
|
||||
//! [rust-readme]: https://github.com/alexcrichton/coz-rs/blob/master/README.md
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::cell::Cell;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
|
||||
/// Equivalent of the `COZ_PROGRESS` and `COZ_PROGRESS_NAMED` macros
|
||||
@ -98,50 +96,6 @@ macro_rules! scope {
|
||||
};
|
||||
}
|
||||
|
||||
/// Perform one-time per-thread initialization for `coz`.
|
||||
///
|
||||
/// This may not be necessary to call, but for good measure it's recommended to
|
||||
/// call once per thread in your application near where the thread starts.
|
||||
/// If you run into issues with segfaults related to SIGPROF handlers this may
|
||||
/// help fix the issue since it installs a bigger stack earlier on in the
|
||||
/// process.
|
||||
pub fn thread_init() {
|
||||
// As one-time program initialization, make sure that our sigaltstack is big
|
||||
// enough. By default coz uses SIGPROF on an alternate signal stack, but the
|
||||
// Rust standard library already sets up a SIGALTSTACK which is
|
||||
// unfortunately too small to run coz's handler. If our sigaltstack looks
|
||||
// too small let's allocate a bigger one and use it here.
|
||||
thread_local!(static SIGALTSTACK_DISABLED: Cell<bool> = Cell::new(false));
|
||||
if SIGALTSTACK_DISABLED.with(|s| s.replace(true)) {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
let mut stack = mem::zeroed();
|
||||
libc::sigaltstack(ptr::null(), &mut stack);
|
||||
let size = 1 << 20; // 1mb
|
||||
if stack.ss_size >= size {
|
||||
return;
|
||||
}
|
||||
let ss_sp = libc::mmap(
|
||||
ptr::null_mut(),
|
||||
size,
|
||||
libc::PROT_READ | libc::PROT_WRITE,
|
||||
libc::MAP_PRIVATE | libc::MAP_ANON,
|
||||
-1,
|
||||
0,
|
||||
);
|
||||
if ss_sp == libc::MAP_FAILED {
|
||||
panic!("failed to allocate alternative stack");
|
||||
}
|
||||
let new_stack = libc::stack_t {
|
||||
ss_sp,
|
||||
ss_flags: 0,
|
||||
ss_size: size,
|
||||
};
|
||||
libc::sigaltstack(&new_stack, ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
||||
/// A `coz`-counter which is either intended for throughput or `begin`/`end`
|
||||
/// points.
|
||||
///
|
||||
@ -267,8 +221,6 @@ fn coz_get_counter(ty: libc::c_int, name: &CStr) -> Option<*mut coz_counter_t> {
|
||||
}
|
||||
});
|
||||
|
||||
thread_init(); // just in case we haven't already
|
||||
|
||||
// SAFETY: We are calling an external function which exists as it is not None
|
||||
// No specific invariants that we must uphold have been defined.
|
||||
func.map(|f| unsafe { f(ty, name.as_ptr()) })
|
||||
|
Loading…
Reference in New Issue
Block a user