# Debugging Tools: Development and Debugging Techniques

[← Back to Rippled II Overview](/core-dev-bootcamp/module02.md)

***

### Introduction

Debugging is an essential skill for any Rippled developer. Whether you're tracking down a subtle transaction processing bug, investigating network connectivity issues, or optimizing performance, having a solid understanding of debugging tools and techniques is critical. The complexity of distributed systems like the XRP Ledger means that effective debugging often requires multiple approaches—from analyzing logs to using debuggers to running controlled experiments.

This deep dive covers the comprehensive toolkit available for debugging Rippled, from basic logging to advanced profiling techniques. You'll learn how to diagnose issues quickly, understand system behavior, and develop confidence in working with the Rippled codebase.

***

### Logging System

#### Overview

Rippled includes a sophisticated logging system that provides detailed visibility into system behavior. Understanding how to configure and use logging effectively is the foundation of debugging Rippled.

#### Log Structure

**Partitions**: Logs are organized by subsystem (partition) **Severity Levels**: Each log entry has a severity level **Timestamps**: All logs include precise timestamps **Context**: Logs include relevant context (account IDs, ledger numbers, etc.)

#### Severity Levels

From most to least verbose:

```
trace   - Extremely detailed, every function call
debug   - Detailed debugging information
info    - General informational messages
warning - Warning conditions
error   - Error conditions
fatal   - Fatal errors that cause termination
```

**Usage Guidelines**:

* **Production**: Use `warning` or `error` to minimize disk I/O
* **Development**: Use `debug` or `trace` for active debugging
* **Investigation**: Temporarily enable `trace` for specific partitions

#### Log Partitions

Major subsystems have their own partitions:

```
Ledger              - Ledger operations
LedgerMaster        - Ledger master coordination
Transaction         - Transaction processing
Consensus           - Consensus rounds
Overlay             - P2P networking
Peer                - Individual peer connections
Protocol            - Protocol message handling
RPC                 - RPC request handling
JobQueue            - Job queue operations
NodeObject          - NodeStore operations
Application         - Application lifecycle
OrderBookDB         - Order book database
PathRequest         - Path finding
ValidatorList       - Validator list management
Amendments          - Amendment processing
```

#### Configuring Logging

**In Configuration File**

Edit `rippled.cfg`:

```ini
[rpc_startup]
{ "command": "log_level", "severity": "warning" }
{ "command": "log_level", "partition": "Transaction", "severity": "trace" }
{ "command": "log_level", "partition": "Consensus", "severity": "debug" }
```

**Via RPC Command**

Dynamic adjustment without restart:

```bash
# Set all partitions to warning
rippled log_level warning

# Set specific partition to trace
rippled log_level Transaction trace

# Set multiple partitions
rippled log_level Consensus debug
rippled log_level Overlay debug
rippled log_level Peer trace
```

**Programmatically**

In code:

```cpp
// Get logger for this partition
beast::Journal j = app_.journal("MyComponent");

// Log at different levels
JLOG(j.trace()) << "Entering function with param: " << param;
JLOG(j.debug()) << "Processing transaction: " << tx.getTransactionID();
JLOG(j.info()) << "Ledger closed: " << ledger.seq();
JLOG(j.warning()) << "Unusual condition detected";
JLOG(j.error()) << "Failed to process: " << error;
JLOG(j.fatal()) << "Critical error, shutting down";
```

#### Log File Location

**Default Locations**:

* **Linux**: `/var/log/rippled/debug.log`
* **macOS**: `~/Library/Application Support/rippled/debug.log`
* **Custom**: Set in `rippled.cfg`:

```ini
[debug_logfile]
/path/to/custom/debug.log
```

#### Log Rotation

Configure log rotation to prevent disk space issues:

```ini
[debug_logfile]
/var/log/rippled/debug.log

# Rotate when file reaches 100MB
# Keep 10 old log files
```

Using system tools (Linux):

```bash
# /etc/logrotate.d/rippled
/var/log/rippled/debug.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}
```

#### Reading Log Files

**Tail Live Logs**:

```bash
tail -f /var/log/rippled/debug.log
```

**Filter by Partition**:

```bash
grep "Transaction:" /var/log/rippled/debug.log
```

**Filter by Severity**:

```bash
grep "ERR" /var/log/rippled/debug.log
```

**Timestamp Range**:

```bash
# Logs between specific times
awk '/2025-01-15 10:00/,/2025-01-15 11:00/' /var/log/rippled/debug.log
```

**Common Patterns**:

```bash
# Find transaction processing
grep "Transaction.*tesSUCCESS" /var/log/rippled/debug.log

# Find consensus rounds
grep "Consensus.*Starting round" /var/log/rippled/debug.log

# Find peer connections
grep "Overlay.*Connected to peer" /var/log/rippled/debug.log

# Find errors
grep -E "ERROR|ERR|Fatal" /var/log/rippled/debug.log
```

***

### Standalone Mode

#### What is Standalone Mode?

Standalone mode runs Rippled as a single-node network where you have complete control:

* **No peers**: Runs without connecting to other nodes
* **Manual ledger close**: You trigger ledger closes
* **Deterministic**: No network randomness
* **Fast**: No consensus delays
* **Isolated**: Perfect for testing

#### Starting Standalone Mode

```bash
rippled --standalone --conf=/path/to/rippled.cfg
```

**Configuration for Standalone**:

```ini
[server]
port_rpc_admin_local
port_ws_admin_local

[port_rpc_admin_local]
port = 5005
ip = 127.0.0.1
admin = 127.0.0.1
protocol = http

[port_ws_admin_local]
port = 6006
ip = 127.0.0.1
admin = 127.0.0.1
protocol = ws

# No peer port needed in standalone

[node_db]
type=NuDB
path=/var/lib/rippled/standalone/db

[database_path]
/var/lib/rippled/standalone
```

#### Using Standalone Mode

**Check Status**:

```bash
rippled server_info
```

Look for:

```json
{
  "result": {
    "info": {
      "build_version": "1.9.0",
      "complete_ledgers": "1-5",
      "peers": 0,
      "server_state": "proposing",
      "standalone": true
    }
  }
}
```

**Submit Transaction**:

```bash
rippled submit '{
  "TransactionType": "Payment",
  "Account": "rN7n7otQDd6FczFgLdlqtyMVrn3HMtthca",
  "Destination": "rLNaPoKeeBjZe2qs6x52yVPZpZ8td4dc6w",
  "Amount": "1000000",
  "Fee": "12",
  "Sequence": 1
}'
```

**Manually Close Ledger**:

```bash
rippled ledger_accept
```

This immediately closes the current ledger and advances to the next one.

**Check Transaction**:

```bash
rippled tx <hash>
```

#### Standalone Mode Workflow

```bash
# 1. Start standalone
rippled --standalone --conf=standalone.cfg

# 2. Fund accounts (in another terminal)
rippled wallet_propose

# 3. Submit transactions
rippled submit <signed_tx>

# 4. Close ledger to include transaction
rippled ledger_accept

# 5. Verify transaction
rippled tx <hash>

# 6. Repeat steps 3-5 as needed
```

#### Advantages for Debugging

**Deterministic Behavior**:

* No network randomness
* Repeatable tests
* Predictable timing

**Complete Control**:

* Manual ledger progression
* No unexpected transactions
* Isolated environment

**Fast Iteration**:

* Instant ledger closes
* No waiting for consensus
* Quick test cycles

**Safe Experimentation**:

* Can't affect mainnet
* Easy to reset (delete database)
* Test dangerous operations safely

***

### GDB Debugging

#### Setting Up GDB

**Install GDB**:

```bash
# Linux
sudo apt-get install gdb

# macOS
brew install gdb
```

**Compile with Debug Symbols**:

```bash
cd rippled/build
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . --target rippled
```

**Launch with GDB**:

```bash
gdb --args ./rippled --conf=/path/to/rippled.cfg --standalone
```

#### Basic GDB Commands

**Starting**:

```gdb
(gdb) run                    # Start program
(gdb) start                  # Start and break at main()
```

**Breakpoints**:

```gdb
(gdb) break Payment.cpp:123  # Break at file:line
(gdb) break Payment::doApply # Break at function
(gdb) break Transactor.cpp:apply # Break at method

(gdb) info breakpoints       # List all breakpoints
(gdb) delete 1               # Delete breakpoint #1
(gdb) disable 2              # Disable breakpoint #2
```

**Execution Control**:

```gdb
(gdb) continue               # Continue execution
(gdb) next                   # Step over (one line)
(gdb) step                   # Step into (enter function)
(gdb) finish                 # Run until current function returns
```

**Inspection**:

```gdb
(gdb) print variable         # Print variable value
(gdb) print *pointer         # Dereference pointer
(gdb) print object.method()  # Call method

(gdb) backtrace              # Show call stack
(gdb) frame 3                # Switch to frame #3
(gdb) info locals            # Show local variables
```

**Advanced**:

```gdb
(gdb) watch variable         # Break when variable changes
(gdb) condition 1 i == 5     # Conditional breakpoint
(gdb) commands 1             # Execute commands at breakpoint
```

#### Debugging Transaction Processing

**Example Session**:

```gdb
# Start GDB with rippled
gdb --args ./rippled --standalone --conf=standalone.cfg

# Set breakpoints
(gdb) break Payment::doApply
(gdb) break Transactor::apply
(gdb) break NetworkOPs::processTransaction

# Run
(gdb) run

# In another terminal, submit transaction
$ rippled submit <signed_tx>

# GDB will break at processTransaction
(gdb) backtrace
#0  NetworkOPs::processTransaction
#1  RPCHandler::doCommand
#2  ...

# Step through
(gdb) next
(gdb) next

# Examine transaction
(gdb) print transaction->getTransactionID()
(gdb) print transaction->getFieldAmount(sfAmount)

# Continue to Payment::doApply
(gdb) continue

# Examine state
(gdb) print account_
(gdb) print ctx_.tx[sfDestination]
(gdb) print view().read(keylet::account(account_))

# Step through payment logic
(gdb) step
(gdb) next

# Check result
(gdb) print result
(gdb) continue
```

#### Debugging Consensus

```gdb
# Set breakpoints in consensus
(gdb) break RCLConsensus::startRound
(gdb) break Consensus::propose
(gdb) break Consensus::peerProposal

# Run
(gdb) run

# When consensus starts
(gdb) print prevLedgerHash
(gdb) print transactions.size()
(gdb) backtrace

# Step through proposal creation
(gdb) step
(gdb) print position_

# Continue to peer proposal handling
(gdb) continue
(gdb) print proposal.position()
(gdb) print peerID
```

#### Debugging Crashes

**Core Dumps**:

Enable core dumps:

```bash
ulimit -c unlimited
```

Run program until crash:

```bash
./rippled --standalone --conf=standalone.cfg
# ... crash occurs
```

Analyze core dump:

```bash
gdb ./rippled core
(gdb) backtrace
(gdb) frame 0
(gdb) info locals
```

**Common Crash Patterns**:

```gdb
# Null pointer dereference
(gdb) print pointer
$1 = 0x0
(gdb) backtrace
# Look for where pointer should have been set

# Segmentation fault
(gdb) print array[index]
# Check if index is out of bounds

# Assert failure
(gdb) backtrace
# Look at assertion condition and surrounding code
```

***

### Log Analysis and Interpretation

#### Transaction Logs

**Successful Payment**:

```
2025-01-15 10:23:45.123 Transaction:DBG Transaction E08D6E9754... submitted
2025-01-15 10:23:45.125 Transaction:TRC Preflight check passed
2025-01-15 10:23:45.126 Transaction:TRC Preclaim check passed
2025-01-15 10:23:45.127 Transaction:DBG Applied to open ledger: tesSUCCESS
2025-01-15 10:23:45.128 Overlay:TRC Relaying transaction to 18 peers
2025-01-15 10:23:50.234 Consensus:DBG Transaction included in consensus set
2025-01-15 10:23:50.456 Transaction:INF Applied to ledger 75234567: tesSUCCESS
```

**Failed Payment**:

```
2025-01-15 10:23:45.123 Transaction:DBG Transaction E08D6E9754... submitted
2025-01-15 10:23:45.125 Transaction:TRC Preflight check passed
2025-01-15 10:23:45.126 Transaction:WRN Preclaim check failed: tecUNFUNDED
2025-01-15 10:23:45.127 Transaction:DBG Rejected: insufficient funds
```

#### Consensus Logs

**Normal Consensus Round**:

```
2025-01-15 10:23:50.000 Consensus:INF Starting consensus round
2025-01-15 10:23:50.001 Consensus:DBG Building initial position: 147 transactions
2025-01-15 10:23:50.010 Consensus:TRC Proposal sent: hash=ABC123...
2025-01-15 10:23:52.123 Consensus:TRC Received proposal from nHU...: 145 txns
2025-01-15 10:23:52.125 Consensus:TRC Received proposal from nHB...: 146 txns
2025-01-15 10:23:52.500 Consensus:DBG Agreement: 145/147 transactions (98%)
2025-01-15 10:23:52.501 Consensus:INF Consensus reached on transaction set
2025-01-15 10:23:52.600 LedgerMaster:INF Ledger 75234567 closed
2025-01-15 10:23:54.000 LedgerMaster:INF Ledger 75234567 validated with 28/35 validations
```

**Disputed Transaction**:

```
2025-01-15 10:23:50.000 Consensus:INF Starting consensus round
2025-01-15 10:23:52.123 Consensus:DBG Transaction TX123 agreement: 65%
2025-01-15 10:23:54.456 Consensus:DBG Transaction TX123 agreement: 75%
2025-01-15 10:23:56.789 Consensus:WRN Transaction TX123 not included: only 75% agreement
2025-01-15 10:23:56.790 Consensus:INF Consensus reached on transaction set (TX123 excluded)
```

#### Network Logs

**Peer Connection**:

```
2025-01-15 10:23:45.123 Overlay:INF Connecting to r.ripple.com:51235
2025-01-15 10:23:45.234 Overlay:DBG TCP connection established
2025-01-15 10:23:45.345 Overlay:TRC TLS handshake complete
2025-01-15 10:23:45.456 Overlay:TRC Protocol handshake: version 2, node nHU...
2025-01-15 10:23:45.567 Overlay:INF Connected to peer nHU... (validator)
2025-01-15 10:23:45.568 Peer:DBG Added to active peers (18/20)
```

**Connection Failure**:

```
2025-01-15 10:23:45.123 Overlay:INF Connecting to bad-peer.example.com:51235
2025-01-15 10:23:50.123 Overlay:WRN Connection timeout
2025-01-15 10:23:50.124 Overlay:DBG Scheduling reconnect in 10 seconds
```

#### Performance Logs

**Slow Ledger Close**:

```
2025-01-15 10:23:50.000 LedgerMaster:INF Closing ledger 75234567
2025-01-15 10:23:55.000 LedgerMaster:WRN Ledger close took 5000ms (expected <2000ms)
2025-01-15 10:23:55.001 Transaction:WRN Applied 500 transactions in 4800ms
2025-01-15 10:23:55.002 OrderBookDB:WRN Order book update took 1200ms
```

***

### Performance Profiling

#### CPU Profiling

**Using perf (Linux)**:

```bash
# Record profile while running
perf record -g ./rippled --standalone --conf=standalone.cfg

# Generate report
perf report

# Generate flamegraph
perf script | stackcollapse-perf.pl | flamegraph.pl > rippled.svg
```

**Using Instruments (macOS)**:

```bash
# Launch with Instruments
instruments -t "Time Profiler" ./rippled --standalone --conf=standalone.cfg
```

**Interpreting Results**:

Look for:

* Hot functions (high CPU usage)
* Unexpected call patterns
* Inefficient algorithms
* Lock contention

#### Memory Profiling

**Using Valgrind**:

```bash
# Memory leak detection
valgrind --leak-check=full ./rippled --standalone --conf=standalone.cfg

# Memory profiler
valgrind --tool=massif ./rippled --standalone --conf=standalone.cfg
ms_print massif.out.12345
```

**Using AddressSanitizer**:

```bash
# Compile with sanitizer
cmake -DCMAKE_BUILD_TYPE=Debug \
      -DCMAKE_CXX_FLAGS="-fsanitize=address" ..
cmake --build . --target rippled

# Run (crashes on memory errors)
./rippled --standalone --conf=standalone.cfg
```

#### Network Profiling

**Wireshark**:

```bash
# Capture traffic
sudo tcpdump -i any port 51235 -w rippled.pcap

# Analyze with Wireshark
wireshark rippled.pcap
```

Filter by:

* Protocol messages
* Connection handshakes
* Bandwidth usage

**Measuring Latency**:

```bash
# Ping peer
rippled ping <peer_ip>

# Check peer latency
rippled peers | grep latency
```

***

### Testing Strategies

#### Unit Testing

**Run All Tests**:

```bash
./rippled --unittest
```

**Run Specific Test Suite**:

```bash
./rippled --unittest=Payment
./rippled --unittest=Consensus
```

**Run with Verbose Output**:

```bash
./rippled --unittest --unittest-log
```

**Writing Tests**:

```cpp
#include <test/jtx.h>

namespace ripple {
namespace test {

class MyTest_test : public beast::unit_test::suite
{
public:
    void testBasicOperation()
    {
        using namespace jtx;
        
        // Create test environment
        Env env(*this);
        
        // Create accounts
        Account alice{"alice"};
        Account bob{"bob"};
        env.fund(XRP(10000), alice, bob);
        
        // Test operation
        env(pay(alice, bob, XRP(100)));
        env.close();
        
        // Verify result
        BEAST_EXPECT(env.balance(bob) == XRP(10100));
    }
    
    void run() override
    {
        testBasicOperation();
    }
};

BEAST_DEFINE_TESTSUITE(MyTest, app, ripple);

} // namespace test
} // namespace ripple
```

#### Integration Testing

**Test Network Setup**:

```bash
# Start multiple rippled instances
./rippled --conf=node1.cfg &
./rippled --conf=node2.cfg &
./rippled --conf=node3.cfg &

# Configure them to peer
rippled --conf=node1.cfg connect localhost:51236
rippled --conf=node2.cfg connect localhost:51237
```

**Test Scenarios**:

* Multi-node consensus
* Network partitions
* Peer discovery
* Transaction propagation

***

### Common Debugging Scenarios

#### Scenario 1: Transaction Not Validating

**Symptoms**: Transaction stuck in pending state

**Debug Steps**:

1. **Check transaction status**:

```bash
rippled tx <hash>
```

2. **Check for sequence gaps**:

```bash
rippled account_info <account>
# Compare Sequence with expected
```

3. **Check logs for rejection**:

```bash
grep "<hash>" /var/log/rippled/debug.log
```

4. **Verify fee is sufficient**:

```bash
rippled server_info | grep "load_factor"
# Fee should be baseFee * loadFactor
```

5. **Check LastLedgerSequence**:

```bash
rippled ledger_current
# Compare with transaction's LastLedgerSequence
```

#### Scenario 2: Consensus Not Progressing

**Symptoms**: Ledger not closing, network stalled

**Debug Steps**:

1. **Check validator connectivity**:

```bash
rippled validators
```

2. **Examine consensus logs**:

```bash
rippled log_level Consensus trace
tail -f /var/log/rippled/debug.log | grep Consensus
```

3. **Check network connectivity**:

```bash
rippled peers
# Verify connected to enough peers
```

4. **Look for disputes**:

```bash
grep "dispute" /var/log/rippled/debug.log
```

#### Scenario 3: High Memory Usage

**Symptoms**: Rippled consuming excessive memory

**Debug Steps**:

1. **Check ledger history**:

```bash
rippled server_info | grep "complete_ledgers"
```

2. **Review configuration**:

```ini
[node_db]
cache_mb=256  # Reduce if too high
```

3. **Profile memory usage**:

```bash
valgrind --tool=massif ./rippled --standalone
ms_print massif.out.12345
```

4. **Check for leaks**:

```bash
valgrind --leak-check=full ./rippled --standalone
```

#### Scenario 4: Slow Ledger Closes

**Symptoms**: Ledgers taking >5 seconds to close

**Debug Steps**:

1. **Enable performance logging**:

```bash
rippled log_level LedgerMaster debug
rippled log_level Transaction debug
```

2. **Check transaction count**:

```bash
grep "Applied.*transactions" /var/log/rippled/debug.log
```

3. **Profile CPU usage**:

```bash
perf record -g ./rippled
perf report
```

4. **Check database performance**:

```bash
# Check NodeStore backend performance
grep "NodeStore" /var/log/rippled/debug.log
```

***

### Hands-On Exercise

#### Exercise: Debug a Transaction Failure

**Objective**: Use debugging tools to diagnose and fix a transaction issue.

**Part 1: Setup**

**Step 1**: Start standalone mode with detailed logging

```bash
# Configure logging
cat > standalone.cfg << EOF
[server]
port_rpc_admin_local

[port_rpc_admin_local]
port = 5005
ip = 127.0.0.1
admin = 127.0.0.1
protocol = http

[node_db]
type=NuDB
path=/tmp/rippled_debug

[database_path]
/tmp/rippled_debug

[rpc_startup]
{ "command": "log_level", "severity": "debug" }
{ "command": "log_level", "partition": "Transaction", "severity": "trace" }
EOF

# Start
rippled --standalone --conf=standalone.cfg
```

**Step 2**: Create test scenario with intentional issue

```javascript
// Create underfunded transaction
const tx = {
  TransactionType: 'Payment',
  Account: 'rN7n7otQDd6FczFgLdlqtyMVrn3HMtthca',
  Destination: 'rLNaPoKeeBjZe2qs6x52yVPZpZ8td4dc6w',
  Amount: '999999999999',  // More than account has
  Fee: '12',
  Sequence: 1
};
```

**Part 2: Debugging Process**

**Step 3**: Submit and observe failure

```bash
rippled submit <signed_tx>
```

**Step 4**: Examine logs

```bash
tail -100 /var/log/rippled/debug.log | grep Transaction
```

Look for:

```
Transaction:TRC Preflight check: passed
Transaction:TRC Preclaim check: failed - tecUNFUNDED_PAYMENT
Transaction:DBG Rejected transaction: insufficient funds
```

**Step 5**: Verify balance

```bash
rippled account_info rN7n7otQDd6FczFgLdlqtyMVrn3HMtthca
```

**Step 6**: Calculate required amount

```javascript
const balance = accountInfo.account_data.Balance;
const reserve = 20000000; // Base reserve
const available = balance - reserve;
console.log(`Available: ${available} drops`);
console.log(`Requested: 999999999999 drops`);
console.log(`Shortfall: ${999999999999 - available} drops`);
```

**Step 7**: Fix and resubmit

```javascript
// Corrected transaction
const fixedTx = {
  ...tx,
  Amount: String(available - 12)  // Account for fee
};
```

**Part 3: Advanced Debugging**

**Step 8**: Debug with GDB

```bash
# Recompile with debug symbols
cd rippled/build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make

# Start with GDB
gdb --args ./rippled --standalone --conf=standalone.cfg
```

**Step 9**: Set breakpoints

```gdb
(gdb) break Payment::preclaim
(gdb) run
```

**Step 10**: Submit transaction (in another terminal)

```bash
rippled submit <signed_tx>
```

**Step 11**: Examine state in GDB

```gdb
# Breakpoint hit
(gdb) print ctx.tx[sfAmount]
(gdb) print (*sleAccount)[sfBalance]
(gdb) print fee
(gdb) print balance < (amount + fee)
# Should be true, causing tecUNFUNDED

(gdb) continue
```

**Analysis Questions**

1. **What error code was returned?**
   * tecUNFUNDED\_PAYMENT
2. **At which validation phase did it fail?**
   * Preclaim (ledger state check)
3. **What was the root cause?**
   * Insufficient balance for payment + fee + reserve
4. **How would you prevent this in client code?**
   * Check balance before submitting
   * Account for reserve requirements
   * Include fee in calculation
5. **What logs helped identify the issue?**
   * Transaction partition trace logs
   * Preclaim failure message

***

### Key Takeaways

#### Core Debugging Skills

✅ **Logging System**: Understand partitions, severity levels, and configuration

✅ **Standalone Mode**: Essential for controlled testing and debugging

✅ **GDB**: Set breakpoints, inspect variables, trace execution

✅ **Log Analysis**: Read and interpret logs to diagnose issues

✅ **Performance Profiling**: Identify bottlenecks and optimize

#### Best Practices

✅ **Start Simple**: Use logs before reaching for debugger

✅ **Reproduce Reliably**: Use standalone mode for consistent reproduction

✅ **Isolate Issues**: Narrow down to specific component

✅ **Read the Code**: Logs point you to code, understand the implementation

✅ **Test Thoroughly**: Write unit tests for bugs you fix

#### Tool Selection

✅ **Logs**: First line of defense, always available

✅ **Standalone Mode**: Controlled environment, fast iteration

✅ **GDB**: Deep inspection, understanding execution flow

✅ **Profiling**: Performance issues, optimization

✅ **Tests**: Regression prevention, continuous validation

***

### Additional Resources

#### Official Documentation

* **XRP Ledger Dev Portal**: [xrpl.org/docs](https://xrpl.org/docs)
* **Rippled Repository**: [github.com/XRPLF/rippled](https://github.com/XRPLF/rippled)
* **Build Instructions**: [github.com/XRPLF/rippled/blob/develop/BUILD.md](https://github.com/XRPLF/rippled/blob/develop/BUILD.md)

#### Debugging Resources

* **GDB Documentation**: [sourceware.org/gdb/documentation](https://sourceware.org/gdb/current/onlinedocs/gdb/)
* **Valgrind Manual**: [valgrind.org/docs/manual](https://valgrind.org/docs/manual/)
* **Linux Perf Wiki**: [perf.wiki.kernel.org](https://perf.wiki.kernel.org/)

#### Codebase References

* `src/ripple/core/impl/JobQueue.cpp` - Job queue debugging
* `src/ripple/app/main/Application.cpp` - Application startup debugging
* `src/test/` - Unit test examples

#### Related Topics

* [Application Layer](/core-dev-bootcamp/module02/application-layer-central-orchestration-and-coordination.md) - Understanding system architecture
* [Transaction Lifecycle](/core-dev-bootcamp/module02/transaction-lifecycle-complete-transaction-journey.md) - Understanding transaction flow
* [Codebase Navigation](/core-dev-bootcamp/module02/codebase-navigation-efficiently-navigating-the-rippled-source.md) - Finding code to debug

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xrpl-commons.org/core-dev-bootcamp/module02/debugging-tools-development-and-debugging-techniques.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
