<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>BeaCox&#39;s Blog</title>
    <link>https://blog.beacox.space/categories/%E5%B7%A5%E5%85%B7/</link>
    <description>Stay humble, remain critical.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <managingEditor>root@beacox.space (BeaCox)</managingEditor>
    <webMaster>root@beacox.space (BeaCox)</webMaster>
    <copyright>© Since 2022 BeaCox</copyright>
    <lastBuildDate>Sat, 20 Jun 2026 04:04:23 +0000</lastBuildDate><atom:link href="https://blog.beacox.space/categories/%E5%B7%A5%E5%85%B7/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Why gdb-mcp?</title>
      <link>https://blog.beacox.space/posts/gdb-mcp/</link>
      <pubDate>Sat, 20 Jun 2026 12:00:00 +0800</pubDate>
      <author>root@beacox.space (BeaCox)</author>
      <guid>https://blog.beacox.space/posts/gdb-mcp/</guid>
      <description><br/>&lt;p&gt;最近写了一个项目：&lt;a
  href=&#34;https://github.com/BeaCox/gdb-mcp&#34;
    target=&#34;_blank&#34;
  &gt;&lt;code&gt;gdb-mcp&lt;/code&gt;&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&#34;github-card-wrapper&#34;&gt;&lt;a id=&#34;github-607b045d9b7ff3bf8b4b9e16c86b3eee&#34; target=&#34;_blank&#34; href=&#34;https://github.com/BeaCox/gdb-mcp&#34; class=&#34;cursor-pointer&#34;&gt;
      &lt;div
        class=&#34;w-full md:w-auto p-0 m-0 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl&#34;&gt;&lt;div class=&#34;w-full md:w-auto pt-3 p-5&#34;&gt;
          &lt;div class=&#34;flex items-center&#34;&gt;
            &lt;span class=&#34;text-2xl text-neutral-800 dark:text-neutral mr-[10px]&#34;&gt;
              

  &lt;span class=&#34;relative block icon&#34;&gt;
    &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 496 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z&#34;/&gt;&lt;/svg&gt;

  &lt;/span&gt;


            &lt;/span&gt;
            &lt;div
              id=&#34;github-607b045d9b7ff3bf8b4b9e16c86b3eee-full_name&#34;
              class=&#34;m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral&#34;&gt;
              BeaCox/gdb-mcp
            &lt;/div&gt;
          &lt;/div&gt;

          &lt;p id=&#34;github-607b045d9b7ff3bf8b4b9e16c86b3eee-description&#34; class=&#34;m-0 mt-2 text-md text-neutral-800 dark:text-neutral&#34;&gt;
            A production-ready MCP server for multi-session GDB and gdbserver debugging through GDB/MI.
          &lt;/p&gt;

          &lt;div class=&#34;m-0 mt-2 flex items-center&#34;&gt;
            
            
            &lt;span
              class=&#34;mr-1 inline-block h-3 w-3 rounded-full background-color-a7f5f35426b927411fc9231b56382173&#34;&gt;&lt;/span&gt;
            &lt;div class=&#34;m-0 mr-5 text-md text-neutral-800 dark:text-neutral&#34;&gt;
              Python
            &lt;/div&gt;

            &lt;span class=&#34;text-md mr-1 text-neutral-800 dark:text-neutral&#34;&gt;
              

  &lt;span class=&#34;relative block icon&#34;&gt;
    &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 576 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M287.9 0C297.1 0 305.5 5.25 309.5 13.52L378.1 154.8L531.4 177.5C540.4 178.8 547.8 185.1 550.7 193.7C553.5 202.4 551.2 211.9 544.8 218.2L433.6 328.4L459.9 483.9C461.4 492.9 457.7 502.1 450.2 507.4C442.8 512.7 432.1 513.4 424.9 509.1L287.9 435.9L150.1 509.1C142.9 513.4 133.1 512.7 125.6 507.4C118.2 502.1 114.5 492.9 115.1 483.9L142.2 328.4L31.11 218.2C24.65 211.9 22.36 202.4 25.2 193.7C28.03 185.1 35.5 178.8 44.49 177.5L197.7 154.8L266.3 13.52C270.4 5.249 278.7 0 287.9 0L287.9 0zM287.9 78.95L235.4 187.2C231.9 194.3 225.1 199.3 217.3 200.5L98.98 217.9L184.9 303C190.4 308.5 192.9 316.4 191.6 324.1L171.4 443.7L276.6 387.5C283.7 383.7 292.2 383.7 299.2 387.5L404.4 443.7L384.2 324.1C382.9 316.4 385.5 308.5 391 303L476.9 217.9L358.6 200.5C350.7 199.3 343.9 194.3 340.5 187.2L287.9 78.95z&#34;/&gt;&lt;/svg&gt;
  &lt;/span&gt;


            &lt;/span&gt;
            &lt;div id=&#34;github-607b045d9b7ff3bf8b4b9e16c86b3eee-stargazers&#34; class=&#34;m-0 mr-5 text-md text-neutral-800 dark:text-neutral&#34;&gt;
              2
            &lt;/div&gt;

            &lt;span class=&#34;text-md mr-1 text-neutral-800 dark:text-neutral&#34;&gt;
              

  &lt;span class=&#34;relative block icon&#34;&gt;
    &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 448 512&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M80 104c13.3 0 24-10.7 24-24s-10.7-24-24-24S56 66.7 56 80s10.7 24 24 24zm80-24c0 32.8-19.7 61-48 73.3V192c0 17.7 14.3 32 32 32H304c17.7 0 32-14.3 32-32V153.3C307.7 141 288 112.8 288 80c0-44.2 35.8-80 80-80s80 35.8 80 80c0 32.8-19.7 61-48 73.3V192c0 53-43 96-96 96H256v70.7c28.3 12.3 48 40.5 48 73.3c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-32.8 19.7-61 48-73.3V288H144c-53 0-96-43-96-96V153.3C19.7 141 0 112.8 0 80C0 35.8 35.8 0 80 0s80 35.8 80 80zm208 24c13.3 0 24-10.7 24-24s-10.7-24-24-24s-24 10.7-24 24s10.7 24 24 24zM248 432c0-13.3-10.7-24-24-24s-24 10.7-24 24s10.7 24 24 24s24-10.7 24-24z&#34;/&gt;&lt;/svg&gt;
  &lt;/span&gt;


            &lt;/span&gt;
            &lt;div id=&#34;github-607b045d9b7ff3bf8b4b9e16c86b3eee-forks&#34; class=&#34;m-0 mr-5 text-md text-neutral-800 dark:text-neutral&#34;&gt;
              0
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      
      
      &lt;script
        async
        type=&#34;text/javascript&#34;
        src=&#34;https://blog.beacox.space/js/fetch-repo.min.b752abce168a1098dd9b725d777ce942b2fbc964c7f0808e1abb6dec3b0374468b3d44229df06d610f5025f3b3473c1323359b651d82122ecbe09d59cad09d51.js&#34;
        integrity=&#34;sha512-t1KrzhaKEJjdm3Jdd3zpQrL7yWTH8ICOGrtt7DsDdEaLPUQinfBtYQ9QJfOzRzwTIzWbZR2CEi7L4J1ZytCdUQ==&#34;
        data-repo-url=&#34;https://api.github.com/repos/BeaCox/gdb-mcp&#34;
        data-repo-id=&#34;github-607b045d9b7ff3bf8b4b9e16c86b3eee&#34;&gt;&lt;/script&gt;
    &lt;/a&gt;&lt;/div&gt;

&lt;p&gt;一句话概括，它是一个面向 MCP 客户端的 GDB server，让 Codex、Claude Code 之类的 agent 可以通过结构化 tool 调用来控制 GDB，而不是把 GDB 当成普通 shell 程序来用。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;TL;DR 
    &lt;div id=&#34;tldr&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#tldr&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;gdb-mcp&lt;/code&gt; 想解决的问题是：让 agent 能够稳定地进入动态调试循环。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 GDB/MI 和 MCP tool 封装 GDB，而不是让 agent 自己拼裸命令、解析终端输出&lt;/li&gt;
&lt;li&gt;显式维护多 GDB session，避免“当前调试目标”这种隐式状态&lt;/li&gt;
&lt;li&gt;为 run / continue / step 这类操作返回 compact context，包括当前位置、backtrace、locals 和 stop reason&lt;/li&gt;
&lt;li&gt;默认关闭写内存、调用函数、任意 GDB 命令等危险能力&lt;/li&gt;
&lt;li&gt;支持本地程序、attach、core dump、gdbserver 和 reverse debugging 等逆向/漏挖常见场景&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我的理解是，agent 想做自动化逆向和漏洞挖掘，不能只有静态分析能力。很多关键事实只存在于运行时，而 GDB 正是最通用的运行时观察入口。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;初心 
    &lt;div id=&#34;初心&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e5%88%9d%e5%bf%83&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;我一开始想做这个东西，是因为我觉得 &lt;strong&gt;GDB MCP 对 agent 自动化逆向和漏洞挖掘很重要&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;逆向和漏挖并不只是“看静态代码”。很多时候真正有用的信息来自动态过程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个输入走到了哪条分支&lt;/li&gt;
&lt;li&gt;某个变量在崩溃前被改成了什么&lt;/li&gt;
&lt;li&gt;堆块、寄存器、栈帧、线程状态现在是什么样&lt;/li&gt;
&lt;li&gt;patch 一个条件、改一个变量、倒回一步之后行为是否变化&lt;/li&gt;
&lt;li&gt;core dump 里保存的现场能不能还原出漏洞路径&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些工作以前主要由人来驱动 GDB：下断点、运行、单步、看 backtrace、看 locals、读内存、继续跑，再根据结果调整下一步。Agent 想进入这个循环，就需要一个稳定的调试接口。&lt;/p&gt;
&lt;p&gt;如果没有这样的接口，agent 只能把 GDB 当成一个普通命令行程序来用。这会带来几个问题：输出格式不稳定、上下文太长、状态不清晰，并且很难区分“读一下状态”和“修改目标程序”。&lt;/p&gt;
&lt;p&gt;市面上已经有一些 GDB MCP，但我试下来都不太符合自己想要的工作流。主要问题如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;会话模型不够明确，多目标调试时容易混在一起&lt;/li&gt;
&lt;li&gt;过度依赖裸 &lt;code&gt;gdb_execute&lt;/code&gt;，agent 需要自己拼命令、自己解析输出&lt;/li&gt;
&lt;li&gt;输出没有为 LLM 上下文做压缩，一次 backtrace 或 disassemble 就可能塞进很多无关内容&lt;/li&gt;
&lt;li&gt;安全边界不清楚，读状态、控制执行、写内存、调用 inferior 函数混在一起&lt;/li&gt;
&lt;li&gt;对 attach、core、gdbserver、reverse debugging 这些逆向/漏洞场景常用能力支持不足&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是我决定&lt;del&gt;自己&lt;/del&gt;（vibe）写一个。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;设计目标 
    &lt;div id=&#34;设计目标&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e8%ae%be%e8%ae%a1%e7%9b%ae%e6%a0%87&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;gdb-mcp&lt;/code&gt; 的目标不是把所有 GDB 命令原样搬到 MCP 里，而是给 agent 一个更适合自动化推理的调试抽象。&lt;/p&gt;
&lt;p&gt;目前它的定位大概是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux-first，优先保证本地 GDB / core / attach / gdbserver 的常见路径可靠&lt;/li&gt;
&lt;li&gt;每个调试目标都有显式 &lt;code&gt;session_id&lt;/code&gt;，不存在隐式当前会话&lt;/li&gt;
&lt;li&gt;常用操作都做成专用 tool，而不是让 agent 到处执行裸命令&lt;/li&gt;
&lt;li&gt;执行类工具尽量直接返回当前位置、栈和局部变量，减少 agent 再发多轮查询&lt;/li&gt;
&lt;li&gt;默认安全，写内存、调用函数、任意 GDB 命令必须显式开启 unsafe&lt;/li&gt;
&lt;li&gt;支持 Codex、Claude Code 以及任何标准 MCP client&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前版本到了 &lt;code&gt;0.3.0&lt;/code&gt;，工具数量五十多个，覆盖 session 管理、执行控制、断点、线程/栈帧、表达式求值、反汇编、内存读取、core、attach、gdbserver、reverse debugging 和诊断信息。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;技术路线 
    &lt;div id=&#34;技术路线&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e6%8a%80%e6%9c%af%e8%b7%af%e7%ba%bf&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;整体结构并不复杂：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MCP client
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  | stdio
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gdb-mcp lazy proxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  | first gdb_* tool call
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gdb-mcp backend
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  |
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  | GDB/MI
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  v
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GDB / gdbserver / target program
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里有两个关键选择：一是用 GDB/MI，而不是直接解析普通 CLI 输出；二是默认入口是一个 lazy stdio proxy。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;GDB/MI 
    &lt;div id=&#34;gdbmi&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#gdbmi&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h3&gt;
&lt;p&gt;GDB 普通 CLI 输出是给人看的，不是给程序解析的。同样是一个栈帧、一个断点、一次停止原因，CLI 输出经常依赖格式化文本。Agent 当然可以“读懂”文本，但如果要做自动化，就不能每一步都赌模型的自然语言解析能力。&lt;/p&gt;
&lt;p&gt;GDB/MI 的输出更接近结构化协议，例如 result record、exec async record、stream record 都有固定形态。项目里写了一个轻量 MI parser，把 GDB 输出解析成统一的 &lt;code&gt;MIRecord&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^done&lt;/code&gt;、&lt;code&gt;^error&lt;/code&gt; 这类 result record 用来判断命令是否成功&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*stopped&lt;/code&gt;、&lt;code&gt;*running&lt;/code&gt; 这类 async record 用来维护 inferior 状态&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~&lt;/code&gt;、&lt;code&gt;@&lt;/code&gt;、&lt;code&gt;&amp;amp;&lt;/code&gt; 分别对应 console、target、log stream&lt;/li&gt;
&lt;li&gt;token 用来把命令和返回结果关联起来&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样 MCP tool 返回给 agent 的就不是一整段终端文本，而是 JSON 结构：&lt;code&gt;ok&lt;/code&gt;、&lt;code&gt;result_class&lt;/code&gt;、&lt;code&gt;results&lt;/code&gt;、&lt;code&gt;stopped&lt;/code&gt;、&lt;code&gt;console&lt;/code&gt;、&lt;code&gt;target&lt;/code&gt;、&lt;code&gt;async&lt;/code&gt;、&lt;code&gt;raw&lt;/code&gt; 等字段都被拆出来了。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;多会话 
    &lt;div id=&#34;多会话&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e5%a4%9a%e4%bc%9a%e8%af%9d&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h3&gt;
&lt;p&gt;另一个设计点是多会话。&lt;/p&gt;
&lt;p&gt;我不希望这个工具存在“当前正在调试的程序”这种隐式全局状态。Agent 只要跑久一点，就很容易出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上一轮开了一个 GDB 没关&lt;/li&gt;
&lt;li&gt;用户又让它看另一个 binary&lt;/li&gt;
&lt;li&gt;过程中还 attach 了一个进程&lt;/li&gt;
&lt;li&gt;后面一句“继续运行”到底指哪个目标不明确&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 &lt;code&gt;gdb-mcp&lt;/code&gt; 的所有 session 操作都围绕显式 &lt;code&gt;session_id&lt;/code&gt; 展开。&lt;code&gt;SessionManager&lt;/code&gt; 负责创建、查找、关闭 session；每个 &lt;code&gt;GdbSession&lt;/code&gt; 内部维护自己的 GDB 子进程、命令 token、pending command、最近事件、最近命令、last stop 和可选的 gdbserver 子进程。&lt;/p&gt;
&lt;p&gt;这对于 agent 来说很重要。它可以先 &lt;code&gt;gdb_list_sessions&lt;/code&gt; 看当前有哪些会话，再决定复用还是新建；多个程序并行分析时，也不会因为“当前 GDB”被覆盖而混乱。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;命令路由 
    &lt;div id=&#34;命令路由&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e5%91%bd%e4%bb%a4%e8%b7%af%e7%94%b1&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h3&gt;
&lt;p&gt;GDB/MI 比较麻烦的一点是异步。一次命令发出去之后，可能先收到 &lt;code&gt;^running&lt;/code&gt;，随后收到若干 stream record，最后收到 &lt;code&gt;*stopped&lt;/code&gt;；也可能命令本身已经 &lt;code&gt;^done&lt;/code&gt;，但 inferior 还没有停。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gdb-mcp&lt;/code&gt; 的处理方式是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每条命令分配一个递增 token。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_PendingCommand&lt;/code&gt; 记录这个 token 对应的 future、result record、stopped record 和中间 records。&lt;/li&gt;
&lt;li&gt;reader task 持续读取 GDB stdout，解析成 &lt;code&gt;MIRecord&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;根据 token 和 record 类型把输出路由到对应 pending command。&lt;/li&gt;
&lt;li&gt;对 &lt;code&gt;run&lt;/code&gt;、&lt;code&gt;continue&lt;/code&gt;、&lt;code&gt;step&lt;/code&gt; 这类命令，可以设置 &lt;code&gt;wait_for_stop=True&lt;/code&gt;，等到真正停止后再返回。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这比简单地“发一行命令，读到 prompt 就结束”要麻烦，但对调试是必要的。因为 agent 关心的往往不是命令是否发出成功，而是程序现在停在了哪里、为什么停、还能看到什么现场。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;Demo 
    &lt;div id=&#34;demo&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#demo&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;仓库里放了一个最小 demo，用来验证最核心的调试路径：编译一个简单 C 程序，下断点，运行到目标函数，然后让 agent 一次性拿到现场。&lt;/p&gt;
&lt;p&gt;demo 程序如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;value=%d&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;42&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;先编译：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cc -g -gdwarf-4 -O0 examples/hello.c -o /tmp/gdb-mcp-hello
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后在 Codex 或 Claude Code 里，其实只需要给一个比较自然的任务：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Use GDB MCP to debug /tmp/gdb-mcp-hello.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Set a breakpoint at add, run, show the current location, backtrace, locals,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;then continue once.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对应到 MCP tool flow，大致是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;gdb_create_session&lt;/code&gt; 加载 &lt;code&gt;/tmp/gdb-mcp-hello&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_set_breakpoint&lt;/code&gt; 在 &lt;code&gt;add&lt;/code&gt; 下断点&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_run_and_context&lt;/code&gt; 运行到断点并返回现场&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_continue_and_context&lt;/code&gt; 继续运行到程序退出&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_close_session&lt;/code&gt; 关闭 session&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;关键是第三步。传统 GDB wrapper 可能只会告诉 agent “程序停了”，然后 agent 还需要继续问当前 frame、backtrace、locals。&lt;code&gt;gdb_run_and_context&lt;/code&gt; 会把这些信息一起返回，结果类似：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;action: run
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;stop: breakpoint-hit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;location: add at examples/hello.c:3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;backtrace: #0 add:3 &amp;lt;- #1 main:8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;locals: a=2, b=40
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这说明 agent 已经知道程序停在 &lt;code&gt;add&lt;/code&gt;，参数 &lt;code&gt;a&lt;/code&gt; 和 &lt;code&gt;b&lt;/code&gt; 分别是 &lt;code&gt;2&lt;/code&gt;、&lt;code&gt;40&lt;/code&gt;，调用者是 &lt;code&gt;main&lt;/code&gt;。如果继续执行，&lt;code&gt;gdb_continue_and_context&lt;/code&gt; 会返回程序输出：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;value=42
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 class=&#34;relative group&#34;&gt;Context Tool 
    &lt;div id=&#34;context-tool&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#context-tool&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;早期只做基础 GDB wrapper 的时候，我很快发现一个问题：agent 调试程序时，常常会重复发这样的工具序列：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;run / continue / step&lt;/li&gt;
&lt;li&gt;current location&lt;/li&gt;
&lt;li&gt;backtrace&lt;/li&gt;
&lt;li&gt;locals&lt;/li&gt;
&lt;li&gt;根据结果决定下一步&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果每一次执行控制都要再查三次状态，成本高，且上下文容易碎。所以现在提供了一组 &lt;code&gt;*_and_context&lt;/code&gt; 工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gdb_run_and_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_continue_and_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_step_and_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_next_and_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_continue_and_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_step_and_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_next_and_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_finish_and_context&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些工具在执行后会自动收集：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当前 frame&lt;/li&gt;
&lt;li&gt;backtrace&lt;/li&gt;
&lt;li&gt;locals&lt;/li&gt;
&lt;li&gt;stop reason&lt;/li&gt;
&lt;li&gt;target output&lt;/li&gt;
&lt;li&gt;一段 compact summary&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如一个典型结果会包含类似这样的 summary：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;action: run
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;stop: breakpoint-hit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;location: add at /tmp/hello.c:3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;backtrace: #0 add:3 &amp;lt;- #1 main:8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;locals: a=2, b=40
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这其实是给 agent 的“最小可用现场”。它不需要立刻看到所有 MI 原始结果，但如果确实需要，也可以传 &lt;code&gt;include_raw=true&lt;/code&gt; 拿完整 payload。&lt;/p&gt;
&lt;p&gt;我的理解是，这是 GDB MCP 和普通 shell GDB 最大的差别之一：它不只是让 agent 能“调用 GDB”，而是把调试循环中最常用的观察结果整理成适合模型消费的形态。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;工具分层 
    &lt;div id=&#34;工具分层&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b7%a5%e5%85%b7%e5%88%86%e5%b1%82&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;目前工具大致分成几类。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;Session 管理 
    &lt;div id=&#34;session-管理&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#session-%e7%ae%a1%e7%90%86&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h3&gt;
&lt;p&gt;包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gdb_create_session&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_attach&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_load_core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_connect_gdbserver&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_launch_gdbserver&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_list_sessions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_close_session&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里比较在意的是 attach、core 和 gdbserver。因为真实逆向/漏洞分析里，很多目标并不是简单 &lt;code&gt;gdb ./a.out&lt;/code&gt; 就能覆盖：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fuzzing 产生 core，需要加载 core 还原现场&lt;/li&gt;
&lt;li&gt;服务进程已经在运行，需要 attach&lt;/li&gt;
&lt;li&gt;目标跑在容器、虚拟机、远程环境里，需要 gdbserver&lt;/li&gt;
&lt;li&gt;某些场景希望 &lt;code&gt;gdbserver :0&lt;/code&gt; 自动选择端口，再由 MCP 解析实际端口连接&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;gdb_launch_gdbserver&lt;/code&gt; 会启动本地 gdbserver、解析 banner 里的端口、创建 GDB session 并连接上去。如果连接失败，会清理刚创建的 GDB 和 gdbserver，避免留下僵尸进程。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;执行控制 
    &lt;div id=&#34;执行控制&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e6%89%a7%e8%a1%8c%e6%8e%a7%e5%88%b6&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h3&gt;
&lt;p&gt;包括 run、continue、interrupt、signal、step、next、detach、kill，以及 reverse debugging 相关工具。&lt;/p&gt;
&lt;p&gt;Reverse debugging 对自动化分析挺有意义。漏洞触发后，agent 经常知道“这里坏了”，但不知道“什么时候开始坏的”。如果目标和 GDB 支持 process record，就可以从崩溃点往回走：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gdb_start_recording&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_step&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_next&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_reverse_finish&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类能力手动用起来已经很有价值，放到 agent workflow 里会更有想象空间。&lt;/p&gt;

&lt;h3 class=&#34;relative group&#34;&gt;观察与分析 
    &lt;div id=&#34;观察与分析&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e8%a7%82%e5%af%9f%e4%b8%8e%e5%88%86%e6%9e%90&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h3&gt;
&lt;p&gt;常用的包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gdb_context&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_backtrace&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_locals&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_eval_expression&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_registers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_read_memory&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_read_c_string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_disassemble&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_disassemble_current_frame&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_source&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_memory_mappings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_shared_libraries&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_info_files&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些工具的原则是：能用更窄、更语义化的接口解决，就不要让 agent 自己拼 GDB 命令。例如读字符串就给 &lt;code&gt;gdb_read_c_string&lt;/code&gt;，读内存就给 &lt;code&gt;gdb_read_memory&lt;/code&gt;，看当前 PC 附近反汇编就给 &lt;code&gt;gdb_disassemble_current_frame&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这会牺牲一部分 GDB 的自由度，但换来的是更稳定的自动化路径。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;安全边界 
    &lt;div id=&#34;安全边界&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e5%ae%89%e5%85%a8%e8%be%b9%e7%95%8c&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;调试器天然危险。&lt;/p&gt;
&lt;p&gt;GDB 可以 attach 到进程，可以读内存，可以改变量，可以写内存，可以调用 inferior 函数，甚至可以通过 CLI 执行 shell 命令。把这种能力交给 agent，如果没有边界，风险很高。&lt;/p&gt;
&lt;p&gt;所以 &lt;code&gt;gdb-mcp&lt;/code&gt; 默认区分几类能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read：读取调试状态或目标状态&lt;/li&gt;
&lt;li&gt;Execution：运行、继续、中断、attach、detach、kill&lt;/li&gt;
&lt;li&gt;Mutation：修改调试器状态，例如断点、frame、路径&lt;/li&gt;
&lt;li&gt;Unsafe：可能执行目标代码或修改 inferior 状态&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;默认情况下，以下能力是关掉的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gdb_execute&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_call_function&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_set_variable&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_write_memory&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gdb_breakpoint_commands&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;必须显式使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gdb-mcp --unsafe
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;或者：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;GDB_MCP_ALLOW_UNSAFE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; gdb-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此外，安全模式下的表达式求值也做了保守过滤。比如 &lt;code&gt;gdb_eval_expression&lt;/code&gt;、&lt;code&gt;gdb_print&lt;/code&gt;、&lt;code&gt;gdb_set_watchpoint&lt;/code&gt; 会拒绝明显的函数调用、赋值、自增自减和控制字符。这个过滤不是 sandbox，不能当作对恶意输入的完整隔离，但它能防止 agent 在普通“读一下变量”的任务中顺手执行了 &lt;code&gt;puts()&lt;/code&gt; 或改掉目标状态。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;Lazy Proxy 
    &lt;div id=&#34;lazy-proxy&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#lazy-proxy&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;0.3.0&lt;/code&gt; 里一个比较重要的变化是默认入口变成 lazy stdio proxy。&lt;/p&gt;
&lt;p&gt;MCP client 启动时一般会枚举 server 的工具。如果 server 一启动就拉起完整 GDB backend，体验会比较差：用户可能只是打开了一个 Codex 会话，并不一定真的要调试程序，但这时后端已经启动、依赖已经检查、进程也挂着了。&lt;/p&gt;
&lt;p&gt;现在的默认 &lt;code&gt;gdb-mcp&lt;/code&gt; 命令只做一件事：立刻向 MCP client 暴露完整 tool schema，但真正的 backend 等到第一次调用 &lt;code&gt;gdb_*&lt;/code&gt; 工具时才启动。&lt;/p&gt;
&lt;p&gt;这样有几个好处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MCP client 启动更快&lt;/li&gt;
&lt;li&gt;不调试时没有多余 GDB 后端进程&lt;/li&gt;
&lt;li&gt;仍然保留完整工具发现能力&lt;/li&gt;
&lt;li&gt;需要时可以切到独立 backend 或 HTTP backend&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果想显式运行后端，也可以用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gdb-mcp-backend --transport streamable-http --host 127.0.0.1 --port &lt;span class=&#34;m&#34;&gt;8000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;GDB_MCP_BACKEND_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://127.0.0.1:8000/mcp gdb-mcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HTTP transport 默认也应该只绑定 loopback。调试器服务不应该裸露到不可信网络里。&lt;/p&gt;

&lt;h2 class=&#34;relative group&#34;&gt;目前的状态 
    &lt;div id=&#34;目前的状态&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e7%9b%ae%e5%89%8d%e7%9a%84%e7%8a%b6%e6%80%81&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;截至现在，&lt;code&gt;gdb-mcp&lt;/code&gt; 已经具备了我最开始想要的核心形态：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;agent 可以创建多个隔离的 GDB session&lt;/li&gt;
&lt;li&gt;可以调试本地程序、attach 进程、加载 core、连接或启动 gdbserver&lt;/li&gt;
&lt;li&gt;可以用 context tool 低成本获得当前位置、栈和局部变量&lt;/li&gt;
&lt;li&gt;可以做常见的断点、watchpoint、寄存器、内存、反汇编、source 查看&lt;/li&gt;
&lt;li&gt;可以在显式 unsafe 模式下进行更强的修改和调用&lt;/li&gt;
&lt;li&gt;可以通过 lazy proxy 适配 Codex / Claude Code 这类 MCP client 的启动模型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然它还远不是终点。后面我比较想继续做的方向包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更好的 crash triage workflow，比如从 core 自动提取崩溃点、输入、调用链和关键内存&lt;/li&gt;
&lt;li&gt;更适合漏洞挖掘的 heap / allocator 辅助工具（pwndbg？）&lt;/li&gt;
&lt;li&gt;对常见 sanitizer、fuzzer 输出的整合&lt;/li&gt;
&lt;li&gt;更强的远程调试和容器隔离方案&lt;/li&gt;
&lt;li&gt;针对 agent 的调试策略 prompt / workflow 示例&lt;/li&gt;
&lt;li&gt;更细粒度的权限模型，而不是只有 safe / unsafe 两档&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class=&#34;relative group&#34;&gt;小结 
    &lt;div id=&#34;小结&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;
    
    &lt;span
        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100&#34;&gt;
        &lt;a class=&#34;group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline&#34; href=&#34;#%e5%b0%8f%e7%bb%93&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;
    &lt;/span&gt;        
    
&lt;/h2&gt;
&lt;p&gt;我对这个项目的判断是：&lt;strong&gt;agent 做自动化逆向和漏洞挖掘，需要稳定的动态调试接口&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;纯静态分析当然有价值，但很多关键事实只存在于运行时。以前人类逆向工程师会通过 GDB 把这些事实一点点挖出来；如果 agent 要参与这个过程，它就需要一个能保持会话、能结构化观察、能控制风险、能压缩上下文的 GDB 接口。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gdb-mcp&lt;/code&gt; 目前就是朝这个方向做的一版实现。它还不复杂，也不完美，但已经能支撑实际的 agent 调试循环了。&lt;/p&gt;
&lt;p&gt;后面应该会继续沿着“少一点裸命令，多一点面向分析任务的工具”这个方向迭代。&lt;/p&gt;
</description>
      
    </item>
    
  </channel>
</rss>
