From d56c2f24252d5d444267e33950825f0a7cb438ca Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Mar 2019 16:05:49 +0300 Subject: explain how to launch the thing --- docs/dev/DEBUGGING.md | 62 --------------- docs/dev/README.md | 81 +++++++++++++++++++ docs/dev/architecture.md | 174 +++++++++++++++++++++++++++++++++++++++++ docs/dev/arhictecture.md | 200 ----------------------------------------------- docs/dev/debugging.md | 62 +++++++++++++++ 5 files changed, 317 insertions(+), 262 deletions(-) delete mode 100644 docs/dev/DEBUGGING.md create mode 100644 docs/dev/architecture.md delete mode 100644 docs/dev/arhictecture.md create mode 100644 docs/dev/debugging.md diff --git a/docs/dev/DEBUGGING.md b/docs/dev/DEBUGGING.md deleted file mode 100644 index f868e6998..000000000 --- a/docs/dev/DEBUGGING.md +++ /dev/null @@ -1,62 +0,0 @@ -# Debugging vs Code plugin and the Language Server - -Install [LLDB](https://lldb.llvm.org/) and the [LLDB Extension](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb). - -Checkout rust rust-analyzer and open it in vscode. - -``` -$ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 -$ cd rust-analyzer -$ code . -``` - -- To attach to the `lsp server` in linux you'll have to run: - - `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` - - This enables ptrace on non forked processes - -- Ensure the dependencies for the extension are installed, run the `npm: install - editors/code` task in vscode. - -- Launch the `Debug Extension`, this will build the extension and the `lsp server`. - -- A new instance of vscode with `[Extension Development Host]` in the title. - - Don't worry about disabling `rls` all other extensions will be disabled but this one. - -- In the new vscode instance open a rust project, and navigate to a rust file - -- In the original vscode start an additional debug session (the three periods in the launch) and select `Debug Lsp Server`. - -- A list of running processes should appear select the `ra_lsp_server` from this repo. - -- Navigate to `crates/ra_lsp_server/src/main_loop.rs` and add a breakpoint to the `on_task` function. - -- Go back to the `[Extension Development Host]` instance and hover over a rust variable and your breakpoint should hit. - -## Demo - -![demonstration of debugging](https://user-images.githubusercontent.com/1711539/51384036-254fab80-1b2c-11e9-824d-95f9a6e9cf4f.gif) - -## Troubleshooting - -### Can't find the `ra_lsp_server` process - -It could be a case of just jumping the gun. - -The `ra_lsp_server` is only started once the `onLanguage:rust` activation. - -Make sure you open a rust file in the `[Extension Development Host]` and try again. - -### Can't connect to `ra_lsp_server` - -Make sure you have run `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope`. - -By default this should reset back to 1 everytime you log in. - -### Breakpoints are never being hit - -Check your version of `lldb` if it's version 6 and lower use the `classic` adapter type. -It's `lldb.adapterType` in settings file. - -If you're running `lldb` version 7 change the lldb adapter type to `bundled` or `native`. diff --git a/docs/dev/README.md b/docs/dev/README.md index 0c09dddfc..ac7f4fd71 100644 --- a/docs/dev/README.md +++ b/docs/dev/README.md @@ -41,3 +41,84 @@ We use Travis for CI. Most of the things, including formatting, are checked by `cargo test` so, if `cargo test` passes locally, that's a good sign that CI will be green as well. We use bors-ng to enforce the [not rocket science](https://graydon2.dreamwidth.org/1597.html) rule. + +You can run `cargo format-hook` to install git-hook to run rustfmt on commit. + +# Code organization + +All Rust code lives in the `crates` top-level directory, and is organized as a +single Cargo workspace. The `editors` top-level directory contains code for +integrating with editors. Currently, it contains plugins for VS Code (in +typescript) and Emacs (in elisp). The `docs` top-level directory contains both +developer and user documentation. + +We have some automation infra in Rust in the `crates/tool` package. It contains +stuff like formatting checking, code generation and powers `cargo install-code`. +The latter syntax is achieved with the help of cargo aliases (see `.cargo` +directory). + +# Launching rust-analyzer + +Debugging language server can be tricky: LSP is rather chatty, so driving it +from the command line is not really feasible, driving it via VS Code requires +interacting with two processes. + +For this reason, the best way to see how rust-analyzer works is to find a +relevant test and execute it (VS Code includes an action for running a single +test). + +However, launching a VS Code instance with locally build language server is +possible. There's even a VS Code task for this, so just F5 should +work (thanks, [@andrew-w-ross](https://github.com/andrew-w-ross)!). + +I often just install development version with `cargo jinstall-lsp` and +restart the host VS Code. + +See [./debugging.md](./debugging.md) for how to attach to rust-analyzer with +debugger, and don't forget that rust-analyzer has useful `pd` snippet and `dbg` +postfix completion for printf debugging :-) + +# Working With VS Code Extension + +To work on the VS Code extension, launch code inside `editors/code` and use `F5` +to launch/debug. To automatically apply formatter and linter suggestions, use +`npm run fix`. + +# Logging + +Logging is done by both rust-analyzer and VS Code, so it might be tricky to +figure out where logs go. + +Inside rust-analyzer, we use the standard `log` crate for logging, and +`flexi_logger` for logging frotend. By default, log goes to stderr (the same as +with `env_logger`), but the stderr itself is processed by VS Code. To mirror +logs to a `./log` directory, set `RA_INTERNAL_MODE=1` environmental variable. + +To see stderr in the running VS Code instance, go to the "Output" tab of the +panel and select `rust-analyzer`. This shows `eprintln!` as well. Note that +`stdout` is used for the actual protocol, so `println!` will break things. + +To log all communication between the server and the client, there are two choices: + +* you can log on the server side, by running something like + ``` + env RUST_LOG=gen_lsp_server=trace code . + ``` + +* you can log on the client side, by enabling `"rust-analyzer.trace.server": + "verbose"` workspace setting. These logs are shown in a separate tab in the + output and could be used with LSP inspector. Kudos to + [@DJMcNab](https://github.com/DJMcNab) for setting this awesome infra up! + + +There's also two VS Code commands which might be of interest: + +* `Rust Analyzer: Status` shows some memory-usage statistics. To take full + advantage of it, you need to compile rust-analyzer with jemalloc support: + ``` + $ cargo install --path crates/ra_lsp_server --force --features jemalloc + ``` + + There's an alias for this: `cargo jinstall-lsp`. + +* `Rust Analyzer: Syntax Tree` shows syntax tree of the current file/selection. diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md new file mode 100644 index 000000000..3cd63bf73 --- /dev/null +++ b/docs/dev/architecture.md @@ -0,0 +1,174 @@ +# Architecture + +This document describes the high-level architecture of rust-analyzer. +If you want to familiarize yourself with the code base, you are just +in the right place! + +See also the [guide](./guide.md), which walks through a particular snapshot of +rust-analyzer code base. + +Yet another resource is this playlist with videos about various parts of the +analyzer: + +https://www.youtube.com/playlist?list=PL85XCvVPmGQho7MZkdW-wtPtuJcFpzycE + +## The Big Picture + +![](https://user-images.githubusercontent.com/1711539/50114578-e8a34280-0255-11e9-902c-7cfc70747966.png) + +On the highest level, rust-analyzer is a thing which accepts input source code +from the client and produces a structured semantic model of the code. + +More specifically, input data consists of a set of test files (`(PathBuf, +String)` pairs) and information about project structure, captured in the so called +`CrateGraph`. The crate graph specifies which files are crate roots, which cfg +flags are specified for each crate (TODO: actually implement this) and what +dependencies exist between the crates. The analyzer keeps all this input data in +memory and never does any IO. Because the input data is source code, which +typically measures in tens of megabytes at most, keeping all input data in +memory is OK. + +A "structured semantic model" is basically an object-oriented representation of +modules, functions and types which appear in the source code. This representation +is fully "resolved": all expressions have types, all references are bound to +declarations, etc. + +The client can submit a small delta of input data (typically, a change to a +single file) and get a fresh code model which accounts for changes. + +The underlying engine makes sure that model is computed lazily (on-demand) and +can be quickly updated for small modifications. + + +## Code generation + +Some of the components of this repository are generated through automatic +processes. These are outlined below: + +- `gen-syntax`: The kinds of tokens that are reused in several places, so a generator + is used. We use tera templates to generate the files listed below, based on + the grammar described in [grammar.ron]: + - [ast/generated.rs][ast generated] in `ra_syntax` based on + [ast/generated.tera.rs][ast source] + - [syntax_kinds/generated.rs][syntax_kinds generated] in `ra_syntax` based on + [syntax_kinds/generated.tera.rs][syntax_kinds source] + +[tera]: https://tera.netlify.com/ +[grammar.ron]: ./crates/ra_syntax/src/grammar.ron +[ast generated]: ./crates/ra_syntax/src/ast/generated.rs +[ast source]: ./crates/ra_syntax/src/ast/generated.rs.tera +[syntax_kinds generated]: ./crates/ra_syntax/src/syntax_kinds/generated.rs +[syntax_kinds source]: ./crates/ra_syntax/src/syntax_kinds/generated.rs.tera + + +## Code Walk-Through + +### `crates/ra_syntax`, `crates/ra_parser` + +Rust syntax tree structure and parser. See +[RFC](https://github.com/rust-lang/rfcs/pull/2256) for some design notes. + +- [rowan](https://github.com/rust-analyzer/rowan) library is used for constructing syntax trees. +- `grammar` module is the actual parser. It is a hand-written recursive descent parser, which + produces a sequence of events like "start node X", "finish not Y". It works similarly to [kotlin's parser](https://github.com/JetBrains/kotlin/blob/4d951de616b20feca92f3e9cc9679b2de9e65195/compiler/frontend/src/org/jetbrains/kotlin/parsing/KotlinParsing.java), + which is a good source of inspiration for dealing with syntax errors and incomplete input. Original [libsyntax parser](https://github.com/rust-lang/rust/blob/6b99adeb11313197f409b4f7c4083c2ceca8a4fe/src/libsyntax/parse/parser.rs) + is what we use for the definition of the Rust language. +- `parser_api/parser_impl` bridges the tree-agnostic parser from `grammar` with `rowan` trees. + This is the thing that turns a flat list of events into a tree (see `EventProcessor`) +- `ast` provides a type safe API on top of the raw `rowan` tree. +- `grammar.ron` RON description of the grammar, which is used to + generate `syntax_kinds` and `ast` modules, using `cargo gen-syntax` command. +- `algo`: generic tree algorithms, including `walk` for O(1) stack + space tree traversal (this is cool) and `visit` for type-driven + visiting the nodes (this is double plus cool, if you understand how + `Visitor` works, you understand the design of syntax trees). + +Tests for ra_syntax are mostly data-driven: `tests/data/parser` contains a bunch of `.rs` +(test vectors) and `.txt` files with corresponding syntax trees. During testing, we check +`.rs` against `.txt`. If the `.txt` file is missing, it is created (this is how you update +tests). Additionally, running `cargo gen-tests` will walk the grammar module and collect +all `//test test_name` comments into files inside `tests/data` directory. + +See [#93](https://github.com/rust-analyzer/rust-analyzer/pull/93) for an example PR which +fixes a bug in the grammar. + +### `crates/ra_db` + +We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and +on-demand computation. Roughly, you can think of salsa as a key-value store, but +it also can compute derived values using specified functions. The `ra_db` crate +provides basic infrastructure for interacting with salsa. Crucially, it +defines most of the "input" queries: facts supplied by the client of the +analyzer. Reading the docs of the `ra_db::input` module should be useful: +everything else is strictly derived from those inputs. + +### `crates/ra_hir` + +HIR provides high-level "object oriented" access to Rust code. + +The principal difference between HIR and syntax trees is that HIR is bound to a +particular crate instance. That is, it has cfg flags and features applied (in +theory, in practice this is to be implemented). So, the relation between +syntax and HIR is many-to-one. The `source_binder` module is responsible for +guessing a HIR for a particular source position. + +Underneath, HIR works on top of salsa, using a `HirDatabase` trait. + +### `crates/ra_ide_api` + +A stateful library for analyzing many Rust files as they change. `AnalysisHost` +is a mutable entity (clojure's atom) which holds the current state, incorporates +changes and hands out `Analysis` --- an immutable and consistent snapshot of +the world state at a point in time, which actually powers analysis. + +One interesting aspect of analysis is its support for cancellation. When a +change is applied to `AnalysisHost`, first all currently active snapshots are +canceled. Only after all snapshots are dropped the change actually affects the +database. + +APIs in this crate are IDE centric: they take text offsets as input and produce +offsets and strings as output. This works on top of rich code model powered by +`hir`. + +### `crates/ra_ide_api_light` + +All IDE features which can be implemented if you only have access to a single +file. `ra_ide_api_light` could be used to enhance editing of Rust code without +the need to fiddle with build-systems, file synchronization and such. + +In a sense, `ra_ide_api_light` is just a bunch of pure functions which take a +syntax tree as input. + +The tests for `ra_ide_api_light` are `#[cfg(test)] mod tests` unit-tests spread +throughout its modules. + + +### `crates/ra_lsp_server` + +An LSP implementation which wraps `ra_ide_api` into a langauge server protocol. + +### `ra_vfs` + +Although `hir` and `ra_ide_api` don't do any IO, we need to be able to read +files from disk at the end of the day. This is what `ra_vfs` does. It also +manages overlays: "dirty" files in the editor, whose "true" contents is +different from data on disk. This is more or less the single really +platform-dependent component, so it lives in a separate repository and has an +extensive cross-platform CI testing. + +### `crates/gen_lsp_server` + +A language server scaffold, exposing a synchronous crossbeam-channel based API. +This crate handles protocol handshaking and parsing messages, while you +control the message dispatch loop yourself. + +Run with `RUST_LOG=sync_lsp_server=debug` to see all the messages. + +### `crates/ra_cli` + +A CLI interface to rust-analyzer. + + +## Testing Infrastructure + + diff --git a/docs/dev/arhictecture.md b/docs/dev/arhictecture.md deleted file mode 100644 index 57f76ebae..000000000 --- a/docs/dev/arhictecture.md +++ /dev/null @@ -1,200 +0,0 @@ -# Architecture - -This document describes the high-level architecture of rust-analyzer. -If you want to familiarize yourself with the code base, you are just -in the right place! - -See also the [guide](./guide.md), which walks through a particular snapshot of -rust-analyzer code base. - -For syntax-trees specifically, there's a [video walk -through](https://youtu.be/DGAuLWdCCAI) as well. - -## The Big Picture - -![](https://user-images.githubusercontent.com/1711539/50114578-e8a34280-0255-11e9-902c-7cfc70747966.png) - -On the highest level, rust-analyzer is a thing which accepts input source code -from the client and produces a structured semantic model of the code. - -More specifically, input data consists of a set of test files (`(PathBuf, -String)` pairs) and information about project structure, captured in the so called -`CrateGraph`. The crate graph specifies which files are crate roots, which cfg -flags are specified for each crate (TODO: actually implement this) and what -dependencies exist between the crates. The analyzer keeps all this input data in -memory and never does any IO. Because the input data is source code, which -typically measures in tens of megabytes at most, keeping all input data in -memory is OK. - -A "structured semantic model" is basically an object-oriented representation of -modules, functions and types which appear in the source code. This representation -is fully "resolved": all expressions have types, all references are bound to -declarations, etc. - -The client can submit a small delta of input data (typically, a change to a -single file) and get a fresh code model which accounts for changes. - -The underlying engine makes sure that model is computed lazily (on-demand) and -can be quickly updated for small modifications. - - -## Code generation - -Some of the components of this repository are generated through automatic -processes. These are outlined below: - -- `gen-syntax`: The kinds of tokens that are reused in several places, so a generator - is used. We use tera templates to generate the files listed below, based on - the grammar described in [grammar.ron]: - - [ast/generated.rs][ast generated] in `ra_syntax` based on - [ast/generated.tera.rs][ast source] - - [syntax_kinds/generated.rs][syntax_kinds generated] in `ra_syntax` based on - [syntax_kinds/generated.tera.rs][syntax_kinds source] - -[tera]: https://tera.netlify.com/ -[grammar.ron]: ./crates/ra_syntax/src/grammar.ron -[ast generated]: ./crates/ra_syntax/src/ast/generated.rs -[ast source]: ./crates/ra_syntax/src/ast/generated.rs.tera -[syntax_kinds generated]: ./crates/ra_syntax/src/syntax_kinds/generated.rs -[syntax_kinds source]: ./crates/ra_syntax/src/syntax_kinds/generated.rs.tera - - -## Code Walk-Through - -### `crates/ra_syntax` - -Rust syntax tree structure and parser. See -[RFC](https://github.com/rust-lang/rfcs/pull/2256) for some design notes. - -- [rowan](https://github.com/rust-analyzer/rowan) library is used for constructing syntax trees. -- `grammar` module is the actual parser. It is a hand-written recursive descent parser, which - produces a sequence of events like "start node X", "finish not Y". It works similarly to [kotlin's parser](https://github.com/JetBrains/kotlin/blob/4d951de616b20feca92f3e9cc9679b2de9e65195/compiler/frontend/src/org/jetbrains/kotlin/parsing/KotlinParsing.java), - which is a good source of inspiration for dealing with syntax errors and incomplete input. Original [libsyntax parser](https://github.com/rust-lang/rust/blob/6b99adeb11313197f409b4f7c4083c2ceca8a4fe/src/libsyntax/parse/parser.rs) - is what we use for the definition of the Rust language. -- `parser_api/parser_impl` bridges the tree-agnostic parser from `grammar` with `rowan` trees. - This is the thing that turns a flat list of events into a tree (see `EventProcessor`) -- `ast` provides a type safe API on top of the raw `rowan` tree. -- `grammar.ron` RON description of the grammar, which is used to - generate `syntax_kinds` and `ast` modules, using `cargo gen-syntax` command. -- `algo`: generic tree algorithms, including `walk` for O(1) stack - space tree traversal (this is cool) and `visit` for type-driven - visiting the nodes (this is double plus cool, if you understand how - `Visitor` works, you understand the design of syntax trees). - -Tests for ra_syntax are mostly data-driven: `tests/data/parser` contains a bunch of `.rs` -(test vectors) and `.txt` files with corresponding syntax trees. During testing, we check -`.rs` against `.txt`. If the `.txt` file is missing, it is created (this is how you update -tests). Additionally, running `cargo gen-tests` will walk the grammar module and collect -all `//test test_name` comments into files inside `tests/data` directory. - -See [#93](https://github.com/rust-analyzer/rust-analyzer/pull/93) for an example PR which -fixes a bug in the grammar. - -### `crates/ra_db` - -We use the [salsa](https://github.com/salsa-rs/salsa) crate for incremental and -on-demand computation. Roughly, you can think of salsa as a key-value store, but -it also can compute derived values using specified functions. The `ra_db` crate -provides basic infrastructure for interacting with salsa. Crucially, it -defines most of the "input" queries: facts supplied by the client of the -analyzer. Reading the docs of the `ra_db::input` module should be useful: -everything else is strictly derived from those inputs. - -### `crates/ra_hir` - -HIR provides high-level "object oriented" access to Rust code. - -The principal difference between HIR and syntax trees is that HIR is bound to a -particular crate instance. That is, it has cfg flags and features applied (in -theory, in practice this is to be implemented). So, the relation between -syntax and HIR is many-to-one. The `source_binder` module is responsible for -guessing a HIR for a particular source position. - -Underneath, HIR works on top of salsa, using a `HirDatabase` trait. - -### `crates/ra_ide_api` - -A stateful library for analyzing many Rust files as they change. `AnalysisHost` -is a mutable entity (clojure's atom) which holds the current state, incorporates -changes and hands out `Analysis` --- an immutable and consistent snapshot of -the world state at a point in time, which actually powers analysis. - -One interesting aspect of analysis is its support for cancellation. When a -change is applied to `AnalysisHost`, first all currently active snapshots are -canceled. Only after all snapshots are dropped the change actually affects the -database. - -APIs in this crate are IDE centric: they take text offsets as input and produce -offsets and strings as output. This works on top of rich code model powered by -`hir`. - -### `crates/ra_ide_api_light` - -All IDE features which can be implemented if you only have access to a single -file. `ra_ide_api_light` could be used to enhance editing of Rust code without -the need to fiddle with build-systems, file synchronization and such. - -In a sense, `ra_ide_api_light` is just a bunch of pure functions which take a -syntax tree as input. - -The tests for `ra_ide_api_light` are `#[cfg(test)] mod tests` unit-tests spread -throughout its modules. - - -### `crates/ra_lsp_server` - -An LSP implementation which wraps `ra_ide_api` into a langauge server protocol. - -### `crates/ra_vfs` - -Although `hir` and `ra_ide_api` don't do any IO, we need to be able to read -files from disk at the end of the day. This is what `ra_vfs` does. It also -manages overlays: "dirty" files in the editor, whose "true" contents is -different from data on disk. - -### `crates/gen_lsp_server` - -A language server scaffold, exposing a synchronous crossbeam-channel based API. -This crate handles protocol handshaking and parsing messages, while you -control the message dispatch loop yourself. - -Run with `RUST_LOG=sync_lsp_server=debug` to see all the messages. - -### `crates/ra_cli` - -A CLI interface to rust-analyzer. - -### `crate/tools` - -Custom Cargo tasks used to develop rust-analyzer: - -- `cargo gen-syntax` -- generate `ast` and `syntax_kinds` -- `cargo gen-tests` -- collect inline tests from grammar -- `cargo install-code` -- build and install VS Code extension and server - -### `editors/code` - -VS Code plugin - - -## Common workflows - -To try out VS Code extensions, run `cargo install-code`. This installs both the -`ra_lsp_server` binary and the VS Code extension. To install only the binary, use -`cargo install-lsp` (shorthand for `cargo install --path crates/ra_lsp_server --force`) - -To see logs from the language server, set `RUST_LOG=info` env variable. To see -all communication between the server and the client, use -`RUST_LOG=gen_lsp_server=debug` (this will print quite a bit of stuff). - -There's `rust-analyzer: status` command which prints common high-level debug -info. In particular, it prints info about memory usage of various data -structures, and, if compiled with jemalloc support (`cargo jinstall-lsp` or -`cargo install --path crates/ra_lsp_server --force --features jemalloc`), includes - statistic about the heap. - -To run tests, just `cargo test`. - -To work on the VS Code extension, launch code inside `editors/code` and use `F5` to -launch/debug. To automatically apply formatter and linter suggestions, use `npm -run fix`. diff --git a/docs/dev/debugging.md b/docs/dev/debugging.md new file mode 100644 index 000000000..f868e6998 --- /dev/null +++ b/docs/dev/debugging.md @@ -0,0 +1,62 @@ +# Debugging vs Code plugin and the Language Server + +Install [LLDB](https://lldb.llvm.org/) and the [LLDB Extension](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb). + +Checkout rust rust-analyzer and open it in vscode. + +``` +$ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 +$ cd rust-analyzer +$ code . +``` + +- To attach to the `lsp server` in linux you'll have to run: + + `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` + + This enables ptrace on non forked processes + +- Ensure the dependencies for the extension are installed, run the `npm: install - editors/code` task in vscode. + +- Launch the `Debug Extension`, this will build the extension and the `lsp server`. + +- A new instance of vscode with `[Extension Development Host]` in the title. + + Don't worry about disabling `rls` all other extensions will be disabled but this one. + +- In the new vscode instance open a rust project, and navigate to a rust file + +- In the original vscode start an additional debug session (the three periods in the launch) and select `Debug Lsp Server`. + +- A list of running processes should appear select the `ra_lsp_server` from this repo. + +- Navigate to `crates/ra_lsp_server/src/main_loop.rs` and add a breakpoint to the `on_task` function. + +- Go back to the `[Extension Development Host]` instance and hover over a rust variable and your breakpoint should hit. + +## Demo + +![demonstration of debugging](https://user-images.githubusercontent.com/1711539/51384036-254fab80-1b2c-11e9-824d-95f9a6e9cf4f.gif) + +## Troubleshooting + +### Can't find the `ra_lsp_server` process + +It could be a case of just jumping the gun. + +The `ra_lsp_server` is only started once the `onLanguage:rust` activation. + +Make sure you open a rust file in the `[Extension Development Host]` and try again. + +### Can't connect to `ra_lsp_server` + +Make sure you have run `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope`. + +By default this should reset back to 1 everytime you log in. + +### Breakpoints are never being hit + +Check your version of `lldb` if it's version 6 and lower use the `classic` adapter type. +It's `lldb.adapterType` in settings file. + +If you're running `lldb` version 7 change the lldb adapter type to `bundled` or `native`. -- cgit v1.2.3