jiebi/CodeConvo huggingface dataset:
Code change:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

Related discussion:
text: let handle = UvHandle::alloc(None::<TtyWatcher>, uvll::UV_TTY); let mut watcher = TtyWatcher { tty: handle, <del> stream: StreamWatcher::new(handle), </del> <ins> stream: StreamWatcher::new(handle, true), </ins> home: io.make_handle(), fd: fd, };
Code change:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

Related discussion:
text: rx2.recv(); }) <ins> iotest!(fn clone_while_reading() { let addr = next_test_ip6(); let listen = TcpListener::bind(addr.ip.to_str().as_slice(), addr.port); let mut accept = listen.listen().unwrap(); // Enqueue a task to write to a socket let (tx, rx) = channel(); let (txdone, rxdone) = channel(); let txdone2 = txdone.clone(); spawn(proc() { let mut tcp = TcpStream::connect(addr.ip.to_str().as_slice(), addr.port).unwrap(); rx.recv(); tcp.write_u8(0).unwrap(); txdone2.send(()); }); // Spawn off a reading clone let tcp = accept.accept().unwrap(); let tcp2 = tcp.clone(); let txdone3 = txdone.clone(); spawn(proc() { let mut tcp2 = tcp2; tcp2.read_u8().unwrap(); txdone3.send(()); }); // Try to ensure that the reading clone is indeed reading for _ in range(0i, 50) { ::task::deschedule(); } // clone the handle again while it's reading, then let it finish the // read. let _ = tcp.clone(); tx.send(()); rxdone.recv(); rxdone.recv(); }) </ins> }
Code change:
When using libgreen on Windows (verified not to occur with libnative) when I'm reading from a TcpStream and the remote host closes the stream (specifically I'm closing the client by pressing ctrl + c), the server silently terminates with no error messages. It appears SIGSEGV is being called. The code I was writing which caused this issue can be found here: Using Windows 8.1 x64 with latest Rust nightly. Attempts to backtrace using gdb have failed:
cc
I have acquired a backtrace by attaching gdb to a running process rather than running the process from gdb to begin with (why this works I have no idea)
After debugging with visual studio I figured out the exact line causing the segfault. At it is . here is a null reference, which was transmuted from getting the data of the handle, which is apparently 0. I don't know what is setting it to 0 though.
It appears even sending packets to the connection causes it to die. Has anyone even tested libgreen on Windows with TCP?
I have determined the cause of the bug to be a race condition. Specifically every time I open up a connection, is called 3 times and is called once. If the 3 new streams all occur before the read call, the pointer remains non-zero. If one of them occurs after the read call, then the pointer becomes zero, and the read callback segfaults. I have verified this through multiple runs and statements everywhere.
To further expand, is called when a TcpStream is created, and also everytime I clone the . Since cloning a is the only way to share it across tasks (it doesn't impl ), I had to spawn two tasks, one to read and one to write. Because I spawned the reading one first it would start a read before I cloned the tcp for the writing task, and once I cloned it, the data pointer got reset so the data pointer the read callback received was null thereby causing the segfault.
Yes, no commit gets pushed to master unless it passes all tests on windows, and that includes many networking tests. Do you have a small test case which reproduces this bug? It's likely that there's just some different callback-invoking behavior on windows than on unix that was accidentally not dealt with.
Here is a minimal code example:

Related discussion:
text: use std::io::timer; use mem; <del> let mut tb = TaskBuilder::new(); </del> <ins> let tb = TaskBuilder::new(); </ins> let rx = tb.try_future(proc() {}); mem::drop(rx); timer::sleep(1000);
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: gimli.debug = 0 miniz_oxide.debug = 0 object.debug = 0 <ins> rustc-demangle.debug = 0 </ins> # These are very thin wrappers around executing lld with the right binary name. # Basically nothing within them can go wrong without having been explicitly logged anyway.
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: <del> use crate::ffi::OsStr; </del> <ins> use crate::ffi::{OsStr, OsString}; </ins> use crate::fmt; use crate::io; <del> use crate::marker::PhantomData; </del> use crate::num::NonZero; use crate::path::Path; use crate::sys::fs::File;
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: //////////////////////////////////////////////////////////////////////////////// pub struct Command { <ins> program: OsString, args: Vec<OsString>, </ins> env: CommandEnv, <ins> cwd: Option<OsString>, stdin: Option<Stdio>, stdout: Option<Stdio>, stderr: Option<Stdio>, </ins> } // passed back to std::process with the pipes connected to the child, if any
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: pub stderr: Option<AnonPipe>, } <del> // FIXME: This should be a unit struct, so we can always construct it // The value here should be never used, since we cannot spawn processes. </del> <ins> #[derive(Debug)] </ins> pub enum Stdio { Inherit, Null, MakePipe, <ins> ParentStdout, ParentStderr, #[allow(dead_code)] // This variant exists only for the Debug impl InheritFile(File), </ins> } impl Command { <del> pub fn new(_program: &OsStr) -> Command { Command { env: Default::default() } </del> <ins> pub fn new(program: &OsStr) -> Command { Command { program: program.to_owned(), args: vec![program.to_owned()], env: Default::default(), cwd: None, stdin: None, stdout: None, stderr: None, } </ins> } <del> pub fn arg(&mut self, _arg: &OsStr) {} </del> <ins> pub fn arg(&mut self, arg: &OsStr) { self.args.push(arg.to_owned()); } </ins> pub fn env_mut(&mut self) -> &mut CommandEnv { &mut self.env } <del> pub fn cwd(&mut self, _dir: &OsStr) {} </del> <ins> pub fn cwd(&mut self, dir: &OsStr) { self.cwd = Some(dir.to_owned()); } </ins> <del> pub fn stdin(&mut self, _stdin: Stdio) {} </del> <ins> pub fn stdin(&mut self, stdin: Stdio) { self.stdin = Some(stdin); } </ins> <del> pub fn stdout(&mut self, _stdout: Stdio) {} </del> <ins> pub fn stdout(&mut self, stdout: Stdio) { self.stdout = Some(stdout); } </ins> <del> pub fn stderr(&mut self, _stderr: Stdio) {} </del> <ins> pub fn stderr(&mut self, stderr: Stdio) { self.stderr = Some(stderr); } </ins> pub fn get_program(&self) -> &OsStr { <del> panic!("unsupported") </del> <ins> &self.program </ins> } pub fn get_args(&self) -> CommandArgs<'_> { <del> CommandArgs { _p: PhantomData } </del> <ins> let mut iter = self.args.iter(); iter.next(); CommandArgs { iter } </ins> } pub fn get_envs(&self) -> CommandEnvs<'_> {
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: } pub fn get_current_dir(&self) -> Option<&Path> { <del> None </del> <ins> self.cwd.as_ref().map(|cs| Path::new(cs)) </ins> } pub fn spawn(
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: impl From<io::Stdout> for Stdio { fn from(_: io::Stdout) -> Stdio { <del> // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> Stdio::ParentStdout </ins> } } impl From<io::Stderr> for Stdio { fn from(_: io::Stderr) -> Stdio { <del> // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> Stdio::ParentStderr </ins> } } impl From<File> for Stdio { <del> fn from(_file: File) -> Stdio { // FIXME: This is wrong. // Instead, the Stdio we have here should be a unit struct. panic!("unsupported") </del> <ins> fn from(file: File) -> Stdio { Stdio::InheritFile(file) </ins> } } impl fmt::Debug for Command { <del> fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) </del> <ins> // show all attributes fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { let mut debug_command = f.debug_struct("Command"); debug_command.field("program", &self.program).field("args", &self.args); if !self.env.is_unchanged() { debug_command.field("env", &self.env); } if self.cwd.is_some() { debug_command.field("cwd", &self.cwd); } if self.stdin.is_some() { debug_command.field("stdin", &self.stdin); } if self.stdout.is_some() { debug_command.field("stdout", &self.stdout); } if self.stderr.is_some() { debug_command.field("stderr", &self.stderr); } debug_command.finish() } else { if let Some(ref cwd) = self.cwd { write!(f, "cd {cwd:?} && ")?; } if self.env.does_clear() { write!(f, "env -i ")?; // Altered env vars will be printed next, that should exactly work as expected. } else { // Removed env vars need the command to be wrapped in `env`. let mut any_removed = false; for (key, value_opt) in self.get_envs() { if value_opt.is_none() { if !any_removed { write!(f, "env ")?; any_removed = true; } write!(f, "-u {} ", key.to_string_lossy())?; } } } // Altered env vars can just be added in front of the program. for (key, value_opt) in self.get_envs() { if let Some(value) = value_opt { write!(f, "{}={value:?} ", key.to_string_lossy())?; } } if self.program != self.args[0] { write!(f, "[{:?}] ", self.program)?; } write!(f, "{:?}", self.args[0])?; for arg in &self.args[1..] { write!(f, " {:?}", arg)?; } Ok(()) } </ins> } }
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: } pub struct CommandArgs<'a> { <del> _p: PhantomData<&'a ()>, </del> <ins> iter: crate::slice::Iter<'a, OsString>, </ins> } impl<'a> Iterator for CommandArgs<'a> { type Item = &'a OsStr; fn next(&mut self) -> Option<&'a OsStr> { <del> None </del> <ins> self.iter.next().map(|os| &**os) </ins> } fn size_hint(&self) -> (usize, Option<usize>) { <del> (0, Some(0)) </del> <ins> self.iter.size_hint() </ins> } } <del> impl<'a> ExactSizeIterator for CommandArgs<'a> {} </del> <ins> impl<'a> ExactSizeIterator for CommandArgs<'a> { fn len(&self) -> usize { self.iter.len() } fn is_empty(&self) -> bool { self.iter.is_empty() } } </ins> impl<'a> fmt::Debug for CommandArgs<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { <del> f.debug_list().finish() </del> <ins> f.debug_list().entries(self.iter.clone()).finish() </ins> } }
Code change:
// BEGIN CODE // -- rust -- fn main() { log "doing"; thisdoesnothingwhatthe; log "boing"; } // END CODE The following code compiles, wouldn't it be wiser to have the compiler report an error about "thisdoesnothingwhatthe"?
Closed by .

Related discussion:
text: rustup toolchain install --profile minimal nightly-${TOOLCHAIN} # Sanity check to see if the nightly exists echo nightly-${TOOLCHAIN} > rust-toolchain <del> echo "=> Uninstalling all old nighlies" </del> <ins> echo "=> Uninstalling all old nightlies" </ins> for nightly in $(rustup toolchain list | grep nightly | grep -v $TOOLCHAIN | grep -v nightly-x86_64); do rustup toolchain uninstall $nightly done
Code change:
The expansion of and both currently cause code to fail the stability check because they expand to reveal unstable implementation details. A seemingly reasonable solution to this would be to just not run the analysis on any code that has been macro-expanded. cc
I definitely agree with this approach: we should be able to annotate a macro with a stability level, and that's what should count for its users. Do we have a way of telling what part of an AST was generated via macro expansion by the time we get to linting?
Mostly; there's the field of a : for normal code, for macro generated code (basically containing the backtrace of macro invocations that led to that point).
OK, that makes this sound like a pretty easy fix. I'll take a quick look at it tomorrow (unless wants to?)
Hm, this seems slightly subtle, since the contents of a macro would then never be checked for stability. This differs to a conventional function, e.g. given , won't warn, but the contents of is still checked, while where is just never checked. (Of course, macros and phasing are both feature gated so you have to opt-in to instability to use non-standard macros anyway.)
Good point. Also, it looks tricky with the current infrastructure to even lint on the macro invocation -- the backtrace of macro expansion does not appear to link to the def_id of the macro (or give any other way of getting at the macro's stability). Nevertheless, I think we should bail out of the lint when we hit the results of expansion; those should be checked, if anywhere, at the site of macro definition. One other question: do syntax extensions also produce the span information you mentioned above? I ask because original problematic cases are written syntax extensions. If not, is there some other way of telling that an expansion happened?
I have a patch ready that bails of out the lint on expanded code. This also seems to mask uses of . If y'all are ok with this strategy for now, I'll file a PR.
Sounds good to me. Thanks!
cc

Related discussion:
text: } fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { <ins> // if the expression was produced by a macro expansion, if e.span.expn_info.is_some() { return } </ins> let id = match e.node { ast::ExprPath(..) | ast::ExprStruct(..) => { match cx.tcx.def_map.borrow().find(&e.id) {
Code change:
The expansion of and both currently cause code to fail the stability check because they expand to reveal unstable implementation details. A seemingly reasonable solution to this would be to just not run the analysis on any code that has been macro-expanded. cc
I definitely agree with this approach: we should be able to annotate a macro with a stability level, and that's what should count for its users. Do we have a way of telling what part of an AST was generated via macro expansion by the time we get to linting?
Mostly; there's the field of a : for normal code, for macro generated code (basically containing the backtrace of macro invocations that led to that point).
OK, that makes this sound like a pretty easy fix. I'll take a quick look at it tomorrow (unless wants to?)
Hm, this seems slightly subtle, since the contents of a macro would then never be checked for stability. This differs to a conventional function, e.g. given , won't warn, but the contents of is still checked, while where is just never checked. (Of course, macros and phasing are both feature gated so you have to opt-in to instability to use non-standard macros anyway.)
Good point. Also, it looks tricky with the current infrastructure to even lint on the macro invocation -- the backtrace of macro expansion does not appear to link to the def_id of the macro (or give any other way of getting at the macro's stability). Nevertheless, I think we should bail out of the lint when we hit the results of expansion; those should be checked, if anywhere, at the site of macro definition. One other question: do syntax extensions also produce the span information you mentioned above? I ask because original problematic cases are written syntax extensions. If not, is there some other way of telling that an expansion happened?
I have a patch ready that bails of out the lint on expanded code. This also seems to mask uses of . If y'all are ok with this strategy for now, I'll file a PR.
Sounds good to me. Thanks!
cc

Related discussion:
text: #![crate_id="lint_stability#0.1"] #![crate_type = "lib"] <ins> #![feature(macro_rules)] #![macro_escape] </ins> #[deprecated] pub fn deprecated() {} #[deprecated="text"]
Code change:
The expansion of and both currently cause code to fail the stability check because they expand to reveal unstable implementation details. A seemingly reasonable solution to this would be to just not run the analysis on any code that has been macro-expanded. cc
I definitely agree with this approach: we should be able to annotate a macro with a stability level, and that's what should count for its users. Do we have a way of telling what part of an AST was generated via macro expansion by the time we get to linting?
Mostly; there's the field of a : for normal code, for macro generated code (basically containing the backtrace of macro invocations that led to that point).
OK, that makes this sound like a pretty easy fix. I'll take a quick look at it tomorrow (unless wants to?)
Hm, this seems slightly subtle, since the contents of a macro would then never be checked for stability. This differs to a conventional function, e.g. given , won't warn, but the contents of is still checked, while where is just never checked. (Of course, macros and phasing are both feature gated so you have to opt-in to instability to use non-standard macros anyway.)
Good point. Also, it looks tricky with the current infrastructure to even lint on the macro invocation -- the backtrace of macro expansion does not appear to link to the def_id of the macro (or give any other way of getting at the macro's stability). Nevertheless, I think we should bail out of the lint when we hit the results of expansion; those should be checked, if anywhere, at the site of macro definition. One other question: do syntax extensions also produce the span information you mentioned above? I ask because original problematic cases are written syntax extensions. If not, is there some other way of telling that an expansion happened?
I have a patch ready that bails of out the lint on expanded code. This also seems to mask uses of . If y'all are ok with this strategy for now, I'll file a PR.
Sounds good to me. Thanks!
cc

Related discussion:
text: pub struct FrozenTupleStruct(pub int); #[locked] pub struct LockedTupleStruct(pub int); <ins> #[macro_export] macro_rules! macro_test( () => (deprecated()); ) </ins>