Forge
csharp5e452b8e
1using DotnetDebug.Core;
2
3namespace DotnetDebugMcp;
4
5/// <summary>Текущая активная отладочная сессия после debug_launch. Очередь ожидания stopped + ретраи в тулах.</summary>
6internal static class DebugSession
7{
8 public static DapClient? CurrentClient { get; set; }
9 public static int LastStoppedThreadId { get; set; }
10 /// <summary>Текст последнего исключения при остановке по reason=exception (для вывода агенту).</summary>
11 public static string? LastExceptionText { get; set; }
12
13 private static TaskCompletionSource? _currentStoppedTcs;
14 private static readonly object StoppedLock = new();
15
16 /// <summary>Вызвать при старте сессии: создаёт TCS для ожидания следующего stopped.</summary>
17 public static void PrepareStoppedWait()
18 {
19 lock (StoppedLock)
20 {
21 _currentStoppedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
22 }
23 }
24
25 /// <summary>Вызывается из read loop при событии stopped. Обновляет threadId, при необходимости — текст исключения, и даёт сигнал ожидающим.</summary>
26 public static void OnStopped(int threadId, string? exceptionText = null)
27 {
28 LastStoppedThreadId = threadId;
29 LastExceptionText = exceptionText;
30 lock (StoppedLock)
31 {
32 var t = _currentStoppedTcs;
33 _currentStoppedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
34 t?.TrySetResult();
35 }
36 }
37
38 /// <summary>Вызывается при событии continued — следующий stack_trace/step будет ждать нового stopped.</summary>
39 public static void OnContinued()
40 {
41 LastStoppedThreadId = 0;
42 LastExceptionText = null;
43 }
44
45 /// <summary>Ждать следующего события stopped (или вернуться сразу, если уже paused). Таймаут — исключение TimeoutException.</summary>
46 public static async Task WaitForStoppedAsync(TimeSpan timeout)
47 {
48 if (CurrentClient == null)
49 throw new InvalidOperationException("No active debug session. Run debug_launch first.");
50 Task waitTask;
51 lock (StoppedLock)
52 {
53 if (LastStoppedThreadId != 0)
54 return;
55 waitTask = _currentStoppedTcs?.Task ?? Task.CompletedTask;
56 }
57 await waitTask.WaitAsync(timeout).ConfigureAwait(false);
58 }
59}
60
View only · write via MCP/CIDE