dap-integration
Guides the integration of DAP servers for probe-rs embedded debugging.
Install
mkdir -p .claude/skills/dap-integration && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10509" && unzip -o skill.zip -d .claude/skills/dap-integration && rm skill.zipInstalls to .claude/skills/dap-integration
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
probe-rs DAPサーバー統合。Use when: DAPサーバー修正、デバッグ機能追加、probe-rs連携、ブレークポイント、パスマッピング、CancellationToken、シャットダウンKey capabilities
- →Configure DAP server
- →Manage server lifecycle
- →Debug embedded probe-rs
- →Handle path mapping
How it works
Architects the DAP server lifecycle and communication for debugging embedded systems.
Inputs & outputs
When to use dap-integration
- →Configure DAP server
- →Debug embedded probe-rs
- →Manage server shutdown
About this skill
probe-rs DAP サーバー統合
When to Use
- DAP サーバーの起動・停止ロジックを変更するとき
- probe-rs との連携機能を追加するとき
- デバッグ関連(ブレークポイント、パスマッピング等)の修正
- DAP サーバーのライフサイクル管理の変更
Architecture
┌─────────────────────────────┐
│ VS Code (Dev Container内) │
│ launch.json + DAP Client │
└──────────┬──────────────────┘
│ TCP (port 50001)
┌──────────▼──────────────────┐
│ baker-link-env (ホスト) │
│ ProbeRsDapServer │
│ └─ probe-rs DAP Server │
└──────────┬──────────────────┘
│ USB (SWD/JTAG)
┌──────────▼──────────────────┐
│ Physical MCU (RP2040 etc.) │
└─────────────────────────────┘
グローバルシングルトン
// main.rs で定義
static DAP_SERVER: OnceLock<Mutex<cmd::ProbeRsDapServer>> = OnceLock::new();
// どこからでもアクセス
crate::dap_server() // → &'static Mutex<ProbeRsDapServer>
ProbeRsDapServer の構造
pub struct ProbeRsDapServer {
pub port: String, // リッスンポート
shutdown: Option<CancellationToken>, // グレースフルシャットダウン用
handle: Option<std::thread::JoinHandle<()>>, // ワーカースレッド
pub status: DapServerStatus, // Running(port) | Stopped
}
Procedure
1. DAP サーバーの起動フロー
impl ProbeRsDapServer {
pub fn start(&mut self, tx: mpsc::Sender<String>) -> Result<(), String> {
if self.status != DapServerStatus::Stopped {
return Ok(()); // 二重起動防止
}
let port = self.parse_port()?;
let shutdown = CancellationToken::new();
let shutdown_task = shutdown.clone();
// 別スレッドで Tokio ランタイムを作成し DAP サーバーを実行
let handle = spawn_dap_server_thread(port, shutdown_task, tx);
self.shutdown = Some(shutdown);
self.handle = Some(handle);
self.status = DapServerStatus::Running(port);
Ok(())
}
}
重要: DAP サーバーは専用スレッドで tokio::runtime::Builder::new_current_thread() を使って新しい Tokio ランタイム上で動く。メインの Dioxus ランタイムとは独立している。
2. DAP サーバーの停止フロー
pub fn stop(&mut self) -> bool {
if self.status == DapServerStatus::Stopped {
return false;
}
// 1. CancellationToken でシャットダウンを通知
if let Some(shutdown) = self.shutdown.take() {
shutdown.cancel();
}
// 2. JoinHandle をデタッチ(UIスレッドをブロックしない)
if let Some(handle) = self.handle.take() {
thread::spawn(move || {
let _ = handle.join();
});
}
self.status = DapServerStatus::Stopped;
true
}
必須パターン:
CancellationTokenで安全にシャットダウンを通知handle.join()は別スレッドでデタッチ — UIスレッドブロック禁止shutdownとhandleをtake()で所有権を移動
3. probe-rs API 呼び出し
use probe_rs_tools::cmd::dap_server;
// 実際の DAP サーバー起動
dap_server::run_with_shutdown_on_port(
port, // u16: リッスンポート
false, // single_session: false = マルチセッション
None, // log_file: Option<PathBuf>
offset, // UtcOffset: ログタイムスタンプ用
shutdown_task, // CancellationToken
)
4. ログ連携
DAP サーバースレッドのログは mpsc::Sender<String> 経由で DisplayBuffer に送る:
fn spawn_dap_server_thread(
port: u16,
shutdown_task: CancellationToken,
log_tx: mpsc::Sender<String>,
) -> thread::JoinHandle<()> {
thread::spawn(move || {
// ランタイムエラー → log_tx で通知
// DAP サーバーエラー → shutdown 状態を確認して適切にログ
if shutdown_probe.is_cancelled() {
let _ = log_tx.send("DAP server shutdown requested".to_string());
} else {
let _ = log_tx.send(format!("[ERROR] DAP server stopped: {error}"));
}
})
}
5. UI との連携 (AppAction)
// app.rs
AppAction::StartDap => {
if let Ok(mut server) = crate::dap_server().lock() {
let tx = crate::display_buffer().lock().ok()?.sender();
match server.start(tx) {
Ok(()) => {
dap_running.set(true);
crate::log_info(format!("DAP Server started on port {}", server.port));
}
Err(e) => {
crate::log_error(e.clone());
last_error.set(Some(e));
}
}
}
}
AppAction::StopDap => {
if let Ok(mut server) = crate::dap_server().lock() {
if server.stop() {
dap_running.set(false);
crate::log_info("DAP Server stopped");
}
}
}
Path Mapping (Docker ↔ Host)
Dev Container 内のパスとホストのパスが異なるため、VS Code の launch.json で pathMappings を設定する必要がある:
{
"pathMappings": [
{
"remoteRoot": "/workspaces/project",
"localRoot": "${workspaceFolder}"
}
]
}
注意事項(既知の問題):
- probe-rs のブレークポイント照合はリクエストパスが相対の場合に DWARF の絶対パスとマッチしないことがある
- ホスト絶対パスマッピングを相対パスフォールバックより優先すべき
- 詳細は
/memories/repo/dap-path-matching.mdを参照
Quality Checklist
-
CancellationTokenでグレースフルシャットダウンが実装されている -
handle.join()はUIスレッド外でデタッチされている - 二重起動チェック (
status != Stopped) がある - ログは
mpsc::Sender<String>経由でDisplayBufferに送っている - エラー時に
shutdown.is_cancelled()を確認して正常停止と異常停止を区別 - UI 側は
AppAction経由でのみ start/stop を発行
When not to use it
- →When not using probe-rs
- →When the DAP server is already stable
Prerequisites
Limitations
- →Requires careful handling of thread-safe state
- →Path mapping can be complex in containers
How it compares
Provides a structured integration for probe-rs DAP servers rather than manual configuration.
Compared to similar skills
dap-integration side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| dap-integration (this skill) | 0 | 4mo | No flags | Advanced |
| memory-safety-patterns | 4 | 4mo | No flags | Advanced |
| debug-cli | 1 | 8mo | Review | Intermediate |
| fix-clippy | 3 | 6mo | No flags | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
memory-safety-patterns
sickn33
Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory bugs.
debug-cli
antinomyhq
Use when users need to debug, modify, or extend the code-forge application's CLI commands, argument parsing, or CLI behavior. This includes adding new commands, fixing CLI bugs, updating command options, or troubleshooting CLI-related issues.
fix-clippy
quickwit-oss
Fix all clippy lint warnings in the project
debug-lldb
regenrek
Capture and analyze thread backtraces with LLDB/GDB to debug hangs, deadlocks, UI freezes, IPC stalls, or high-CPU loops across any language or project. Use when an app becomes unresponsive, switching contexts stalls, or you need thread stacks to locate lock inversion or blocking calls.
handling-rust-errors
hashintel
HASH error handling patterns using error-stack crate. Use when working with Result types, Report types, defining custom errors, propagating errors with change_context, adding context with attach, implementing Error trait, or documenting error conditions in Rust code.
rust-router
actionbook
CRITICAL: Use for ALL Rust questions including errors, design, and coding. HIGHEST PRIORITY for: 比较, 对比, compare, vs, versus, 区别, difference, 最佳实践, best practice, tokio vs, async-std vs, 比较 tokio, 比较 async, Triggers on: Rust, cargo, rustc, crate, Cargo.toml, 意图分析, 问题分析, 语义分析, analyze intent, question analysis, compile error, borrow error, lifetime error, ownership error, type error, trait error, value moved, cannot borrow, does not live long enough, mismatched types, not satisfied, E0382, E0597, E0277, E0308, E0499, E0502, E0596, async, await, Send, Sync, tokio, concurrency, error handling, 编译错误, compile error, 所有权, ownership, 借用, borrow, 生命周期, lifetime, 类型错误, type error, 异步, async, 并发, concurrency, 错误处理, error handling, 问题, problem, question, 怎么用, how to use, 如何, how to, 为什么, why, 什么是, what is, 帮我写, help me write, 实现, implement, 解释, explain