Skip to content

Commit 63ac2c4

Browse files
committed
feat: add preliminary framework to handle requests
add basic logic to handle http requests and dispatch to gdb handlers Signed-off-by: Lix Zhou
1 parent f0542dc commit 63ac2c4

File tree

10 files changed

+4290
-53
lines changed

10 files changed

+4290
-53
lines changed

.cursorrules

Lines changed: 633 additions & 0 deletions
Large diffs are not rendered by default.

Cargo.lock

Lines changed: 2780 additions & 48 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,24 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7-
tokio = "1.44.1"
7+
axum = "0.8"
8+
tokio = { version = "1.44", features = ["full"] }
9+
tower = "0.4"
10+
tower-http = { version = "0.5", features = ["cors", "trace"] }
11+
tracing = "0.1"
12+
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
13+
tracing-appender = "0.2"
14+
serde = { version = "1.0", features = ["derive"] }
15+
serde_json = "1.0"
16+
thiserror = "1.0"
17+
async-trait = "0.1"
18+
tokio-stream = "0.1"
19+
futures = "0.3"
20+
anyhow = "1.0"
21+
regex = "1.10"
22+
uuid = { version = "1.7", features = ["v4", "serde"] }
23+
clap = { version = "4.5", features = ["derive"] }
24+
dotenv = "0.15"
25+
mcp-core = { version = "0.1", features = ["sse"] }
26+
mcp-core-macros = "0.1"
27+
schemars = "0.8"

README.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,60 @@
1-
# mcp_server_gdb
2-
MCP Server to expose the GDB debugging capabilities
1+
# MCP Server GDB
2+
3+
A GDB/MI protocol server based on the Axum framework, providing RESTful API interfaces for remote application debugging.
4+
5+
## Features
6+
7+
- Create and manage GDB debug sessions
8+
- Send GDB/MI commands and get responses
9+
- Set and manage breakpoints
10+
- View stack information and variables
11+
- Control program execution (run, pause, step, etc.)
12+
- Support concurrent multi-session debugging
13+
14+
## API Endpoints
15+
16+
### Session Management
17+
18+
- `GET /api/sessions` - Get all sessions
19+
- `POST /api/sessions` - Create new session
20+
- `GET /api/sessions/:session_id` - Get specific session
21+
- `DELETE /api/sessions/:session_id` - Close session
22+
23+
### Debug Control
24+
25+
- `POST /api/sessions/:session_id/command` - Send GDB command
26+
- `POST /api/sessions/:session_id/start` - Start debugging
27+
- `POST /api/sessions/:session_id/stop` - Stop debugging
28+
- `POST /api/sessions/:session_id/continue` - Continue execution
29+
- `POST /api/sessions/:session_id/step` - Step execution
30+
- `POST /api/sessions/:session_id/next` - Next execution
31+
32+
### Breakpoint Management
33+
34+
- `GET /api/sessions/:session_id/breakpoints` - Get breakpoint list
35+
- `POST /api/sessions/:session_id/breakpoints` - Set breakpoint
36+
- `DELETE /api/sessions/:session_id/breakpoints/:breakpoint_id` - Delete breakpoint
37+
38+
### Debug Information
39+
40+
- `GET /api/sessions/:session_id/stack` - Get stack information
41+
- `GET /api/sessions/:session_id/variables/:frame_id` - Get local variables
42+
43+
## Usage
44+
45+
1. Install Rust and Cargo
46+
2. Clone this repository
47+
3. Run `cargo run` to start the server
48+
4. Default server runs on `http://localhost:8080`
49+
50+
## Configuration
51+
52+
You can adjust server configuration by modifying the `src/config.rs` file:
53+
54+
- Server port
55+
- GDB path
56+
- Temporary file directory
57+
58+
## License
59+
60+
MIT

src/config.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/// Server Configuration
2+
pub struct Config {
3+
/// Server port
4+
pub server_port: u16,
5+
/// GDB path
6+
pub gdb_path: String,
7+
/// Temporary file directory
8+
pub temp_dir: String,
9+
}
10+
11+
impl Default for Config {
12+
fn default() -> Self {
13+
Self {
14+
server_port: std::env::var("SERVER_PORT")
15+
.unwrap_or_else(|_| "8080".to_string())
16+
.parse()
17+
.expect("Invalid server port"),
18+
gdb_path: std::env::var("GDB_PATH").unwrap_or_else(|_| "gdb".to_string()),
19+
temp_dir: std::env::temp_dir().to_string_lossy().to_string(),
20+
}
21+
}
22+
}

src/error.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use axum::{
2+
Json,
3+
http::StatusCode,
4+
response::{IntoResponse, Response},
5+
};
6+
use serde_json::json;
7+
use thiserror::Error;
8+
9+
/// Application error types
10+
#[derive(Error, Debug)]
11+
pub enum AppError {
12+
#[error("GDB error: {0}")]
13+
GDBError(String),
14+
15+
#[error("Parse error: {0}")]
16+
ParseError(String),
17+
18+
#[error("IO error: {0}")]
19+
IoError(#[from] std::io::Error),
20+
21+
#[error("Resource not found: {0}")]
22+
NotFound(String),
23+
24+
#[error("Internal server error: {0}")]
25+
InternalServerError(String),
26+
}
27+
28+
impl IntoResponse for AppError {
29+
fn into_response(self) -> Response {
30+
let (status, error_message) = match self {
31+
AppError::GDBError(msg) => (StatusCode::BAD_REQUEST, msg),
32+
AppError::ParseError(msg) => (StatusCode::BAD_REQUEST, msg),
33+
AppError::IoError(err) => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()),
34+
AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
35+
AppError::InternalServerError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
36+
};
37+
38+
let body = Json(json!({
39+
"error": {
40+
"message": error_message,
41+
"code": status.as_u16()
42+
}
43+
}));
44+
45+
(status, body).into_response()
46+
}
47+
}
48+
49+
/// Application result type
50+
pub type AppResult<T> = Result<T, AppError>;

0 commit comments

Comments
 (0)