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