Skip to content

调试器 API

概述

Trae 调试器 API 提供了完整的调试功能,支持多种编程语言和调试协议。开发者可以通过 API 创建自定义调试器、设置断点、检查变量、控制程序执行流程等。

核心概念

调试会话

调试会话是调试器的核心概念,代表一个正在进行的调试过程:

typescript
interface DebugSession {
  id: string;
  name: string;
  type: string;
  configuration: DebugConfiguration;
  workspaceFolder?: WorkspaceFolder;
}

interface DebugConfiguration {
  type: string;
  name: string;
  request: 'launch' | 'attach';
  program?: string;
  args?: string[];
  env?: { [key: string]: string };
  cwd?: string;
  [key: string]: any;
}

调试适配器

typescript
interface DebugAdapter {
  type: string;
  executable: DebugAdapterExecutable;
  server?: DebugAdapterServer;
}

interface DebugAdapterExecutable {
  command: string;
  args?: string[];
  options?: {
    env?: { [key: string]: string };
    cwd?: string;
  };
}

API 参考

调试会话管理

startDebugging()

启动调试会话:

typescript
import { debug, DebugConfiguration } from '@trae/api';

// 启动 Node.js 调试会话
const config: DebugConfiguration = {
  type: 'node',
  request: 'launch',
  name: 'Launch Program',
  program: '${workspaceFolder}/app.js',
  args: ['--port', '3000'],
  env: {
    NODE_ENV: 'development'
  },
  cwd: '${workspaceFolder}',
  console: 'integratedTerminal'
};

const success = await debug.startDebugging(undefined, config);
if (success) {
  console.log('Debugging started successfully');
}

stopDebugging()

停止调试会话:

typescript
// 停止当前活动的调试会话
if (debug.activeDebugSession) {
  await debug.stopDebugging(debug.activeDebugSession);
}

// 停止所有调试会话
for (const session of debug.debugSessions) {
  await debug.stopDebugging(session);
}

断点管理

addBreakpoints()

添加断点:

typescript
import { debug, Breakpoint, SourceBreakpoint } from '@trae/api';

// 添加源码断点
const sourceBreakpoint = new SourceBreakpoint(
  new Location(uri, new Position(10, 0)), // 第11行
  true, // 启用
  'x > 5' // 条件
);

debug.addBreakpoints([sourceBreakpoint]);

// 添加函数断点
const functionBreakpoint = new FunctionBreakpoint(
  'myFunction',
  true,
  'arguments.length > 0'
);

debug.addBreakpoints([functionBreakpoint]);

removeBreakpoints()

移除断点:

typescript
// 移除特定断点
debug.removeBreakpoints([sourceBreakpoint]);

// 移除所有断点
const allBreakpoints = debug.breakpoints;
debug.removeBreakpoints(allBreakpoints);

调试控制

执行控制命令

typescript
// 继续执行
await debug.activeDebugSession?.customRequest('continue');

// 单步执行
await debug.activeDebugSession?.customRequest('next');

// 步入函数
await debug.activeDebugSession?.customRequest('stepIn');

// 步出函数
await debug.activeDebugSession?.customRequest('stepOut');

// 暂停执行
await debug.activeDebugSession?.customRequest('pause');

// 重启调试
await debug.activeDebugSession?.customRequest('restart');

变量检查

getVariables()

获取变量信息:

typescript
// 获取当前作用域的变量
const getVariables = async (session: DebugSession) => {
  try {
    const response = await session.customRequest('scopes', {
      frameId: 0
    });
    
    const scopes = response.scopes;
    const variables = [];
    
    for (const scope of scopes) {
      const varsResponse = await session.customRequest('variables', {
        variablesReference: scope.variablesReference
      });
      
      variables.push(...varsResponse.variables);
    }
    
    return variables;
  } catch (error) {
    console.error('Failed to get variables:', error);
    return [];
  }
};

evaluateExpression()

评估表达式:

typescript
const evaluateExpression = async (expression: string) => {
  if (!debug.activeDebugSession) {
    return null;
  }
  
  try {
    const response = await debug.activeDebugSession.customRequest('evaluate', {
      expression,
      frameId: 0,
      context: 'watch'
    });
    
    return {
      result: response.result,
      type: response.type,
      variablesReference: response.variablesReference
    };
  } catch (error) {
    console.error('Failed to evaluate expression:', error);
    return null;
  }
};

调用堆栈

getStackTrace()

获取调用堆栈:

typescript
const getStackTrace = async (session: DebugSession) => {
  try {
    const response = await session.customRequest('stackTrace', {
      threadId: 1,
      startFrame: 0,
      levels: 20
    });
    
    return response.stackFrames.map(frame => ({
      id: frame.id,
      name: frame.name,
      source: frame.source,
      line: frame.line,
      column: frame.column
    }));
  } catch (error) {
    console.error('Failed to get stack trace:', error);
    return [];
  }
};

调试适配器

注册调试适配器

registerDebugAdapterDescriptorFactory()

typescript
import { debug, DebugAdapterDescriptorFactory } from '@trae/api';

class MyDebugAdapterFactory implements DebugAdapterDescriptorFactory {
  createDebugAdapterDescriptor(
    session: DebugSession,
    executable: DebugAdapterExecutable | undefined
  ) {
    // 返回调试适配器描述符
    return new DebugAdapterExecutable(
      'node',
      ['path/to/debug-adapter.js'],
      {
        env: { DEBUG: 'true' }
      }
    );
  }
}

// 注册工厂
const disposable = debug.registerDebugAdapterDescriptorFactory(
  'myLanguage',
  new MyDebugAdapterFactory()
);

自定义调试适配器

typescript
class CustomDebugAdapter {
  private session: DebugSession;
  
  constructor(session: DebugSession) {
    this.session = session;
  }
  
  async initialize() {
    // 初始化调试适配器
    await this.session.customRequest('initialize', {
      clientID: 'trae',
      clientName: 'Trae IDE',
      adapterID: 'custom',
      pathFormat: 'path',
      linesStartAt1: true,
      columnsStartAt1: true,
      supportsVariableType: true,
      supportsVariablePaging: true,
      supportsRunInTerminalRequest: true
    });
  }
  
  async launch(config: DebugConfiguration) {
    // 启动程序
    await this.session.customRequest('launch', config);
  }
  
  async attach(config: DebugConfiguration) {
    // 附加到进程
    await this.session.customRequest('attach', config);
  }
}

事件处理

调试事件监听

typescript
// 监听调试会话开始
debug.onDidStartDebugSession(session => {
  console.log(`Debug session started: ${session.name}`);
  
  // 设置初始断点
  setupInitialBreakpoints(session);
});

// 监听调试会话结束
debug.onDidTerminateDebugSession(session => {
  console.log(`Debug session terminated: ${session.name}`);
  
  // 清理资源
  cleanupDebugResources(session);
});

// 监听调试会话变化
debug.onDidChangeActiveDebugSession(session => {
  if (session) {
    console.log(`Active debug session changed to: ${session.name}`);
    updateDebugUI(session);
  }
});

// 监听断点变化
debug.onDidChangeBreakpoints(event => {
  console.log('Breakpoints changed:', {
    added: event.added,
    removed: event.removed,
    changed: event.changed
  });
});

自定义调试事件

typescript
// 处理自定义调试协议事件
const handleCustomEvents = (session: DebugSession) => {
  session.customRequest('setExceptionBreakpoints', {
    filters: ['uncaught', 'caught']
  });
  
  // 监听输出事件
  session.onDidReceiveDebugSessionCustomEvent(event => {
    if (event.event === 'output') {
      console.log('Debug output:', event.body.output);
    }
    
    if (event.event === 'stopped') {
      console.log('Execution stopped:', event.body.reason);
      handleExecutionStopped(session, event.body);
    }
  });
};

高级功能

多线程调试

typescript
const handleMultiThreadDebugging = async (session: DebugSession) => {
  try {
    // 获取所有线程
    const threadsResponse = await session.customRequest('threads');
    const threads = threadsResponse.threads;
    
    console.log('Available threads:', threads);
    
    // 为每个线程获取堆栈跟踪
    for (const thread of threads) {
      const stackTrace = await session.customRequest('stackTrace', {
        threadId: thread.id
      });
      
      console.log(`Thread ${thread.id} stack:`, stackTrace.stackFrames);
    }
  } catch (error) {
    console.error('Multi-thread debugging error:', error);
  }
};

条件断点

typescript
const setConditionalBreakpoint = (uri: Uri, line: number, condition: string) => {
  const breakpoint = new SourceBreakpoint(
    new Location(uri, new Position(line, 0)),
    true,
    condition
  );
  
  debug.addBreakpoints([breakpoint]);
};

// 示例:设置条件断点
setConditionalBreakpoint(
  Uri.file('/path/to/file.js'),
  15,
  'user.age > 18 && user.isActive'
);

日志点

typescript
const setLogPoint = (uri: Uri, line: number, logMessage: string) => {
  const breakpoint = new SourceBreakpoint(
    new Location(uri, new Position(line, 0)),
    true,
    undefined,
    undefined,
    logMessage
  );
  
  debug.addBreakpoints([breakpoint]);
};

// 示例:设置日志点
setLogPoint(
  Uri.file('/path/to/file.js'),
  20,
  'User ID: {userId}, Name: {user.name}'
);

调试配置

预定义配置

typescript
// Node.js 调试配置
const nodeConfig: DebugConfiguration = {
  type: 'node',
  request: 'launch',
  name: 'Launch Node.js',
  program: '${workspaceFolder}/index.js',
  args: [],
  env: {},
  console: 'integratedTerminal',
  internalConsoleOptions: 'neverOpen',
  skipFiles: ['<node_internals>/**']
};

// Python 调试配置
const pythonConfig: DebugConfiguration = {
  type: 'python',
  request: 'launch',
  name: 'Launch Python',
  program: '${workspaceFolder}/main.py',
  args: [],
  console: 'integratedTerminal',
  justMyCode: true
};

// Chrome 调试配置
const chromeConfig: DebugConfiguration = {
  type: 'chrome',
  request: 'launch',
  name: 'Launch Chrome',
  url: 'http://localhost:3000',
  webRoot: '${workspaceFolder}/src',
  sourceMaps: true
};

动态配置

typescript
const createDynamicConfig = (projectType: string): DebugConfiguration => {
  const baseConfig = {
    name: `Debug ${projectType}`,
    request: 'launch' as const,
    cwd: '${workspaceFolder}'
  };
  
  switch (projectType) {
    case 'react':
      return {
        ...baseConfig,
        type: 'chrome',
        url: 'http://localhost:3000',
        webRoot: '${workspaceFolder}/src'
      };
      
    case 'express':
      return {
        ...baseConfig,
        type: 'node',
        program: '${workspaceFolder}/server.js',
        env: { NODE_ENV: 'development' }
      };
      
    default:
      throw new Error(`Unsupported project type: ${projectType}`);
  }
};

错误处理

typescript
const robustDebugSession = async (config: DebugConfiguration) => {
  try {
    const success = await debug.startDebugging(undefined, config);
    
    if (!success) {
      throw new Error('Failed to start debugging session');
    }
    
    // 设置错误处理
    debug.activeDebugSession?.onDidReceiveDebugSessionCustomEvent(event => {
      if (event.event === 'error') {
        console.error('Debug session error:', event.body);
        handleDebugError(event.body);
      }
    });
    
  } catch (error) {
    console.error('Debug session failed:', error);
    showDebugErrorMessage(error.message);
  }
};

const handleDebugError = (error: any) => {
  // 根据错误类型采取不同的处理策略
  switch (error.type) {
    case 'connection_failed':
      // 尝试重新连接
      retryConnection();
      break;
      
    case 'breakpoint_failed':
      // 移除有问题的断点
      removeProblematicBreakpoints();
      break;
      
    default:
      // 通用错误处理
      logError(error);
  }
};

性能优化

延迟加载

typescript
const lazyDebugAdapter = {
  async createDebugAdapterDescriptor(session: DebugSession) {
    // 延迟加载调试适配器
    const { DebugAdapter } = await import('./debug-adapter');
    return new DebugAdapter(session);
  }
};

缓存优化

typescript
const debugCache = new Map();

const getCachedVariables = async (session: DebugSession, frameId: number) => {
  const cacheKey = `${session.id}:${frameId}`;
  
  if (debugCache.has(cacheKey)) {
    return debugCache.get(cacheKey);
  }
  
  const variables = await getVariables(session, frameId);
  debugCache.set(cacheKey, variables);
  
  return variables;
};

相关 API

您的终极 AI 驱动 IDE 学习指南