Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Failing to build the lib portion of a project crashes the RLS on the bin portion #443

Closed
mqudsi opened this issue Aug 15, 2017 · 10 comments
Closed
Labels

Comments

@mqudsi
Copy link

mqudsi commented Aug 15, 2017

Using neovim LanguageClient, running the latest nightly toolchain/rls/src/etc I get the following (every time):

22:41:55 DEBUG     => {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections:\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":2,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
22:41:55 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
22:41:55 WARNING  no handler implemented for rustDocument_diagnosticsBegin
22:41:56 INFO     textDocument/didChange
22:41:56 DEBUG     => {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections::\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":3,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
22:41:56 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
22:41:56 WARNING  no handler implemented for rustDocument_diagnosticsBegin
22:41:56 DEBUG     <= 
22:41:56 ERROR    Failed to start language server: [b'{"message":"expected identifier, found keyword `use`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":320,"byte_end":323,"line_start":15,"line_end":15,"column_start":1,"column_end":4,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":1,"highlight_end":4}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"expected one of `::`, `;`, or `as`, found `std`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":323,"byte_end":323,"line_start":15,"line_end":15,"column_start":4,"column_end":4,"is_primary":false,"text":[{"text":"use std::env;","highlight_start":4,"highlight_end":4}],"label":"expected one of `::`, `;`, or `as` here","suggested_replacement":null,"expansion":null},{"file_name":"src/main.rs","byte_start":324,"byte_end":327,"line_start":15,"line_end":15,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":5,"highlight_end":8}],"label":"unexpected token","suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"aborting due to 2 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":null}\n', b'thread \'<unnamed>\' panicked at \'could not run cargo: CargoError(Internal(Msg("failed to stat `/mnt/d/GIT/udpproxy/target/rls/debug/.fingerprint/udpproxy-9ca18b3406e94519/dep-bin-udpproxy-9ca18b3406e94519`")), State { next_error: Some(Error { repr: Os { code: 2, message: "No such file or directory" } }), backtrace: None })\', /checkout/src/libcore/result.rs:860:4\n', b'note: Run with `RUST_BACKTRACE=1` for a backtrace.\n', b'thread \'<unnamed>\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n', b'thread \'main\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n']
22:41:57 ERROR    Failed to start language server: []

I will attempt to get the full backtrace. Any suggestions?

@nrc
Copy link
Member

nrc commented Aug 15, 2017

Looks like Cargo can't read a fingerprint file from disk. You could try a cargo clean of the project before using the RLS. You could also try running in VSCode to see if it is a client or server problem. I would also do a rustup update to make sure all your versions of rls, Cargo, and rustc are up to date and on the same version. (To check, are you building your own RLS or using the version from rustup?)

@mqudsi
Copy link
Author

mqudsi commented Aug 15, 2017

@nrc I'll try cargo clean and let you know. Everything was installed via rustup, and I had already updated prior to posting.

Unfortunately, I can't try another client easily as this is under WSL and VSCode would execute out of the WSL environment.

@mqudsi
Copy link
Author

mqudsi commented Aug 16, 2017

cargo clean fixed that particular problem but one or two completions later, it happened again.

This is with RUST_BACKTRACE=full:

05:57:45 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:57:45 WARNING  register completion manager source failed. Error: NvimError(b'Error calling function.',)
05:57:47 WARNING  no handler implemented for rustDocument_diagnosticsEnd
05:57:50 INFO     Begin textDocument/completion
05:57:50 INFO     textDocument/didChange
05:57:50 INFO     Begin textDocument/completion
05:57:50 DEBUG     => {"id":1,"method":"textDocument/completion","jsonrpc":"2.0","params":{"textDocument":{"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"},"position":{"character":22,"line":13}}}
05:57:50 INFO     textDocument/didChange
05:57:50 DEBUG     => {"id":2,"method":"textDocument/completion","jsonrpc":"2.0","params":{"textDocument":{"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"},"position":{"character":22,"line":13}}}
05:57:50 DEBUG     <= {"jsonrpc":"2.0","id":1,"result":[{"label":"hash_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"hash_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"Bound","kind":13,"detail":"pub enum Bound<T> {"},{"label":"BinaryHeap","kind":7,"detail":"pub struct BinaryHeap<T>"},{"label":"BTreeMap","kind":7,"detail":"pub struct BTreeMap<K, V>"},{"label":"BTreeSet","kind":7,"detail":"pub struct BTreeSet<T>"},{"label":"LinkedList","kind":7,"detail":"pub struct LinkedList<T>"},{"label":"VecDeque","kind":7,"detail":"pub struct VecDeque<T>"},{"label":"binary_heap","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/binary_heap.rs"},{"label":"btree_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"btree_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"linked_list","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/linked_list.rs"},{"label":"vec_deque","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/vec_deque.rs"},{"label":"HashMap","kind":7,"detail":"pub struct HashMap<K, V, S = RandomState>"},{"label":"HashSet","kind":7,"detail":"pub struct HashSet<T, S = RandomState>"},{"label":"range","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/range.rs"}]}
05:57:50 DEBUG     <= {"jsonrpc":"2.0","id":2,"result":[{"label":"hash_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"hash_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"Bound","kind":13,"detail":"pub enum Bound<T> {"},{"label":"BinaryHeap","kind":7,"detail":"pub struct BinaryHeap<T>"},{"label":"BTreeMap","kind":7,"detail":"pub struct BTreeMap<K, V>"},{"label":"BTreeSet","kind":7,"detail":"pub struct BTreeSet<T>"},{"label":"LinkedList","kind":7,"detail":"pub struct LinkedList<T>"},{"label":"VecDeque","kind":7,"detail":"pub struct VecDeque<T>"},{"label":"binary_heap","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/binary_heap.rs"},{"label":"btree_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"btree_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"linked_list","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/linked_list.rs"},{"label":"vec_deque","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/vec_deque.rs"},{"label":"HashMap","kind":7,"detail":"pub struct HashMap<K, V, S = RandomState>"},{"label":"HashSet","kind":7,"detail":"pub struct HashSet<T, S = RandomState>"},{"label":"range","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/range.rs"}]}
05:57:50 INFO     textDocument/didChange
05:57:50 DEBUG     => {"method":"textDocument/didChange","jsonrpc":"2.0","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections::h\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":2,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
05:57:50 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
05:57:50 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:57:52 INFO     textDocument/didChange
05:57:52 DEBUG     => {"method":"textDocument/didChange","jsonrpc":"2.0","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections::\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":3,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
05:57:52 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
05:57:52 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:57:52 DEBUG     <= 
05:57:54 ERROR    Failed to start language server: [b'{"message":"expected identifier, found keyword `use`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":320,"byte_end":323,"line_start":15,"line_end":15,"column_start":1,"column_end":4,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":1,"highlight_end":4}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"expected one of `::`, `;`, or `as`, found `std`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":323,"byte_end":323,"line_start":15,"line_end":15,"column_start":4,"column_end":4,"is_primary":false,"text":[{"text":"use std::env;","highlight_start":4,"highlight_end":4}],"label":"expected one of `::`, `;`, or `as` here","suggested_replacement":null,"expansion":null},{"file_name":"src/main.rs","byte_start":324,"byte_end":327,"line_start":15,"line_end":15,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":5,"highlight_end":8}],"label":"unexpected token","suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"aborting due to 2 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":null}\n', b'thread \'<unnamed>\' panicked at \'could not run cargo: CargoError(Internal(Msg("failed to stat `/mnt/d/GIT/udpproxy/target/rls/debug/.fingerprint/udpproxy-9ca18b3406e94519/dep-bin-udpproxy-9ca18b3406e94519`")), State { next_error: Some(Error { repr: Os { code: 2, message: "No such file or directory" } }), backtrace: Some(stack backtrace:\n', b'   0:     0x7fd6e5aaac0c - backtrace::backtrace::trace::h31ca0a1f8bbf6ac2\n', b'   1:     0x7fd6e5aaad62 - backtrace::capture::Backtrace::new::hf6b7f1754ee14e12\n', b'   2:     0x7fd6e5846f34 - error_chain::make_backtrace::h441fcfb9da5c86ff\n', b'   3:     0x7fd6e5705182 - cargo::ops::cargo_rustc::fingerprint::Fingerprint::update_local::h9da3d2fdae79029c\n', b'   4:     0x7fd6e5711253 - <F as cargo::ops::cargo_rustc::job::FnBox<A, R>>::call_box::h37c2ff4b05819a4d\n', b'   5:     0x7fd6e570e6b1 - <F as cargo::ops::cargo_rustc::job::FnBox<A, R>>::call_box::h17263152bffd329c\n', b'   6:     0x7fd6e571c2d5 - cargo::ops::cargo_rustc::job_queue::JobQueue::run::{{closure}}::hb86f486459441f25\n', b'   7:     0x7fd6e55f3766 - <F as crossbeam::FnBox>::call_box::h37d6494a46c86b2b\n', b'   8:     0x7fd6e55f5f62 - std::panicking::try::do_call::h1ec7a40d5c9a3dbc\n', b'   9:     0x7fd6e34b570c - panic_unwind::__rust_maybe_catch_panic\n', b'                        at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  10:     0x7fd6e56350ab - <F as alloc::boxed::FnBox<A>>::call_box::hdf351144609fbaa2\n', b'  11:     0x7fd6e3484bfb - alloc::boxed::{{impl}}::call_once<(),()>\n', b'                        at /checkout/src/liballoc/boxed.rs:692\n', b'                         - std::sys_common::thread::start_thread\n', b'                        at /checkout/src/libstd/sys_common/thread.rs:21\n', b'                         - std::sys::imp::thread::{{impl}}::new::thread_start\n', b'                        at /checkout/src/libstd/sys/unix/thread.rs:84\n', b'  12:     0x7fd6e2db76b9 - start_thread\n', b'  13:     0x7fd6e25b73dc - clone\n', b"  14:                0x0 - <unknown>) })', /checkout/src/libcore/result.rs:860:4\n", b'stack backtrace:\n', b'   0:     0x7fd6e34784d3 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hd639a7f6daa6ea13\n', b'                               at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49\n', b'   1:     0x7fd6e3472c74 - std::sys_common::backtrace::_print::hb50ac545893876ff\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:71\n', b'   2:     0x7fd6e3485cc3 - std::panicking::default_hook::{{closure}}::hecaa7fb15d8f3afa\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:60\n', b'                               at /checkout/src/libstd/panicking.rs:381\n', b'   3:     0x7fd6e3485a22 - std::panicking::default_hook::h3069832862588f27\n', b'                               at /checkout/src/libstd/panicking.rs:397\n', b'   4:     0x7fd6e34861c7 - std::panicking::rust_panic_with_hook::h433501d327eb5ed9\n', b'                               at /checkout/src/libstd/panicking.rs:611\n', b'   5:     0x7fd6e3486024 - std::panicking::begin_panic::h2c8c099fbcad29db\n', b'                               at /checkout/src/libstd/panicking.rs:572\n', b'   6:     0x7fd6e3485f99 - std::panicking::begin_panic_fmt::h821787127b4b95c2\n', b'                               at /checkout/src/libstd/panicking.rs:522\n', b'   7:     0x7fd6e3485f2a - rust_begin_unwind\n', b'                               at /checkout/src/libstd/panicking.rs:498\n', b'   8:     0x7fd6e34c6670 - core::panicking::panic_fmt::h56d9d605a1f3f3aa\n', b'                               at /checkout/src/libcore/panicking.rs:71\n', b'   9:     0x7fd6e5505925 - core::result::unwrap_failed::hb546e44765872d83\n', b'  10:     0x7fd6e55680ec - rls::build::cargo::run_cargo::hdb588f0ff6849e7b\n', b'  11:     0x7fd6e54bbf27 - std::sys_common::backtrace::__rust_begin_short_backtrace::h2d6b9de92f010cf2\n', b'  12:     0x7fd6e54c28ed - std::panicking::try::do_call::hce8396101e8cf8c1\n', b'  13:     0x7fd6e34b570c - __rust_maybe_catch_panic\n', b'                               at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  14:     0x7fd6e5508687 - <F as alloc::boxed::FnBox<A>>::call_box::h8066611131b038e8\n', b'  15:     0x7fd6e3484bfb - std::sys::imp::thread::Thread::new::thread_start::h511fdbf2f5a927dc\n', b'                               at /checkout/src/liballoc/boxed.rs:692\n', b'                               at /checkout/src/libstd/sys_common/thread.rs:21\n', b'                               at /checkout/src/libstd/sys/unix/thread.rs:84\n', b'  16:     0x7fd6e2db76b9 - start_thread\n', b'  17:     0x7fd6e25b73dc - clone\n', b'  18:                0x0 - <unknown>\n', b'thread \'<unnamed>\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n', b'stack backtrace:\n', b'   0:     0x7fd6e34784d3 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hd639a7f6daa6ea13\n', b'                               at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49\n', b'   1:     0x7fd6e3472c74 - std::sys_common::backtrace::_print::hb50ac545893876ff\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:71\n', b'   2:     0x7fd6e3485cc3 - std::panicking::default_hook::{{closure}}::hecaa7fb15d8f3afa\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:60\n', b'                               at /checkout/src/libstd/panicking.rs:381\n', b'   3:     0x7fd6e3485a22 - std::panicking::default_hook::h3069832862588f27\n', b'                               at /checkout/src/libstd/panicking.rs:397\n', b'   4:     0x7fd6e34861c7 - std::panicking::rust_panic_with_hook::h433501d327eb5ed9\n', b'                               at /checkout/src/libstd/panicking.rs:611\n', b'   5:     0x7fd6e3486024 - std::panicking::begin_panic::h2c8c099fbcad29db\n', b'                               at /checkout/src/libstd/panicking.rs:572\n', b'   6:     0x7fd6e3485f99 - std::panicking::begin_panic_fmt::h821787127b4b95c2\n', b'                               at /checkout/src/libstd/panicking.rs:522\n', b'   7:     0x7fd6e3485f2a - rust_begin_unwind\n', b'                               at /checkout/src/libstd/panicking.rs:498\n', b'   8:     0x7fd6e34c6670 - core::panicking::panic_fmt::h56d9d605a1f3f3aa\n', b'                               at /checkout/src/libcore/panicking.rs:71\n', b'   9:     0x7fd6e55055bf - core::result::unwrap_failed::h865b754f0bd183b6\n', b'  10:     0x7fd6e5563a09 - rls::build::environment::EnvironmentLock::lock::hf1d6176cd121e169\n', b'  11:     0x7fd6e556dace - rls::build::rustc::rustc::hae2f7267876dbd23\n', b'  12:     0x7fd6e5574fea - rls::build::BuildQueue::run_thread::h2f359e5e05b1cdf5\n', b'  13:     0x7fd6e54bb286 - std::sys_common::backtrace::__rust_begin_short_backtrace::h0c710f4cb1c48eb5\n', b'  14:     0x7fd6e54c1f92 - std::panicking::try::do_call::h929a59eea8dab156\n', b'  15:     0x7fd6e34b570c - __rust_maybe_catch_panic\n', b'                               at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  16:     0x7fd6e550a66b - <F as alloc::boxed::FnBox<A>>::call_box::he20ace87c7de2cb8\n', b'  17:     0x7fd6e3484bfb - std::sys::imp::thread::Thread::new::thread_start::h511fdbf2f5a927dc\n', b'                               at /checkout/src/liballoc/boxed.rs:692\n', b'                               at /checkout/src/libstd/sys_common/thread.rs:21\n', b'                               at /checkout/src/libstd/sys/unix/thread.rs:84\n', b'  18:     0x7fd6e2db76b9 - start_thread\n', b'  19:     0x7fd6e25b73dc - clone\n', b'  20:                0x0 - <unknown>\n', b'thread \'main\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n', b'stack backtrace:\n', b'   0:     0x7fd6e34784d3 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hd639a7f6daa6ea13\n', b'                               at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49\n', b'   1:     0x7fd6e3472c74 - std::sys_common::backtrace::_print::hb50ac545893876ff\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:71\n', b'   2:     0x7fd6e3485cc3 - std::panicking::default_hook::{{closure}}::hecaa7fb15d8f3afa\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:60\n', b'                               at /checkout/src/libstd/panicking.rs:381\n', b'   3:     0x7fd6e3485a22 - std::panicking::default_hook::h3069832862588f27\n', b'                               at /checkout/src/libstd/panicking.rs:397\n', b'   4:     0x7fd6e34861c7 - std::panicking::rust_panic_with_hook::h433501d327eb5ed9\n', b'                               at /checkout/src/libstd/panicking.rs:611\n', b'   5:     0x7fd6e3486024 - std::panicking::begin_panic::h2c8c099fbcad29db\n', b'                               at /checkout/src/libstd/panicking.rs:572\n', b'   6:     0x7fd6e3485f99 - std::panicking::begin_panic_fmt::h821787127b4b95c2\n', b'                               at /checkout/src/libstd/panicking.rs:522\n', b'   7:     0x7fd6e3485f2a - rust_begin_unwind\n', b'                               at /checkout/src/libstd/panicking.rs:498\n', b'   8:     0x7fd6e34c6670 - core::panicking::panic_fmt::h56d9d605a1f3f3aa\n', b'                               at /checkout/src/libcore/panicking.rs:71\n', b'   9:     0x7fd6e5505d2f - core::result::unwrap_failed::hdf9f8b71caf03662\n', b'  10:     0x7fd6e555f595 - rls::actions::ActionHandler::build_current_project::hff9fc2b3ffb1b287\n', b'  11:     0x7fd6e557c4c9 - <rls::server::LsService<O>>::handle_message::h63a690a9a5b47e49\n', b'  12:     0x7fd6e559aa07 - rls::main::hdf6c5fc0223a5ecd\n', b'  13:     0x7fd6e34b570c - __rust_maybe_catch_panic\n', b'                               at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  14:     0x7fd6e348702b - std::rt::lang_start::h0ffd459081119e40\n', b'                               at /checkout/src/libstd/panicking.rs:459\n', b'                               at /checkout/src/libstd/panic.rs:361\n', b'                               at /checkout/src/libstd/rt.rs:61\n', b'  15:     0x7fd6e24d082f - __libc_start_main\n', b'  16:     0x7fd6e548be70 - <unknown>\n']
05:57:54 ERROR    Failed to start language server: []
05:57:55 ERROR    Failed to start language server: []
05:57:55 ERROR    Failed to start language server: []
05:57:58 ERROR    Failed to start language server: []
05:57:58 ERROR    Failed to start language server: []
05:57:58 ERROR    Failed to start language server: []
05:57:59 ERROR    Failed to start language server: []
05:58:00 ERROR    Failed to start language server: []
05:58:01 ERROR    Failed to start language server: []
05:58:02 ERROR    Failed to start language server: []
05:58:03 ERROR    Failed to start language server: []
05:58:03 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:07 ERROR    Failed to start language server: []
05:58:13 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:58:13 WARNING  register completion manager source failed. Error: NvimError(b'Error calling function.',)

It seems to be fully reproducible based off the completions that my navigation in the code are triggering.

@mqudsi
Copy link
Author

mqudsi commented Aug 16, 2017

OK, it seems that cargo clean may not be very thorough. rm -rf target seems to have done the trick.

I have the strace output, if it's worth anything to you, from the failed RLS runs (attached).

strace.txt

@vorner
Copy link

vorner commented Aug 17, 2017

Hello.

I'm getting the same or very similar problem now, since I updated this morning. I'm not sure this is exactly the same problem, but it seems to act in the same way. Few things of note:

  • The code I open can't be compiled now (I left yesterday in a hurry in the middle of some refactoring and opened it on another computer after updating rustc, rls and everything). If anyone is interesting in trying it themselves, I put the code into a separate branch and will leave it there for now: https://gitlab.labs.nic.cz/turris/pakon-aggregator/tree/slice-time-broken-rls
  • It is started with removed target directory, so it starts clean.
  • It crashes even without any interaction from my side, just when trying to examine the sources at startup (only the initialize and textDocument/did Open methods were sent to it). I tried multiple times.
  • When I first switch to a branch that compiles, open a file and let it crunch, than back to this one that doesn't compile, the crash disappears. The fact that there are some artifacts/caches from a successful analysis make the crash go away.
  • I don't know if it is related, but it is a lib+bin crate. I open a file in the lib (src/flow/slice.rs, if someone wants to try the exact same scenario). The logs also contain about not being able to find the aggregator crate (the lib of the project), so it may be trying to compile the bin in parallel when the lib is not there. But that's just a wild guess.

I have a log output of rls itself (I can re-run it with something more verbose than info):

rls.log.txt

The error is similar to this one too, but it happens with CARGO_INCREMENTAL=0, so maybe it's related but maybe it isn't: #425.

And yes, this is the same project as in #440.

Is this the same problem? Or, should I open a different issue? Can I help debugging it somehow? While I know close to nothing about how rls works internally, I might try some debugging (but some hints or suggestions what to check and see would really help).

Thank you

@nrc nrc added the bug label Aug 17, 2017
@jTitor
Copy link

jTitor commented Aug 21, 2017

@vorner The error is due to Cargo assuming that a nonexistent fingerprint for an artifact is a fatal error for its build tasks; when a library project fails to build, its result artifact naturally won't exist, and when the bin references that nonexistent artifact Cargo then panics. Which it should, I can't think of what else would be a suitable response.

The problem is that RLS quits or crashes because of this. It needs to note the failure but continue operating as if that were another error causing the build to fail. I'll keep looking into it.

@nrc nrc changed the title Result::unwrap exception leading to PoisonError Failing to build the lib portion of a project crashes the RLS on the bin portion Aug 21, 2017
@Xanewok
Copy link
Member

Xanewok commented Aug 21, 2017

Now that I think about it, maybe when running rustc via cmd.exec() we should Err out like here instead, so the compilation stops there?

@vorner
Copy link

vorner commented Aug 21, 2017

@jTitor I'm not sure about that.

First, I didn't open a file in the bin, but in the lib. So why did RLS even touch that bin part?

The other thing is, the logs in #440 also contain errors with missing fingerprints. However, the code compiles correctly and RLS does not crash (it just doesn't provide all the functionality). So I don't know if that deduction goes a bit too far.

Anyway, as I said, I have no real idea what happens inside RLS, just that the fingerprint error leads to the crash only sometimes.

@nrc
Copy link
Member

nrc commented Oct 30, 2017

cc #132

@nrc
Copy link
Member

nrc commented Jun 21, 2018

This is fixed now.

@nrc nrc closed this as completed Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants