On Thu, 2017-06-29 at 17:45 +0000, Ximin Luo wrote:
> Ximin Luo:
> > [..]
> > 
> > The segfault occurs on various commands at different frequencies and after 
> > differing amounts of time (but all less than a few seconds). The stack 
> > traces 
> > are all different too. [..]
> 
> With some help from arielby from #rust-internals, we noticed that the
> stack getting allocated was always 192KB even though `ulimit -s` says
> 8192 (i.e. 8MB),

That's normal.

> and when the program tries to grow beyond this, is when the segfaults
> occur. Hope that's useful.

That's obviously not.  A page fault below the stack mapping and not too
far below the stack pointer should cause the mapping to expand, up to
the limit, without the process having to do anything about it.

The shell ulimit command, and the underlying setrlimit(2) system call,
set the limit for expansion of the stack mapping.  Expansion is also
restricted by the requirement of a gap between the stack and the next
mapping below, but so long as the size limit is not 'unlimited' this
*should* make no difference.  The gap used to be 1 page and is now
configurable but defaults to 256 pages.

The stack gap used to be included in the range shown in /proc/*/maps
and was counted toward the stack limit.  The first version of the fix
did not change that, so it effectively reduced all existing limits by
255 pages.  The second version of the fix excludes the stack gap from
both.

This expanding behaviour normally only applies to the initial thread's
stack mapping, which is allocated automatically by execve(2).  For new
threads created using clone(2) the caller usually sets up a fixed size
stack mapping.

Hopefully that explanation can help you and the Rust developers
identify what's upsetting Rust, and I can then try to get the kernel
behaviour further refined to avoid doing so.

[...]
> Also, I earlier stated that this could be worked around by disabling
> ASLR (which gdb does implicitly, so we had to re-enable it). This was
> true on a deb8u1 kernel, but seems no longer to be true on the newer
> deb8u2 kernels - i.e. now when disabling ASLR I still see the
> segfaults. :(
> 
> Running using the Debian rustc and cargo package, with the same
> command line that the rustc build would run:
> 
> > (sid_ppc64el-dchroot)infinity0@plummer:~/rustc$ gdb -q -ex 'run build 
> > --manifest-path /home/infinity0/rustc/src/bootstrap/Cargo.toml --frozen' 
> > cargo
> Reading symbols from cargo...Reading symbols from 
> /usr/lib/debug/.build-id/e9/f3607a78a9b60bc2112c3810f72b42b9a5e1f9.debug...done.
> done.
> Starting program: /usr/bin/cargo build --manifest-path 
> /home/infinity0/rustc/src/bootstrap/Cargo.toml --frozen
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library 
> "/lib/powerpc64le-linux-gnu/libthread_db.so.1".
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000020376b78 in regex::exec::ExecBuilder::build::h46818bd83e889eca ()
> (gdb) info inferiors
>   Num  Description       Executable        
> * 1    process 32472     /usr/bin/cargo    
> (gdb) shell command grep stack /proc/32472/maps
> 3ffffffd0000-400000000000 rw-p 00000000 00:00 0                          
> [stack]
> 
> Setting `ulimit -s 24576` still works, though.

Do you know how much stack space this function needs?  Can you get the
page fault address?  (I don't remember how to do that in gdb.)

Ben.

-- 
Ben Hutchings
When in doubt, use brute force. - Ken Thompson

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to