Skip to content

Implement GDB Server endpoint#406

Open
Krilliac wants to merge 10 commits into
mangoszero:masterfrom
Krilliac:master
Open

Implement GDB Server endpoint#406
Krilliac wants to merge 10 commits into
mangoszero:masterfrom
Krilliac:master

Conversation

@Krilliac

@Krilliac Krilliac commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

This change is Reviewable

claude and others added 7 commits June 29, 2026 06:53
Port the DuetOS GDB-server system to MaNGOS Zero so a debugger or an AI
agent can attach to the running mangosd and drive it: read process memory,
inspect live game state, and run server commands over one endpoint.

Two layers, matching the DuetOS design:
- Native: a transport-agnostic GDB Remote Serial Protocol (RSP) stub over
  TCP (gdb / lldb / IDA). Framing, checksum, qSupported, ?, g/G (synthetic
  registers), guarded m/M memory, H, c/s/D/k, vCont, qRcmd.
- Semantic: 'monitor mangos <verb>' commands (status, players, tick,
  session, config, and a 'cmd' bridge to the full ChatCommand surface),
  also exposed on a plain-text TCP bridge for AI agents and non-RSP
  debuggers (WinDbg/CDB/x64dbg attach natively + use the bridge).

The kernel NMI-freeze stop is replaced by a cooperative world-tick stop:
the world thread runs the RSP pump loop (pausing the 50ms tick) while the
ACE network thread only shuttles bytes. The stop loop honours
World::IsStopped() so a paused server can still shut down.

Memory access is guarded (Linux /proc/self/maps, Windows VirtualQuery) so
a bad debugger address returns an RSP error instead of crashing.

New subsystem: src/game/Debug/GdbServer/ (RSP core, monitor, verbs,
guarded memory, facade) + src/mangosd/GdbServerThread (ACE listener
modeled on RAThread). Config-gated, disabled by default, localhost bind.
See doc/GdbServer.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L1LfL8h1fGgLYjsfvyhEo
Reword header comments and documentation to describe the debug endpoint as
a native mangosd feature built on the GDB Remote Serial Protocol, removing
references to the upstream project and kernel-debugging framing. No
behavioural change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L1LfL8h1fGgLYjsfvyhEo
Build on the Phase 1 endpoint with the in-process debugging features that
let a debugger or AI agent genuinely drive the server:

- Live register capture: at any stop the world thread's real registers are
  captured (Linux getcontext, Windows RtlCaptureContext on x86_64) and
  returned by the 'g' packet, so gdb can backtrace the actual call stack
  through the 'm' memory packets.
- Game-level breakpoints: arm pauses on a received opcode, on player
  map-entry, or on a named label. When one fires and a debugger is attached,
  the world thread stops inline at the call site, captures context, and waits
  for resume. Driven over the monitor surface (mangos break ...). Hot-path
  cost is a single relaxed atomic load when nothing is armed; an
  armed-but-unattended breakpoint never stalls the server.
- monitor mangos dump: world-thread backtrace (Linux symbols; addresses
  elsewhere).

Wired demonstration call sites: opcode dispatch (WorldSession::Update) and
player map-entry (Player::AddToWorld), each behind a GDB_BREAK_* macro.

Native instruction breakpoints / hardware single-step are intentionally not
implemented: patching int3 or self-setting debug registers in a live
multi-threaded server is unsafe; the cooperative game-level breakpoints are
the supported equivalent. See doc/GdbServer.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L1LfL8h1fGgLYjsfvyhEo
…overage

Replace the opcode/map/label-specific breakpoint engine with a generic
(event, filter) model and wire breakpoints across every major gameplay
subsystem, so a debugger or AI agent can pause the server on essentially any
in-game event.

Engine (GdbBreakpoints):
- 21 event families in a single enum; armed set tracked as a per-event
  bitmask, so the call-site guard is one relaxed atomic load.
- Each breakpoint is an event plus an optional numeric filter (0 = any), e.g.
  spell id, map id, quest id, creature entry.
- Name<->event table drives the monitor surface: mangos break
  events|list|clear|<event> [filter]|del <event> [filter].
- Stops never nest (reentrancy guard) so a breakpoint that fires from a
  command run while already stopped is ignored.

Wired call sites: opcode dispatch, login, logout, map enter, map leave,
spell cast, spell prepare, unit death, damage dealt, level up, loot, quest
accept/complete/reward, chat, item use, gossip select, creature create,
game-object use, command parse, and world tick (single-step the world loop).

Each fires inline on the world thread, captures live registers, and waits —
only while a debugger is attached, so an armed-but-unattended breakpoint
never stalls the server. New sites need a single GDB_BREAK(event, detail).

Verified the engine end-to-end (event listing, arm/list/clear, filter
matching, register-published 'g', monitor encode/decode) with the standalone
protocol test. Docs updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L1LfL8h1fGgLYjsfvyhEo
Prepare for wide subsystem coverage by relocating the breakpoint event
enum to the shared layer and adding a lightweight bridge so lower-layer
systems can raise game-level breakpoints.

- New shared/Debug/GdbEvents.h: GdbEvent enum (55 event families, <= 64 so
  the armed set stays a single bitmask), shared by both libraries.
- New shared/Debug/DebugBreakHook: a function-pointer shim (armed-mask
  getter + hit handler) that the game engine registers at startup, letting
  shared subsystems raise breakpoints without depending on game. Inert
  until registered. GDB_BREAK_SHARED() macro for shared call sites.
- GdbBp now aliases the shared enum, expands its name table to all 55
  events, and registers the bridge in GdbServer::Init.
- Wire the first shared-layer hooks: SQL query (DbQuery) and statement
  (DbExecute) execution in MySQLConnection.

Verified the engine end-to-end with the standalone protocol test (all 55
events list/arm/match) and -fsyntax-only across the debug subsystem.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L1LfL8h1fGgLYjsfvyhEo
Wire game-level breakpoint hooks across every major subsystem via the event
model, taking total coverage to ~55 events / 53 call sites.

Added hooks:
- Netcode/auth: WorldSocket accept/close, HandleAuthSession, SendPacket.
- Warden: check request and violation handling.
- Scripting: creature AI selection (CreatureAISelector).
- Creature AI: enter/leave combat, AI update, respawn.
- Maps/instances: map create, grid load, dungeon create, instance reset.
- Economy/social: mail send/receive, auction list/bid, trade complete,
  group join.
- BG/pet/item/pvp/move: battleground start/end, pet summon, item
  equip/destroy, honorable kill, movement inform.
- Database (shared layer): SQL query/execute via the registered bridge.

These were discovered and applied by a parallel agent workflow, then
hand-audited: three insertions that the literal anchor placement put inside
an if-condition / constructor initializer lists were relocated into the
function bodies, and three detail expressions referencing not-yet-declared
packet locals were reduced to filter 0. Every call site was checked for
correct include, scope-valid detail expression, and statement-boundary
placement.

Docs updated with the full event catalogue.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L1LfL8h1fGgLYjsfvyhEo
@codacy-production

codacy-production Bot commented Jun 29, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 436 complexity · 5 duplication

Metric Results
Complexity 436
Duplication 5

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@Krilliac Krilliac changed the title Temp Implement GDB Server endpoint Jun 29, 2026
claude and others added 2 commits July 2, 2026 00:33
Fix the three high-severity issues Codacy flagged on the PR:

- GdbServer::CaptureContext now returns void and is called unconditionally;
  the register snapshot is published either way (zeroed on architectures
  without a capture path), removing the "condition is always false" warning.
- Value-initialize GdbSocketBase::outputBuffer and GdbMonSocket::inputBuffer
  in their constructors (uninitialized-member warnings).

No behavioural change: on x86_64 the captured registers are identical; on
other targets the reply is the same zeroed register block as before.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L1LfL8h1fGgLYjsfvyhEo
Merge upstream mangoszero/server master (09b4d1f) into Krilliac/server-Zero
master to make PR mangoszero#406 mergeable. All six conflicts were additive collisions
between the GDB-server feature and upstream additions, resolved as unions:

- mangosd.cpp: keep both the GDB-server includes/thread and upstream's
  WorkerSupervisor/MangosdTest includes and the AH-supervisor shutdown block.
- mangosd/CMakeLists.txt: keep both GdbServerThread and MangosdTest sources.
- mangosd.conf.dist.in: keep both the GdbServer and AH.Service config blocks.
- Map.cpp / MailHandler.cpp / AuctionHouseHandler.cpp: keep both the
  GdbBreakpoints include and upstream's new includes.

No logic changes; every conflict was include/config/cleanup ordering.
@AppVeyorBot

Copy link
Copy Markdown

# Conflicts:
#	src/game/BattleGround/BattleGround.cpp
#	src/game/Object/GameObject.cpp
#	src/game/Object/Player.cpp
#	src/game/WorldHandlers/Spell.cpp
@AppVeyorBot

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants