Command documentation sourced from the linux-command project This comprehensive command reference is part of the linux-command documentation project.
valgrind - Memory Debugging and Profiling Tool
The valgrind command is a suite of tools for debugging and profiling Linux programs. It includes Memcheck, a memory error detector that can detect memory leaks, invalid memory access, use of undefined values, and other memory-related problems. Valgrind is an essential tool for C/C++ development, helping developers find subtle bugs that often go undetected by compilers and traditional debuggers. The framework provides dynamic analysis tools that work with unmodified executables, making it invaluable for finding memory management issues, performance bottlenecks, and thread safety problems in complex applications.
Basic Syntax
valgrind [valgrind options] [program options]
valgrind --tool=<tool> [tool options] [program options]
valgrind [options] <executable> [executable arguments]
Core Tools Overview
Memcheck (Default Tool)
Memory Error Detector
- Detects memory management problems
- Finds leaks, invalid reads/writes, use of uninitialized values
- Identifies mismatched allocation/deallocation functions
- Most commonly used valgrind tool for memory debugging
Cachegrind
Cache and Branch Prediction Profiler
- Simulates L1, L2, and last-level cache performance
- Provides branch prediction statistics
- Helps identify cache-related performance bottlenecks
- Generates detailed cache miss and branch misprediction reports
Callgrind
Call Graph Profiler
- Extends Cachegrind with call graph analysis
- Tracks function call relationships and frequencies
- Provides detailed execution path analysis
- Integration with KCachegrind for visualization
Massif
Heap Profiler
- Tracks detailed memory allocation patterns
- Shows memory usage over time
- Identifies memory allocation hotspots
- Helps with memory usage optimization
Helgrind
Thread Error Detector
- Detects data races in multi-threaded programs
- Identifies pthreads API usage errors
- Finds potential deadlocks and lock order violations
- Essential for concurrent programming debugging
DRD (Data Race Detector)
Alternative Thread Error Detector
- Uses different algorithms than Helgrind
- Often detects different classes of errors
- Lower runtime overhead in some scenarios
- Complementary to Helgrind for thorough analysis
General Valgrind Options
Tool Selection
--tool=<tool>- Specify which tool to use (memcheck, cachegrind, callgrind, massif, helgrind, drd)--help-debug- Show debugging options for the selected tool
Process Control
--trace-children=<yes|no>- Follow into child processes (default: no)--trace-children-skip=<patt1,patt2,...>- Skip tracing certain child processes--child-silent-after-fork=<yes|no>- Suppress output from child processes after fork--run-libc-freeres=<yes|no>- Run glibc's memory freeing function at exit
Memory and Performance
--max-frames=<number>- Maximum stack frames to show (default: 12)--main-stacksize=<number>- Set main thread's stack size--sim-hints=<hint1,hint2,...>- Pass hints to simulation engine--kernel-variant=<variant1,variant2,...>- Handle kernel variants
Output Control
--log-file=<filename>- Write output to file--log-fd=<number>- Write output to file descriptor--xml=<yes|no>- Output in XML format (default: no)--xml-file=<filename>- XML output file--xml-fd=<number>- XML output file descriptor--quiet- Suppress startup messages--verbose- Verbose output--demangle=<yes|no>- Automatically demangle C++ names
Error Control
--error-limit=<yes|no>- Stop showing errors after 1000 different errors--error-exitcode=<number>- Exit code to return if errors found (default: 0)--show-error-list=<yes|no>- Show suppressed errors list at exit--keep-debuginfo=<yes|no>- Keep debug info after unload
Memcheck Tool Options
Memory Leak Detection
--leak-check=<no|summary|full>- Check for memory leaks (default: summary)--leak-resolution=<low|med|high>- Leak resolution level (default: high)--show-leak-kinds=<kind1,kind2,...>- Leak kinds to detect (definite,indirect,possible,reachable)--show-possibly-lost=<yes|no>- Show possibly lost blocks (default: yes)--track-origins=<yes|no>- Track origins of uninitialized values--keep-stacktraces=<alloc|free|alloc-and-free|none>- Stack traces to keep
Memory Checking Options
--undef-value-errors=<yes|no>- Check for undefined value errors--partial-loads-ok=<yes|no>- Allow partial loads from invalid addresses--freelist-vol=<number>- Volume of freed blocks queue--workaround-gcc296-bugs=<yes|no>- Work around GCC 2.96 bugs--malloc-fill=<hex>- Fill allocated memory with byte value--free-fill=<hex>- Fill freed memory with byte value
Tracking and Suppression
--track-fds=<yes|no>- Track open file descriptors (default: no)--suppressions=<filename>- Load suppressions from file--gen-suppressions=<no|yes|all>- Generate suppressions for errors--suppressions-print-all=<yes|no>- Print all suppressed errors
Usage Examples
Basic Memory Debugging
Simple Memory Checks
# Run program with Memcheck (default tool)
valgrind ./myprogram
# Run with arguments
valgrind ./myprogram --input data.txt --verbose
# Full leak checking with detailed output
valgrind --leak-check=full --show-leak-kinds=all ./myprogram
# Quiet mode for automated testing
valgrind --quiet --leak-check=full ./myprogram
# Track file descriptors along with memory
valgrind --track-fds=yes --leak-check=full ./myprogram
Enhanced Error Reporting
# Increase call stack depth for better error reporting
valgrind --num-callers=20 --leak-check=full ./myprogram
# Track origins of uninitialized values
valgrind --track-origins=yes ./myprogram
# Show all reachable blocks for comprehensive analysis
valgrind --leak-check=full --show-leak-kinds=all ./myprogram
# Generate suppressions for known issues
valgrind --gen-suppressions=all ./myprogram > suppressions.supp
# Use custom suppressions file
valgrind --suppressions=mycustom.supp ./myprogram
Output Management
# Save output to file with timestamp
valgrind --log-file=valgrind_$(date +%Y%m%d_%H%M%S).log ./myprogram
# XML output for automated analysis
valgrind --xml=yes --xml-file=valgrind.xml ./myprogram
# Combine XML with detailed leak checking
valgrind --xml=yes --xml-file=analysis.xml --leak-check=full ./myprogram
# Exit with error code if memory issues found
valgrind --error-exitcode=1 --leak-check=full ./myprogram
Advanced Memory Analysis
Detailed Heap Profiling
# Track all memory allocation sites
valgrind --tool=massif --stacks=yes --alloc-fn=malloc --alloc-fn=calloc ./myprogram
# Detailed heap profiling with high-frequency snapshots
valgrind --tool=massif --detailed-freq=5 --threshold=0.1 ./myprogram
# Massif with specific output file
valgrind --tool=massif --massif-out-file=memory_analysis ./myprogram
# Analyze memory allocation patterns
valgrind --tool=massif --heap=yes --depth=20 ./myprogram
Memory Error Pattern Analysis
# Fill memory with known patterns for debugging
valgrind --malloc-fill=0xCD --free-fill=0xEF ./myprogram
# Check for overlapping memory blocks
valgrind --check-heap=yes --leak-check=full ./myprogram
# Comprehensive error tracking with high resolution
valgrind --leak-check=full --leak-resolution=high --track-origins=yes ./myprogram
# Monitor specific memory regions
valgrind --redzone-size=64 --leak-check=full ./myprogram
Performance Profiling with Cachegrind
Cache Performance Analysis
# Run with Cachegrind for cache simulation
valgrind --tool=cachegrind ./myprogram
# Generate branch prediction statistics
valgrind --tool=cachegrind --branch-sim=yes ./myprogram
# Cache simulation with L1, L2, and LL cache
valgrind --tool=cachegrind --cache-sim=yes ./myprogram
# Custom cache configuration
valgrind --tool=cachegrind --I1=32768,8,64 --D1=32768,8,64 --L2=2097152,8,64 ./myprogram
Advanced Cachegrind Analysis
# Save cache analysis to specific file
valgrind --tool=cachegrind --cachegrind-out-file=cache_analysis.out ./myprogram
# Generate branch prediction with detailed info
valgrind --tool=cachegrind --branch-sim=yes --cachegrind-out-file=branch_analysis.out ./myprogram
# Combine cache and branch simulation
valgrind --tool=cachegrind --cache-sim=yes --branch-sim=yes ./myprogram
# Analyze specific functions with function scanning
valgrind --tool=cachegrind --fn-scan=yes ./myprogram
Cache Performance Optimization
# Compare different cache configurations
valgrind --tool=cachegrind --I1=16384,4,32 --D1=16384,4,32 ./myprogram
# Analyze instruction cache performance
valgrind --tool=cachegrind --I1=65536,16,64 ./myprogram
# Data cache optimization analysis
valgrind --tool=cachegrind --D1=65536,16,64 --L2=4194304,16,64 ./myprogram
# Profile with specific cache line size
valgrind --tool=cachegrind --cachegrind-out-file=cache_opt.out ./myprogram
Call Graph Profiling with Callgrind
Function Call Analysis
# Run with Callgrind for detailed call graph
valgrind --tool=callgrind ./myprogram
# Collect detailed instruction-level information
valgrind --tool=callgrind --dump-instr=yes ./myprogram
# Function-level profiling only (faster)
valgrind --tool=callgrind --dump-line=no ./myprogram
# Combine with cache simulation
valgrind --tool=callgrind --cache-sim=yes ./myprogram
Advanced Callgrind Profiling
# Generate call graph with specific output file
valgrind --tool=callgrind --callgrind-out-file=callgraph.out ./myprogram
# Collect information about specific functions
valgrind --tool=callgrind --fn-name=main --fn-name=process_data ./myprogram
# Profile with automatic cache simulation
valgrind --tool=callgrind --collect-jumps=yes ./myprogram
# Track function entry and exit events
valgrind --tool=callgrind --collect-systime=yes ./myprogram
Callgrind Visualization and Analysis
# Analyze with callgrind_annotate command-line tool
callgrind_annotate callgrind.out.*
# Generate human-readable report
callgrind_annotate --auto=yes callgrind.out.*
# Sort by function calls
callgrind_annotate --sort=A:B callgrind.out.*
# Use with KCachegrind GUI for visualization
kcachegrind callgrind.out.*
Thread Debugging with Helgrind
Race Condition Detection
# Run multi-threaded program with Helgrind
valgrind --tool=helgrind ./mythreaded_program
# Track thread creation and destruction
valgrind --tool=helgrind --track-lockorders=yes ./myprogram
# Show detailed race condition information
valgrind --tool=helgrind --show-error-list=yes ./myprogram
# Comprehensive race condition analysis
valgrind --tool=helgrind --history-level=full ./myprogram
Advanced Thread Safety Analysis
# Check for deadlocks and lock order violations
valgrind --tool=helgrind --check-stack-var=yes ./myprogram
# Detailed synchronization analysis with large conflict cache
valgrind --tool=helgrind --conflict-cache-size=1000000 ./myprogram
# Track memory access patterns
valgrind --tool=helgrind --segment-merging=yes ./myprogram
# Analyze specific thread functions
valgrind --tool=helgrind --helgrind-out-file=thread_analysis ./myprogram
Thread Performance Analysis
# Minimal overhead for basic race detection
valgrind --tool=helgrind --history-level=approx ./myprogram
# Track only essential operations
valgrind --tool=helgrind --history-level=none ./myprogram
# High precision thread analysis
valgrind --tool=helgrind --trace-malloc=yes ./myprogram
Practical Development Workflow
Memory Leak Detection in Development
# Compile with debug symbols for meaningful output
gcc -g -O0 -Wall -o myprogram myprogram.c
# Basic memory leak check
valgrind --leak-check=full --show-leak-kinds=definite ./myprogram
# Comprehensive memory analysis
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./myprogram
# Automated testing with error detection
valgrind --quiet --error-exitcode=1 --leak-check=full ./myprogram
# Generate report for team review
valgrind --leak-check=full --log-file=memory_report.txt --show-leak-kinds=all ./myprogram
Performance Optimization Workflow
# Step 1: Identify performance bottlenecks
valgrind --tool=callgrind ./myprogram
kcachegrind callgrind.out.*
# Step 2: Analyze cache performance
valgrind --tool=cachegrind --cache-sim=yes ./myprogram
cg_annotate cachegrind.out.*
# Step 3: Profile memory usage patterns
valgrind --tool=massif --stacks=yes ./myprogram
ms_print massif.out.*
# Step 4: Comprehensive analysis
valgrind --tool=callgrind --cache-sim=yes --callgrind-out-file=comprehensive.out ./myprogram
Regression Testing Integration
#!/bin/bash
# regression_memory_test.sh
PROGRAM="./myprogram"
LOG_FILE="regression_test.log"
ERROR_CODE=1
echo "Running memory regression tests..."
# Test for memory leaks
valgrind --quiet --leak-check=full --error-exitcode=$ERROR_CODE --log-file=$LOG_FILE $PROGRAM
if [ $? -eq 0 ]; then
echo "✓ Memory leak test passed"
else
echo "✗ Memory leak test failed. Check $LOG_FILE"
exit 1
fi
# Test for race conditions in multi-threaded code
valgrind --quiet --tool=helgrind --error-exitcode=$ERROR_CODE --log-file=thread_test.log $PROGRAM
if [ $? -eq 0 ]; then
echo "✓ Thread safety test passed"
else
echo "✗ Thread safety test failed. Check thread_test.log"
exit 1
fi
echo "All memory tests passed successfully"
Integration with Build Systems
Makefile Integration
# Memory check target
memcheck: $(TARGET)
valgrind --leak-check=full --error-exitcode=1 --show-leak-kinds=all ./$(TARGET)
# Performance profiling target
profile: $(TARGET)
valgrind --tool=callgrind --callgrind-out-file=callgrind.out ./$(TARGET)
@echo "Run 'kcachegrind callgrind.out' to view results"
# Thread safety check
helgrind: $(TARGET)
valgrind --tool=helgrind --error-exitcode=1 ./$(TARGET)
# Cache performance analysis
cachegrind: $(TARGET)
valgrind --tool=cachegrind --cachegrind-out-file=cache.out ./$(TARGET)
cg_annotate cache.out
# Heap profiling
massif: $(TARGET)
valgrind --tool=massif --massif-out-file=massif.out ./$(TARGET)
ms_print massif.out
# Comprehensive analysis
analyze: $(TARGET)
@echo "Running comprehensive analysis..."
$(MAKE) memcheck
$(MAKE) helgrind
$(MAKE) profile
@echo "Analysis complete"
.PHONY: memcheck profile helgrind cachegrind massif analyze
CMake Integration
# Add custom targets for valgrind analysis
find_program(VALGRIND_EXECUTABLE valgrind)
if(VALGRIND_EXECUTABLE)
add_custom_target(memcheck
COMMAND ${VALGRIND_EXECUTABLE} --leak-check=full --error-exitcode=1 $<TARGET_FILE:${PROJECT_NAME}>
DEPENDS ${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Running memory leak check with valgrind"
)
add_custom_target(thread-check
COMMAND ${VALGRIND_EXECUTABLE} --tool=helgrind --error-exitcode=1 $<TARGET_FILE:${PROJECT_NAME}>
DEPENDS ${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Running thread safety check with helgrind"
)
add_custom_target(profile
COMMAND ${VALGRIND_EXECUTABLE} --tool=callgrind $<TARGET_FILE:${PROJECT_NAME}>
DEPENDS ${PROJECT_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Running call graph profiling with callgrind"
)
endif()
Continuous Integration Pipeline
#!/bin/bash
# ci_memory_analysis.sh
set -e
PROJECT_NAME="myproject"
BUILD_DIR="build"
RESULTS_DIR="valgrind_results"
echo "Setting up continuous integration memory analysis..."
# Create results directory
mkdir -p $RESULTS_DIR
# Build project with debug symbols
mkdir -p $BUILD_DIR
cd $BUILD_DIR
cmake -DCMAKE_BUILD_TYPE=Debug ..
make -j$(nproc)
cd ..
# Run memory leak detection
echo "Running memory leak detection..."
valgrind --leak-check=full --show-leak-kinds=all --xml=yes --xml-file=$RESULTS_DIR/memcheck.xml ./$BUILD_DIR/$PROJECT_NAME
# Run thread safety check
echo "Running thread safety check..."
valgrind --tool=helgrind --xml=yes --xml-file=$RESULTS_DIR/helgrind.xml ./$BUILD_DIR/$PROJECT_NAME
# Run performance profiling
echo "Running performance profiling..."
valgrind --tool=callgrind --callgrind-out-file=$RESULTS_DIR/callgrind.out ./$BUILD_DIR/$PROJECT_NAME
# Generate human-readable reports
echo "Generating analysis reports..."
callgrind_annotate $RESULTS_DIR/callgrind.out > $RESULTS_DIR/performance_report.txt
# Check for errors in XML output
if grep -q "error" $RESULTS_DIR/memcheck.xml; then
echo "Memory errors detected!"
exit 1
fi
if grep -q "error" $RESULTS_DIR/helgrind.xml; then
echo "Thread errors detected!"
exit 1
fi
echo "All memory analysis checks passed!"
Advanced Debugging Scenarios
Complex Memory Leak Analysis
# Track indirect leaks through complex data structures
valgrind --leak-check=full --show-leak-kinds=definite,indirect ./complex_program
# High-resolution leak tracking with deep stack traces
valgrind --leak-check=full --leak-resolution=high --num-callers=30 ./myprogram
# Track memory leaks across fork/exec boundaries
valgrind --trace-children=yes --leak-check=full ./parent_program
# Analyze specific memory allocation patterns
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./myprogram
Performance Bottleneck Identification
# Identify hot functions with call graph analysis
valgrind --tool=callgrind --collect-jumps=yes --simulate-cache=yes ./performance_critical_app
# Cache miss analysis for optimization
valgrind --tool=cachegrind --cache-sim=yes --branch-sim=yes ./myprogram
# Function-level profiling with instruction counting
valgrind --tool=callgrind --dump-instr=yes --collect-systime=yes ./myprogram
# Memory allocation hotspot analysis
valgrind --tool=massif --alloc-fn=malloc --alloc-fn=calloc --stacks=yes ./memory_intensive_app
Thread Safety Verification
# Comprehensive race condition detection
valgrind --tool=helgrind --history-level=full --check-stack-var=yes ./multithreaded_app
# Lock order dependency analysis
valgrind --tool=helgrind --track-lockorders=yes ./threaded_application
# Low overhead race detection for long-running applications
valgrind --tool=helgrind --history-level=approx --conflict-cache-size=2000000 ./server_app
# Deadlock detection in complex synchronization code
valgrind --tool=helgrind --show-error-list=yes ./sync_critical_app
Specialized Analysis Scenarios
Embedded Systems Debugging
# Memory analysis for resource-constrained environments
valgrind --max-frames=8 --leak-check=full --show-leak-kinds=definite ./embedded_app
# Low overhead analysis for real-time systems
valgrind --tool=massif --detailed-freq=100 --threshold=1.0 ./realtime_app
# Cache analysis for performance-critical embedded code
valgrind --tool=cachegrind --I1=8192,4,32 --D1=8192,4,32 ./embedded_program
Large-Scale Application Analysis
# Handle large applications with increased limits
valgrind --max-stackframe=16777216 --leak-check=full ./large_application
# Distributed memory analysis for multi-process applications
valgrind --trace-children=yes --track-fds=yes ./distributed_app
# Long-running application profiling with periodic snapshots
valgrind --tool=massif --detailed-freq=1 --massif-out-file=massif_snapshot ./long_running_server
Network and Server Applications
# Server application with network I/O analysis
valgrind --track-fds=yes --leak-check=full ./network_server
# High-concurrency server thread analysis
valgrind --tool=helgrind --conflict-cache-size=5000000 ./web_server
# Memory usage patterns for connection handling
valgrind --tool=massif --alloc-fn=malloc --stacks=yes ./connection_server
Automation and Scripting
Batch Analysis Script
#!/bin/bash
# batch_valgrind_analysis.sh
PROGRAMS_DIR="./programs"
RESULTS_DIR="./analysis_results"
mkdir -p $RESULTS_DIR
echo "Starting batch Valgrind analysis..."
for program in $PROGRAMS_DIR/*; do
if [ -x "$program" ]; then
program_name=$(basename "$program")
echo "Analyzing $program_name..."
# Memory leak detection
valgrind --leak-check=full --show-leak-kinds=all \
--log-file="$RESULTS_DIR/${program_name}_memcheck.log" \
"$program"
# Thread safety check
valgrind --tool=helgrind \
--log-file="$RESULTS_DIR/${program_name}_helgrind.log" \
"$program"
echo "Analysis complete for $program_name"
fi
done
echo "Batch analysis complete. Results in $RESULTS_DIR"
Memory Regression Testing
#!/bin/bash
# memory_regression_test.sh
BASELINE_RESULTS="baseline_results"
CURRENT_RESULTS="current_results"
PROGRAM="./myprogram"
# Run baseline analysis
mkdir -p $BASELINE_RESULTS
valgrind --leak-check=full --xml=yes --xml-file="$BASELINE_RESULTS/baseline.xml" $PROGRAM
# Run current analysis
mkdir -p $CURRENT_RESULTS
valgrind --leak-check=full --xml=yes --xml-file="$CURRENT_RESULTS/current.xml" $PROGRAM
# Compare results
baseline_errors=$(grep -c "<error>" "$BASELINE_RESULTS/baseline.xml")
current_errors=$(grep -c "<error>" "$CURRENT_RESULTS/current.xml")
echo "Baseline errors: $baseline_errors"
echo "Current errors: $current_errors"
if [ $current_errors -gt $baseline_errors ]; then
echo "REGRESSION DETECTED: More errors in current build!"
exit 1
else
echo "No regression detected"
exit 0
fi
Related Commands
gdb- GNU Debugger for source-level debugginggcc- GNU Compiler Collection for compilationg++- GNU C++ Compilerstrace- System call tracer for debuggingltrace- Library call tracermake- Build automation toolcmake- Cross-platform build systemaddr2line- Address to line number converterc++filt- C++ name demanglerobjdump- Object file disassemblernm- Symbol table extraction toolreadelf- ELF file analysis toolldd- List dynamic dependencies
Best Practices
Development Workflow
- Always compile with debug symbols: Use
-gflag for meaningful stack traces - Test early and often: Integrate valgrind into your regular development cycle
- Fix errors systematically: Address errors from top to bottom in output
- Use appropriate tools: Choose the right valgrind tool for your specific needs
- Create suppression files: Document and suppress known library issues
- Track regressions: Use valgrind in automated testing to prevent new memory issues
- Profile before optimizing: Use performance tools to identify actual bottlenecks
Memory Management
- Check all memory allocations: Verify malloc/calloc/new have corresponding free/delete
- Initialize all variables: Use
--track-origins=yesto find uninitialized values - Check array bounds: Valgrind detects buffer overflows and underflows
- Avoid memory leaks: Use
--leak-check=fullfor comprehensive leak detection - Track file descriptors: Use
--track-fds=yesto detect resource leaks
Performance Optimization
- Profile before optimizing: Use Callgrind to identify actual hotspots
- Analyze cache performance: Use Cachegrind for cache miss optimization
- Monitor memory usage: Use Massif for memory allocation pattern analysis
- Consider thread safety: Use Helgrind for multi-threaded application debugging
Testing and Quality Assurance
- Integrate into CI/CD: Use valgrind in continuous integration pipelines
- Set exit codes: Use
--error-exitcodefor automated testing - Save analysis results: Use log files for documentation and review
- Test edge cases: Verify error handling paths with valgrind
Performance Tips
Reducing Valgrind Overhead
- Use appropriate tool selection: Memcheck has highest overhead, Massif lowest
- Limit stack trace depth: Reduce
--num-callersfor faster execution - Disable unnecessary features: Use
--quietand minimal checking options when possible - Use summary mode:
--leak-check=summaryis faster thanfull - Focus on specific functions: Use tools to profile only relevant code sections
Optimizing Analysis Accuracy
- Compile without optimization: Use
-O0for most accurate line-by-line analysis - Include all debug information: Use
-g3for maximum debugging detail - Use static linking: When possible to analyze all code paths
- Run with realistic data: Test with typical input data and workloads
- Analyze multiple runs: Different runs may reveal different issues
Memory and Resource Management
- Increase system resources: Valgrind can require 2-4x normal memory usage
- Use 64-bit systems: Better for analyzing large memory applications
- Monitor disk space: Log files can become large for long-running applications
- Plan for extended runtime: Valgrind typically slows execution by 10-50x
Troubleshooting
Common Issues and Solutions
Performance Problems
# Valgrind running too slow
# Solution: Use lighter tools or reduce checking depth
valgrind --tool=massif ./program # Less overhead than Memcheck
valgrind --num-callers=5 ./program # Reduce stack trace depth
valgrind --leak-check=summary ./program # Faster leak checking
Memory Issues
# Out of memory errors
# Solution: Increase available memory or use 64-bit system
ulimit -s unlimited # Increase stack limit
valgrind --main-stacksize=16777216 ./program # Increase valgrind stack
False Positives
# Too many false positives from system libraries
# Solution: Use suppression files
valgrind --suppressions=/usr/lib/valgrind/default.supp ./program
# Generate custom suppression file
valgrind --gen-suppressions=all ./program > my_suppressions.supp
valgrind --suppressions=my_suppressions.supp ./program
Missing Debug Information
# Poor stack traces or missing function names
# Solution: Recompile with debug symbols
gcc -g -o program program.c # Add debug symbols
gcc -g3 -O0 -o program program.c # Maximum debug info, no optimization
Complex Programs
# Multi-threaded programs with complex synchronization
# Solution: Use appropriate thread analysis tools
valgrind --tool=helgrind --history-level=full ./program
# Programs that fork children
# Solution: Trace child processes
valgrind --trace-children=yes ./parent_program
The valgrind command is an indispensable tool for C/C++ development, providing powerful memory debugging, profiling, and thread safety checking capabilities. Mastering its various tools and options enables developers to create more reliable, efficient, and maintainable software by catching memory-related errors early in the development process. The framework's ability to work with unmodified binaries makes it particularly valuable for analyzing complex applications and legacy codebases where source modification may not be feasible.