forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
libstd/sys/unix/process.rs: reap a zombie who didn't get through to exec(2) #1
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
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…xec(2). After the library successfully called fork(2), the child does several setup works such as setting UID, GID and current directory before it calls exec(2). When those setup works failed, the child exits but the parent didn't call waitpid(2) and left it as a zombie. This patch also add several sanity checks. They shouldn't make any noticeable impact to runtime performance. The new test case in libstd/io/process.rs calls the ps command to check if the new code can really reap a zombie. The output of "ps -A -o pid,sid,command" should look like this: PID SID COMMAND 1 1 /sbin/init 2 0 [kthreadd] 3 0 [ksoftirqd/0] ... 12562 9237 ./spawn-failure 12563 9237 [spawn-failure] <defunct> 12564 9237 [spawn-failure] <defunct> ... 12592 9237 [spawn-failure] <defunct> 12593 9237 ps -A -o pid,sid,command 12884 12884 /bin/zsh 12922 12922 /bin/zsh ... where ./spawn-failure is my test program which intentionally leaves many zombies. Filtering the output with the "SID" (session ID) column is a quick way to tell if a process (zombie) was spawned by my own test program. Then the number of "defunct" lines is the number of zombie children. Signed-off-by: NODA, Kai <[email protected]>
nodakai
pushed a commit
that referenced
this pull request
Jan 1, 2015
Fixes rust-lang#19707. In terms of output, it currently uses the form `argument #1`, `argument #2`, etc. If anyone has any better suggestions I would be glad to consider them.
nodakai
pushed a commit
that referenced
this pull request
Dec 18, 2015
…hange Change verbiage in Stack & Heap page
nodakai
pushed a commit
that referenced
this pull request
Mar 6, 2016
suggest: Put the `use` in suggested code inside the quotes Change import a trait suggestion from: help: candidate #1: use `std::io::Write` to help: candidate #1: `use std::io::Write` so that the code can be copied directly. Fixes rust-lang#31864
nodakai
pushed a commit
that referenced
this pull request
Aug 23, 2016
rustc_trans: don't Assert(Overflow(Neg)) when overflow checks are off. Generic functions using `Neg` on primitive types would panic even in release mode, with MIR trans. The solution is a bit hacky, as I'm checking the message, since there's no dedicated `CheckedUnOp`. Blocks Servo rustup ([failure #1](http://build.servo.org/builders/linux-rel/builds/2477/steps/test_3/logs/stdio), [failure #2](http://build.servo.org/builders/mac-rel-css/builds/2364/steps/test/logs/stdio)) - this should be the last hurdle, it affects only one test.
nodakai
pushed a commit
that referenced
this pull request
Feb 16, 2017
For a given file ```rust trait A { fn foo(&self) {} } trait B : A { fn foo(&self) {} } fn bar<T: B>(a: &T) { a.foo() } ``` provide the following output ``` error[E0034]: multiple applicable items in scope --> file.rs:6:5 | 6 | a.foo(1) | ^^^ multiple `foo` found | note: candidate #1 is defined in the trait `A` --> file.rs:2:11 | 2 | trait A { fn foo(&self, a: usize) {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to use it here write `A::foo(&a, 1)` instead --> file.rs:6:5 | 6 | a.foo(1) | ^^^ note: candidate #2 is defined in the trait `B` --> file.rs:3:15 | 3 | trait B : A { fn foo(&self, a: usize) {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to use it here write `B::foo(&a, 1)` instead --> file.rs:6:5 | 6 | a.foo(1) | ^^^ ```
nodakai
pushed a commit
that referenced
this pull request
Feb 16, 2017
E0034: provide disambiguated syntax for candidates For a given file ```rust trait A { fn foo(&self) {} } trait B : A { fn foo(&self) {} } fn bar<T: B>(a: &T) { a.foo() } ``` provide the following output ``` error[E0034]: multiple applicable items in scope --> file.rs:6:5 | 6 | a.foo(1) | ^^^ multiple `foo` found | note: candidate #1 is defined in the trait `A` --> file.rs:2:11 | 2 | trait A { fn foo(&self, a: usize) {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to use it here write `A::foo(&a, 1)` instead --> file.rs:6:5 | 6 | a.foo(1) | ^^^ note: candidate #2 is defined in the trait `B` --> file.rs:3:15 | 3 | trait B : A { fn foo(&self, a: usize) {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to use it here write `B::foo(&a, 1)` instead --> file.rs:6:5 | 6 | a.foo(1) | ^^^ ``` Fix rust-lang#37767.
nodakai
pushed a commit
that referenced
this pull request
Feb 16, 2017
LeakSanitizer, ThreadSanitizer, AddressSanitizer and MemorySanitizer support ``` $ cargo new --bin leak && cd $_ $ edit Cargo.toml && tail -n3 $_ ``` ``` toml [profile.dev] opt-level = 1 ``` ``` $ edit src/main.rs && cat $_ ``` ``` rust use std::mem; fn main() { let xs = vec![0, 1, 2, 3]; mem::forget(xs); } ``` ``` $ RUSTFLAGS="-Z sanitizer=leak" cargo run --target x86_64-unknown-linux-gnu; echo $? Finished dev [optimized + debuginfo] target(s) in 0.0 secs Running `target/debug/leak` ================================================================= ==10848==ERROR: LeakSanitizer: detected memory leaks Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x557c3488db1f in __interceptor_malloc /shared/rust/checkouts/lsan/src/compiler-rt/lib/lsan/lsan_interceptors.cc:55 #1 0x557c34888aaa in alloc::heap::exchange_malloc::h68f3f8b376a0da42 /shared/rust/checkouts/lsan/src/liballoc/heap.rs:138 #2 0x557c34888afc in leak::main::hc56ab767de6d653a $PWD/src/main.rs:4 #3 0x557c348c0806 in __rust_maybe_catch_panic ($PWD/target/debug/leak+0x3d806) SUMMARY: LeakSanitizer: 16 byte(s) leaked in 1 allocation(s). 23 ``` ``` $ cargo new --bin racy && cd $_ $ edit src/main.rs && cat $_ ``` ``` rust use std::thread; static mut ANSWER: i32 = 0; fn main() { let t1 = thread::spawn(|| unsafe { ANSWER = 42 }); unsafe { ANSWER = 24; } t1.join().ok(); } ``` ``` $ RUSTFLAGS="-Z sanitizer=thread" cargo run --target x86_64-unknown-linux-gnu; echo $? ================== WARNING: ThreadSanitizer: data race (pid=12019) Write of size 4 at 0x562105989bb4 by thread T1: #0 racy::main::_$u7b$$u7b$closure$u7d$$u7d$::hbe13ea9e8ac73f7e $PWD/src/main.rs:6 (racy+0x000000010e3f) #1 _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h2e466a92accacc78 /shared/rust/checkouts/lsan/src/libstd/panic.rs:296 (racy+0x000000010cc5) #2 std::panicking::try::do_call::h7f4d2b38069e4042 /shared/rust/checkouts/lsan/src/libstd/panicking.rs:460 (racy+0x00000000c8f2) #3 __rust_maybe_catch_panic <null> (racy+0x0000000b4e56) #4 std::panic::catch_unwind::h31ca45621ad66d5a /shared/rust/checkouts/lsan/src/libstd/panic.rs:361 (racy+0x00000000b517) #5 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::hccfc37175dea0b01 /shared/rust/checkouts/lsan/src/libstd/thread/mod.rs:357 (racy+0x00000000c226) #6 _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::hd880bbf91561e033 /shared/rust/checkouts/lsan/src/liballoc/boxed.rs:605 (racy+0x00000000f27e) #7 std::sys::imp::thread::Thread::new::thread_start::hebdfc4b3d17afc85 <null> (racy+0x0000000abd40) Previous write of size 4 at 0x562105989bb4 by main thread: #0 racy::main::h23e6e5ca46d085c3 $PWD/src/main.rs:8 (racy+0x000000010d7c) #1 __rust_maybe_catch_panic <null> (racy+0x0000000b4e56) #2 __libc_start_main <null> (libc.so.6+0x000000020290) Location is global 'racy::ANSWER::h543d2b139f819b19' of size 4 at 0x562105989bb4 (racy+0x0000002f8bb4) Thread T1 (tid=12028, running) created by main thread at: #0 pthread_create /shared/rust/checkouts/lsan/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (racy+0x00000001aedb) #1 std::sys::imp::thread::Thread::new::hce44187bf4a36222 <null> (racy+0x0000000ab9ae) #2 std::thread::spawn::he382608373eb667e /shared/rust/checkouts/lsan/src/libstd/thread/mod.rs:412 (racy+0x00000000b5aa) #3 racy::main::h23e6e5ca46d085c3 $PWD/src/main.rs:6 (racy+0x000000010d5c) #4 __rust_maybe_catch_panic <null> (racy+0x0000000b4e56) #5 __libc_start_main <null> (libc.so.6+0x000000020290) SUMMARY: ThreadSanitizer: data race $PWD/src/main.rs:6 in racy::main::_$u7b$$u7b$closure$u7d$$u7d$::hbe13ea9e8ac73f7e ================== ThreadSanitizer: reported 1 warnings 66 ``` ``` $ cargo new --bin oob && cd $_ $ edit src/main.rs && cat $_ ``` ``` rust fn main() { let xs = [0, 1, 2, 3]; let y = unsafe { *xs.as_ptr().offset(4) }; } ``` ``` $ RUSTFLAGS="-Z sanitizer=address" cargo run --target x86_64-unknown-linux-gnu; echo $? ================================================================= ==13328==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff29f3ecd0 at pc 0x55802dc6bf7e bp 0x7fff29f3ec90 sp 0x7fff29f3ec88 READ of size 4 at 0x7fff29f3ecd0 thread T0 #0 0x55802dc6bf7d in oob::main::h0adc7b67e5feb2e7 $PWD/src/main.rs:3 #1 0x55802dd60426 in __rust_maybe_catch_panic ($PWD/target/debug/oob+0xfe426) #2 0x55802dd58dd9 in std::rt::lang_start::hb2951fc8a59d62a7 ($PWD/target/debug/oob+0xf6dd9) #3 0x55802dc6c002 in main ($PWD/target/debug/oob+0xa002) #4 0x7fad8c3b3290 in __libc_start_main (/usr/lib/libc.so.6+0x20290) #5 0x55802dc6b719 in _start ($PWD/target/debug/oob+0x9719) Address 0x7fff29f3ecd0 is located in stack of thread T0 at offset 48 in frame #0 0x55802dc6bd5f in oob::main::h0adc7b67e5feb2e7 $PWD/src/main.rs:1 This frame has 1 object(s): [32, 48) 'xs' <== Memory access at offset 48 overflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow $PWD/src/main.rs:3 in oob::main::h0adc7b67e5feb2e7 Shadow bytes around the buggy address: 0x1000653dfd40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfd50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfd60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfd70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x1000653dfd90: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00 0x1000653dfda0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfdb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfdc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfdd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000653dfde0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==13328==ABORTING 1 ``` ``` $ cargo new --bin uninit && cd $_ $ edit src/main.rs && cat $_ ``` ``` rust use std::mem; fn main() { let xs: [u8; 4] = unsafe { mem::uninitialized() }; let y = xs[0] + xs[1]; } ``` ``` $ RUSTFLAGS="-Z sanitizer=memory" cargo run; echo $? ==30198==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x563f4b6867da in uninit::main::hc2731cd4f2ed48f8 $PWD/src/main.rs:5 #1 0x563f4b7033b6 in __rust_maybe_catch_panic ($PWD/target/debug/uninit+0x873b6) #2 0x563f4b6fbd69 in std::rt::lang_start::hb2951fc8a59d62a7 ($PWD/target/debug/uninit+0x7fd69) #3 0x563f4b6868a9 in main ($PWD/target/debug/uninit+0xa8a9) #4 0x7fe844354290 in __libc_start_main (/usr/lib/libc.so.6+0x20290) #5 0x563f4b6864f9 in _start ($PWD/target/debug/uninit+0xa4f9) SUMMARY: MemorySanitizer: use-of-uninitialized-value $PWD/src/main.rs:5 in uninit::main::hc2731cd4f2ed48f8 Exiting 77 ```
nodakai
pushed a commit
that referenced
this pull request
Mar 7, 2017
nodakai
pushed a commit
that referenced
this pull request
Mar 14, 2017
Group "missing variable bind" spans in `or` matches and clarify wording for the two possible cases: when a variable from the first pattern is not in any of the subsequent patterns, and when a variable in any of the other patterns is not in the first one. Before: ``` error[E0408]: variable `a` from pattern #1 is not bound in pattern #2 --> file.rs:10:23 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^^^^ pattern doesn't bind `a` error[E0408]: variable `b` from pattern #2 is not bound in pattern #1 --> file.rs:10:32 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^ pattern doesn't bind `b` error[E0408]: variable `a` from pattern #1 is not bound in pattern #3 --> file.rs:10:37 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^ pattern doesn't bind `a` error[E0408]: variable `d` from pattern #1 is not bound in pattern #3 --> file.rs:10:37 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^ pattern doesn't bind `d` error[E0408]: variable `c` from pattern #3 is not bound in pattern #1 --> file.rs:10:43 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^ pattern doesn't bind `c` error[E0408]: variable `d` from pattern #1 is not bound in pattern #4 --> file.rs:10:48 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^ pattern doesn't bind `d` error: aborting due to 6 previous errors ``` After: ``` error[E0408]: variable `a` is not bound in all patterns --> file.rs:20:37 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { intln!("{:?}", a); } | - ^^^^^^^^^^^ ^^^^^^^^ - variable t in all patterns | | | | | | | pattern doesn't bind `a` | | pattern doesn't bind `a` | variable not in all patterns error[E0408]: variable `d` is not bound in all patterns --> file.rs:20:37 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { intln!("{:?}", a); } | - - ^^^^^^^^ ^^^^^^^^ pattern esn't bind `d` | | | | | | | pattern doesn't bind `d` | | variable not in all patterns | variable not in all patterns error[E0408]: variable `b` is not bound in all patterns --> file.rs:20:37 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { intln!("{:?}", a); } | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern esn't bind `b` | | | | | | | pattern doesn't bind `b` | | variable not in all patterns | pattern doesn't bind `b` error[E0408]: variable `c` is not bound in all patterns --> file.rs:20:48 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { intln!("{:?}", a); } | ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern esn't bind `c` | | | | | | | variable not in all tterns | | pattern doesn't bind `c` | pattern doesn't bind `c` error: aborting due to 4 previous errors ``` * Have only one presentation for binding consistency errors * Point to same binding in multiple patterns when possible * Check inconsistent bindings in all arms * Simplify wording of diagnostic message * Sort emition and spans of binding errors for deterministic output
nodakai
pushed a commit
that referenced
this pull request
Mar 14, 2017
Clean up "pattern doesn't bind x" messages Group "missing variable bind" spans in `or` matches and clarify wording for the two possible cases: when a variable from the first pattern is not in any of the subsequent patterns, and when a variable in any of the other patterns is not in the first one. Before: ```rust error[E0408]: variable `a` from pattern #1 is not bound in pattern #2 --> file.rs:10:23 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^^^^ pattern doesn't bind `a` error[E0408]: variable `b` from pattern #2 is not bound in pattern #1 --> file.rs:10:32 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^ pattern doesn't bind `b` error[E0408]: variable `a` from pattern #1 is not bound in pattern #3 --> file.rs:10:37 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^ pattern doesn't bind `a` error[E0408]: variable `d` from pattern #1 is not bound in pattern #3 --> file.rs:10:37 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^ pattern doesn't bind `d` error[E0408]: variable `c` from pattern #3 is not bound in pattern #1 --> file.rs:10:43 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^ pattern doesn't bind `c` error[E0408]: variable `d` from pattern #1 is not bound in pattern #4 --> file.rs:10:48 | 10 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^ pattern doesn't bind `d` error: aborting due to 6 previous errors ``` After: ```rust error[E0408]: variable `d` is not bound in all patterns --> $DIR/issue-39698.rs:20:37 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` | | | | | | | pattern doesn't bind `d` | | variable not in all patterns | variable not in all patterns error[E0408]: variable `c` is not bound in all patterns --> $DIR/issue-39698.rs:20:48 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^^^^ ^^^^^^^^^^^ - ^^^^^^^^ pattern doesn't bind `c` | | | | | | | variable not in all patterns | | pattern doesn't bind `c` | pattern doesn't bind `c` error[E0408]: variable `a` is not bound in all patterns --> $DIR/issue-39698.rs:20:37 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | - ^^^^^^^^^^^ ^^^^^^^^ - variable not in all patterns | | | | | | | pattern doesn't bind `a` | | pattern doesn't bind `a` | variable not in all patterns error[E0408]: variable `b` is not bound in all patterns --> $DIR/issue-39698.rs:20:37 | 20 | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | ^^^^^^^^^^^ - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `b` | | | | | | | pattern doesn't bind `b` | | variable not in all patterns | pattern doesn't bind `b` error: aborting due to 4 previous errors ``` Fixes rust-lang#39698.
nodakai
pushed a commit
that referenced
this pull request
Jun 26, 2018
When encountering an unexisting method for a given trait where an associated function has the same name, suggest using the appropriate syntax, instead of using `help` text. When only one candidate is found, do not call it "candidate #1", just call it "the candidate".
nodakai
pushed a commit
that referenced
this pull request
Jun 26, 2018
Tweak output on E0599 for assoc fn used as method - Use suggestion instead of `help` when possible - Add primary span label - Remove incorrect `help` suggestion using incorrect syntax - Do not refer to only one possible candidate as `candidate #1`, refer to it as `the candidate`
nodakai
pushed a commit
that referenced
this pull request
Jul 8, 2018
Suggestion for 'static impl Trait return When encountering a named or anonymous sup requirement (for example, `&'a self`) and a `'static` impl Trait return type, suggest adding the `'_` lifetime constraing to the return type. Fix rust-lang#43719, rust-lang#51282. ``` error: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:17:16 | LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> { | ----------------------- this return type evaluates to the `'static` lifetime... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | | ...but this borrow... | note: ...can't outlive the anonymous lifetime #1 defined on the method body at 16:5 --> $DIR/static-return-lifetime-infered.rs:16:5 | LL | / fn iter_values_anon(&self) -> impl Iterator<Item=u32> { LL | | self.x.iter().map(|a| a.0) LL | | } | |_____^ help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 16:5 | LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ```
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
(This PR depends on my another PR rust-lang#19439 )
After the library successfully called
fork(2)
, the child does severalsetup works such as setting UID, GID and current directory before it
calls
exec(2)
. When those setup works failed, the child exits but theparent didn't call
waitpid(2)
and left it as a zombie.This patch also add several sanity checks. They shouldn't make any
noticeable impact to runtime performance.
The new test case in libstd/io/process.rs calls the ps command to check
if the new code can really reap a zombie.
The output of
ps -A -o pid,sid,command
should look like this:where
./spawn-failure
is my test program which intentionally leaves manyzombies. Filtering the output with the "SID" (session ID) column is
a quick way to tell if a process (zombie) was spawned by my own test
program. Then the number of "defunct" lines is the number of zombie
children.