Skip to content

DebugMCP accepts complex GDB expressions but returns empty output for C struct/array inspection #100

Description

@XIAO-Q7

DebugMCP accepts complex GDB expressions but returns empty output for C struct/array inspection

Summary

In embedded C/C++ debugging, DebugMCP can successfully start a debug session, hit breakpoints, and read simple registers/scalars, but it does not reliably surface readable output for complex C/GDB expressions involving structs, arrays, byte buffers, and typed address casts.

The main failure mode is not expression parsing. The command appears to execute successfully, but the returned result contains resultClass: done with empty output.

Environment

  • Target: Cortex-M embedded firmware
  • VS Code debug adapter: Cortex-Debug
  • Session type: Cortex-Debug-backed GDB session inside VS Code
  • Debug server: JLink GDB Server
  • Debugger: arm-none-eabi-gdb
  • DebugMCP used through VS Code

Repro

At a halted frame in C code, with a local variable like:

ARM_ETH_MAC_ADDR pxMAC_ADDR = { 0 };

and with a known address like 0x2001d17c, try the following through DebugMCP evaluate_expression:

p pxMAC_ADDR
p *(ARM_ETH_MAC_ADDR *)0x2001d17c
print/x pxMAC_ADDR.b[0]
x/6bx &pxMAC_ADDR.b[0]

Actual behavior

The expressions are accepted and do not report parse errors, but the returned result is often effectively empty, for example:

resultClass: done
output: ""

Similarly, local variable inspection can show that a variable exists, but only as a collapsed summary:

pxMAC_ADDR: {...} (ARM_ETH_MAC_ADDR)

without exposing the struct fields or byte array contents.

Expected behavior

DebugMCP should return the actual textual output produced by GDB for these expressions, for example:

{b = {0x46, 0x29, 0x04, 0xb4, 0x78, 0xd8}}

or:

0x2001d17c: 0x46 0x29 0x04 0xb4 0x78 0xd8

For variable inspection, structs and arrays should be expandable instead of only returning {...}.

Control comparison

Running the same commands in external arm-none-eabi-gdb against the same halted target works correctly and prints valid output, for example:

$1 = {b = {0x46, 0x29, 0x4, 0xb4, 0x78, 0xd8}}
0x2001d17c:     0x46    0x29    0x04    0xb4    0x78    0xd8

Simple register reads also work correctly through the same setup, for example:

info registers sp
p/x $sp

returns:

sp             0x2001d170          0x2001d170
$1 = 0x2001d170

This suggests the problem is not basic debugger connectivity, but specifically how DebugMCP captures and surfaces complex C/C++ value output.

Suspected root cause

Possible causes:

  1. evaluate_expression forwards commands to GDB but does not fully capture console/text output.
  2. get_variables_values only returns summarized values and does not recursively expand structs/arrays.
  3. Complex C/C++ debug value rendering is incomplete compared to scalar/register handling.

Why this matters

This makes DebugMCP much less useful in common embedded debugging scenarios where the important runtime data is stored in:

  • structs
  • byte arrays
  • packet headers
  • register blocks
  • typed memory views

Requested improvement

  1. Make evaluate_expression reliably return GDB text output for commands like p, print, p/x, and x/....
  2. Make get_variables_values expand struct fields and array elements.
  3. Distinguish between:
    • command succeeded and produced no output
    • command succeeded but output was not captured
    • command failed

Minimal acceptance criteria

  • evaluate_expression("p var") returns printed text for struct values.
  • evaluate_expression("x/6bx addr") returns byte-dump output.
  • Typed address-cast expressions such as p *(ARM_ETH_MAC_ADDR *)0x2001d17c return readable struct contents.
  • Structs and arrays are expandable in variable inspection.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions