pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: pkg/57708: rust problem when building firefox
The following reply was made to PR pkg/57708; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: he%NetBSD.org@localhost
Cc: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Subject: Re: pkg/57708: rust problem when building firefox
Date: Thu, 30 Nov 2023 14:38:25 +0000
This is a multi-part message in MIME format.
--=_tVq9BOFzAnpXS9N5Qy8XBZQoi+hFOgDk
The attached Rust program prints the parameters for both the main
thread and non-main threads. It should be relatively easy to adapt to
the code in Rust std/sys/thread.rs, I expect.
Plop it in src/main.rs next to a Cargo.toml file with the following
content, and run with `cargo run':
[package]
name = "stackguard"
version = "0.1.0"
edition = "2021"
[dependencies]
libc = "^0.2.150"
--=_tVq9BOFzAnpXS9N5Qy8XBZQoi+hFOgDk
Content-Type: text/plain; charset="ISO-8859-1"; name="main"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="main.rs"
//
// __MACHINE_STACK_GROWS_UP (hppa):
//
// +---------------+
// | |
// | guard pages | guardsize
// | |
// +---------------+ guardaddr =3D stackbase + stacksize
// | |
// | stack pages | stacksize
// | |
// +---------------+ stackaddr =3D stackbase
//
// !__MACHINE_STACK_GROWS_UP (i.e., stack grows down -- most
// architectures):
//
// +---------------+ stackbase
// | |
// | stack pages | stacksize
// | |
// +---------------+ stackaddr =3D stackbase - stacksize
// | |
// | guard pages | guardsize
// | |
// +---------------+ guardaddr =3D stackbase - stacksize - guardsize
//
use libc;
use std::io;
use std::mem;
use std::os::raw::c_int;
use std::os::raw::c_uint;
use std::os::raw::c_ulong;
use std::os::raw::c_void;
use std::ptr;
const __MACHINE_STACK_GROWS_UP: bool =3D false; // XXX
#[repr(C)]
struct AuxInfo {
a_type: u32, // Elf32_Word, Elf64_Word
a_v: c_ulong, // Elf32_Word, Elf64_Xword
}
const AT_NULL: u32 =3D 0;
const AT_STACKBASE: u32 =3D 13;
extern { fn _dlauxinfo() -> *const AuxInfo; }
const VM_GUARD_SIZE: c_int =3D 17;
fn pth(error: c_int) -> io::Result<()> {
if error =3D=3D 0 {
Ok(())
} else {
Err(io::Error::from_raw_os_error(error))
}
}
fn getmainstack() -> io::Result<(*mut c_void, usize, *mut c_void, usize)> {
// Get the stack guard size by reading the unsigned int
// vm.guard_size sysctl.
//
// XXX In principle, this is racy because there is a window between
// when the kernel reads the sysctl to determine the guard page
// allocation and when we read the sysctl to find what that was,
// during which time a privileged process could change the sysctl
// without affecting the guard page allocation, but
//
// (a) it's unlikely that this will happen, and
//
// (b) NetBSD doesn't currently provide a non-racy way to do this,
// like maybe an AT_NETBSD_GUARDSIZE auxinfo entry.
//
let mut mib =3D [libc::CTL_VM, VM_GUARD_SIZE];
let mut guardsize: c_uint =3D 0;
let mut len: usize =3D mem::size_of::<c_uint>();
if unsafe { libc::sysctl(
mib.as_mut_ptr(), // name
mib.len() as c_uint, // namelen
&mut guardsize as *mut _ as *mut _, // oldp
&mut len, // oldlenp
ptr::null_mut(), // newp
0, // newlenp
) } =3D=3D -1 {
return Err(io::Error::last_os_error());
}
// Get the stack base by reading the AT_STACKBASE _dlauxinfo item.
// Note: This is the initial stack pointer -- not the numerically
// lowest address; it grows up or down depending on
// __MACHINE_STACK_GROWS_UP.
//
let mut auxinfo =3D unsafe { _dlauxinfo() };
let mut stackbase: *mut c_void =3D ptr::null_mut();
while unsafe { (*auxinfo).a_type } !=3D AT_NULL {
let (a_type, a_v) =3D unsafe { ((*auxinfo).a_type, (*auxinfo).a_v) =
};
println!("a_type=3D{} a_v=3D0x{:x}", a_type, a_v);
if a_type =3D=3D AT_STACKBASE {
stackbase =3D unsafe { mem::transmute((*auxinfo).a_v) };
break
}
auxinfo =3D unsafe { auxinfo.offset(1) };
}
// Get the stack size by reading the hard stack rlimit, which the
// kernel used to determine the maximum stack allocation (not
// including the guard pages).
//
// XXX In principle, this is racy because there is a window between
// when the kernel reads the rlimit to determine the maximum stack
// allocation and when we read the rlimit to find what that was,
// during which time a privileged process could change the rlimit
// without affecting the stack allocation, but
//
// (a) it's unlikely that this will happen, and
//
// (b) NetBSD doesn't currently provide a non-racy way to do this,
// like maybe an AT_NETBSD_STACKSIZE auxinfo entry.
//
let mut rlim =3D unsafe { mem::zeroed() };
if unsafe { libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) } =3D=3D -1 {
return Err(io::Error::last_os_error());
}
let stacksize =3D rlim.rlim_max as usize;
let istacksize =3D stacksize as isize;
let iguardsize =3D guardsize as isize;
// Determine the numerically least addresses of the stack and
// guard. See diagram at top about stacks that grow up vs stacks
// that grow down.
//
let stackaddr =3D if __MACHINE_STACK_GROWS_UP {
stackbase
} else {
unsafe { stackbase.offset(-istacksize) }
};
let guardaddr =3D if __MACHINE_STACK_GROWS_UP {
unsafe { stackbase.offset(istacksize) }
} else {
unsafe { stackbase.offset(-istacksize - iguardsize) }
};
Ok((stackaddr, stacksize, guardaddr, guardsize as usize))
}
fn getthreadattrstack(attr: *mut libc::pthread_attr_t)
-> io::Result<(*mut c_void, usize, *mut c_void, usize)> {
let mut stackaddr =3D ptr::null_mut();
let mut stacksize: usize =3D 0;
let mut guardsize: usize =3D 0;
pth(unsafe {
libc::pthread_attr_getstack(attr, &mut stackaddr, &mut stacksize)
})?;
pth(unsafe { libc::pthread_attr_getguardsize(attr, &mut guardsize) })?;
let guardaddr =3D if __MACHINE_STACK_GROWS_UP {
unsafe { stackaddr.offset(stacksize as isize) }
} else {
unsafe { stackaddr.offset(-(guardsize as isize)) }
};
Ok((stackaddr, stacksize, guardaddr, guardsize))
}
fn getthreadstack() -> io::Result<(*mut c_void, usize, *mut c_void, usize)>=
{
let t =3D unsafe { libc::pthread_self() };
let mut attr: libc::pthread_attr_t =3D unsafe { mem::zeroed() };
pth(unsafe { libc::pthread_getattr_np(t, &mut attr) })?;
let r =3D getthreadattrstack(&mut attr);
pth(unsafe { libc::pthread_attr_destroy(&mut attr) })
.expect("pthread_attr_destroy should never fail");
r
}
fn showstack(name: &str, stack: (*mut c_void, usize, *mut c_void, usize)) {
let (stackaddr, stacksize, guardaddr, guardsize) =3D stack;
println!("{} stack @ [{:p}, {:p})",
name,
stackaddr, unsafe { stackaddr.offset(stacksize as isize) });
println!("{} guard @ [{:p}, {:p})",
name,
guardaddr, unsafe { guardaddr.offset(guardsize as isize) });
}
fn main() {
match getmainstack() {
Ok(stack) =3D> showstack("main", stack),
Err(e) =3D> println!("getmainstack: {}", e),
}
match getthreadstack() {
Ok(stack) =3D> showstack("thread", stack),
Err(e) =3D> println!("getthreadstack: {}", e),
}
}
--=_tVq9BOFzAnpXS9N5Qy8XBZQoi+hFOgDk--
Home |
Main Index |
Thread Index |
Old Index