Appendix: Debugging Guide

Troubleshooting and Diagnostic Techniques

← Back to Building and Integrating Custom RPC Handlers


Introduction

Even with careful coding, issues will arise during RPC handler development. This guide provides systematic approaches to diagnosing and fixing problems, from compilation errors to runtime issues to performance bottlenecks.

The key is having the right tools and techniques to isolate the problem quickly.


Common Compilation Errors

Error 1: Undeclared Identifiers

Error Message:

error: 'jss::my_field' was not declared in this scope

Root Causes:

  • Typo in JSON string constant name

  • Using string literal instead of jss:: constant

  • Missing include file

Solution:

Prevention:

  • Always use jss:: constants from xrpl/protocol/jss.h

  • Check spelling carefully

  • Refer to existing handlers for correct constant names


Error 2: Type Mismatch in RPC Functions

Error Message:

Root Causes:

  • Wrong parameter types

  • Missing required parameters

  • Template specialization issues

Solution:


Error 3: Const Correctness Issues

Error Message:

Root Causes:

  • Discarding const qualifier

  • Passing const reference where non-const expected

  • Missing const in function signature

Solution:


Error 4: Missing Include Files

Error Message:

Solution:

Checklist:

  • RPCHelpers.h for helper functions

  • Context.h for RPC::JsonContext

  • ErrorCodes.h for error constants

  • jss.h for JSON string constants

  • base_uint.h for uint256 and similar

  • AccountID.h if using AccountID directly


Runtime Debugging Techniques

Technique 1: Strategic Logging

Adding Debug Output:

Journal Levels:

  • fatal() - Application stopping

  • error() - Significant problems

  • warning() - Unexpected but recoverable

  • info() - General informational

  • debug() - Detailed diagnostic (hidden in release builds)

  • trace() - Very detailed (rarely used)

Viewing Output:


Technique 2: Using the Debugger (GDB)

Building for Debugging:

Launching Debugger:

GDB Commands:

Common GDB Debugging Pattern:


Technique 3: Using LLDB (macOS)

Similar to GDB but with slightly different syntax:

LLDB Commands:


Technique 4: Analyzing Crashes

When handler crashes (segmentation fault):

Common Crash Scenarios:


Log Level Configuration

Setting Log Levels

In Config File (rippled.cfg):

Command Line:

Common Modules to Debug:

  • rpc - RPC handler execution

  • ledger - Ledger operations

  • transaction - Transaction processing

  • app - Application lifecycle

  • protocol - Protocol messages

  • peer - Network peer communication

Interpreting Log Output

Typical Log Format:

Log Levels Mean:

  • [FATAL] - Rippled about to stop

  • [ERROR] - Handler failed, returned error

  • [WARN] - Unusual condition, but handler succeeded

  • [INFO] - Normal informational messages

  • [DEBUG] - Detailed execution trace (very verbose)

  • [TRACE] - Extremely detailed (rarely used)


Testing Strategies

Strategy 1: Unit Testing Handlers

Test File Structure (src/test/rpc/handlers/MyHandler_test.cpp):

Running Tests:


Strategy 2: Integration Testing

Testing with Live Ledger:


Strategy 3: Performance Testing

Measuring Handler Execution Time:


Performance Troubleshooting

Issue: Handler is Slow

Diagnostic Steps:

  1. Add timing logs:

  1. Identify bottleneck:

  1. Optimize identified bottleneck:

    • Cache frequently accessed values

    • Minimize ledger reads

    • Use indexed lookups when available

    • Avoid redundant computations

Issue: High Memory Usage

Diagnostic:


Checklist: Debug Workflow

When your handler isn't working:


Resources

Debugging Tools:

  • GDB: https://sourceware.org/gdb/

  • LLDB: https://lldb.llvm.org/

  • Valgrind: https://valgrind.org/ (memory debugging)

Rippled Specific:

  • Source: https://github.com/XRPLF/rippled

  • Build docs: Rippled documentation

  • Community: XRPL Discord #coredev channel


← Back to Appendices | Helper Functions


Related Module Sections:

Last updated