Skip to content

Commit

Permalink
feature: add async backtrace, async backtrace all and `async task…
Browse files Browse the repository at this point in the history
…` commands (close #27)
  • Loading branch information
godzie44 committed Oct 24, 2024
1 parent 4e6a2f8 commit ac1de66
Show file tree
Hide file tree
Showing 42 changed files with 1,826 additions and 83 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* [Examining the stack](#examining-the-stack)
* [Examining source files](#examining-source-files)
* [Examining data](#examining-data)
* [Async rust](#async-rust)
* [Async backtrace](#async-backtrace)
* [Other commands](#other-commands)
* [Tui interface](#tui-interface)
* [Configuration](#configuration)
Expand Down Expand Up @@ -426,6 +428,34 @@ Some examples:
element at index 1 at field `field2` in dereferenced value of field `field1`
at variable var1 🤡

## Async rust

Now BugStalker support some commands for interaction with async runtimes (currently only tokio multithread runtime is
supported).
There is also `oracle tokio`, but it adds some overhead to your program and
is not very informative unlike the commands presented below.

### Async backtrace

[demo async backtrace](https://github.com/godzie44/BugStalker/blob/master/doc/demo_async_bt.gif)

While debugging an asynchronous application, you may want to control the state of your application.
If it were a regular synchronous application, you could use the `backtrace` command,
unfortunately for an application with an asynchronous runtime, this command is of little use.

Therefore, BugStalker presents a family of commands "asynchronous backtrace". With their help
you can get information about the state of your asynchronous runtime -
the state of asynchronous workers and blocking threads, as well as information about each task in the system,
including its current state and its own "backtrace" - a stack of futures starting from the root.

- `async backtrace` - show information about tokio async workers and blocking threads (alias: `async bt`).
It contains worker/blocking thread id, worker local tasks queue info, currently executed tasks for each worker.
- `async backtrace all` - same as previous (alias: `async bt all`), but contains information about all tasks in the
system.
Each task contains an id, and represents as a futures stack, where one future wait for other, and so on.
- `async task {regex}` - print all task with root async functions with names matched to regex. If regex are empty
then print active task.

## Other commands

Of course, the debugger provides many more commands:
Expand Down
Binary file added doc/demo_async_bt.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
140 changes: 102 additions & 38 deletions examples/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ members = [
"shlib/calc_bin",
"shlib/printer_lib",
"panic",
"calculations"
"calculations",
"tokio_tcp"
]
resolver = "2"
6 changes: 5 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@ Initiated by user or system panic (like divide by zero panic).

### Calculations

Program that calculates some values. Useful for watchpoints testing.
Program that calculates some values. Useful for watchpoints testing.

### Tokio_tcp

Tokio tcp echo-server. Useful for testing `async ...` commands.
4 changes: 2 additions & 2 deletions examples/todos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ edition = "2021"
publish = false

[dependencies]
axum = {version = "0.6.18", features = ["default"]}
axum = { version = "0.7.5", features = ["default"] }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.4", features = ["util", "timeout"] }
tower-http = { version = "0.4.0", features = ["add-extension", "trace"] }
tower-http = { version = "0.5.0", features = ["add-extension", "trace"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
uuid = { version = "1.0", features = ["serde", "v4"] }
10 changes: 5 additions & 5 deletions examples/todos/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//!
//! - `GET /todos`: return a JSON list of Todos.
//! - `POST /todos`: create a new Todo.
//! - `PUT /todos/:id`: update a specific Todo.
//! - `PATCH /todos/:id`: update a specific Todo.
//! - `DELETE /todos/:id`: delete a specific Todo.
//!
//! Run with
Expand Down Expand Up @@ -57,7 +57,7 @@ async fn main() {
} else {
Err((
StatusCode::INTERNAL_SERVER_ERROR,
format!("Unhandled internal error: {}", error),
format!("Unhandled internal error: {error}"),
))
}
}))
Expand All @@ -67,11 +67,11 @@ async fn main() {
)
.with_state(db);

tracing::debug!("listening on 127.0.0.1:3000");
axum::Server::bind(&"127.0.0.1:3000".parse().unwrap())
.serve(app.into_make_service())
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.unwrap();
tracing::debug!("listening on {}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
}

// The query parameters for todos index
Expand Down
Loading

0 comments on commit ac1de66

Please sign in to comment.