본문으로 건너뛰기 C++ Debugging Practical Complete Guide | gdb· LLDB

C++ Debugging Practical Complete Guide | gdb· LLDB

C++ Debugging Practical Complete Guide | gdb· LLDB

이 글의 핵심

Organizes core concepts and practical points of C++ debugging practical guide.

1. cout Debugging

#include <iostream>
using namespace std;
int buggyFunction(int x) {
    cout << "[DEBUG] buggyFunction called, x = " << x << endl;
    
    int result = x * 2;
    cout << "[DEBUG] result = " << result << endl;
    
    return result;
}

Pros: Simple, fast
Cons: Requires code modification, performance impact

2. Check Conditions with assert

#include <cassert>
void process(int* ptr) {
    assert(ptr != nullptr);  // Check only in debug build
    assert(*ptr > 0);
    
    // ...
}
int main() {
    int* ptr = nullptr;
    process(ptr);  // Assertion fails!
}

3. Using Breakpoints

Visual Studio

F9: Set/unset breakpoint
F5: Start debugging
F10: Step over (execute line by line)
F11: Step into (enter function)
Shift+F11: Step out (exit function)

GDB

# Compile (with -g option required)
g++ -g program.cpp -o program
# Run gdb
gdb ./program
# Set breakpoint
(gdb) break main
(gdb) break file.cpp:42
# Run
(gdb) run
# Step by step
(gdb) next  # Step Over
(gdb) step  # Step Into
# Print variable
(gdb) print variable
(gdb) print *ptr
# Continue execution
(gdb) continue

4. Conditional Breakpoints

Visual Studio

Right-click breakpoint → Conditions
Example: i == 100

GDB

(gdb) break main if x == 10
(gdb) condition 1 i == 100  # Add condition to breakpoint 1

5. Memory Debugging

Valgrind (Linux)

# Install
sudo apt install valgrind
# Check memory leaks
valgrind --leak-check=full ./program
# Output example
==12345== HEAP SUMMARY:
==12345==     in use at exit: 40 bytes in 1 blocks
==12345==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==12345== 
==12345== LEAK SUMMARY:
==12345==    definitely lost: 40 bytes in 1 blocks

AddressSanitizer

# Compile
g++ -fsanitize=address -g program.cpp -o program
# Run
./program
# Auto-detect errors
=================================================================
==12345==ERROR: AddressSanitizer: heap-use-after-free

Understanding with everyday analogy: Think of memory as an apartment building. Stack is like an elevator - fast but limited space. Heap is like a warehouse - spacious but takes time to find things. Pointers are like notes saying “Floor 3, Unit 302” - they point to addresses.

Practical Examples

Example 1: Debugging Segmentation Fault

#include <iostream>
using namespace std;
int main() {
    int* ptr = nullptr;
    
    // Debugging tip: Check nullptr
    if (ptr == nullptr) {
        cerr << "Error: ptr is nullptr!" << endl;
        return 1;
    }
    
    *ptr = 10;  // Segfault!
    
    return 0;
}

Debugging with GDB:

$ gdb ./program
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
(gdb) backtrace  # Check call stack
(gdb) print ptr  # Check ptr value
$1 = (int *) 0x0

Example 2: Debugging Infinite Loop

#include <iostream>
using namespace std;
int main() {
    int i = 0;
    
    while (i < 10) {
        cout << i << endl;
        // i++; Missing! Infinite loop
    }
    
    return 0;
}

Debugging method:

  1. Stop with Ctrl+C
  2. Set breakpoint
  3. Check variable i value
  4. Check if i++ executes

Example 3: Log Macro

#include <iostream>
using namespace std;
#ifdef DEBUG
#define LOG(msg) cout << "[" << __FILE__ << ":" << __LINE__ << "] " << msg << endl
#else
#define LOG(msg)
#endif
int main() {
    int x = 10;
    LOG("x = " << x);
    
    x *= 2;
    LOG("x after multiply = " << x);
    
    return 0;
}

Compile:

# Debug build
g++ -DDEBUG program.cpp -o program
# Release build (no logs)
g++ program.cpp -o program

Summary

Key Points

  1. cout debugging: Simple but requires code modification
  2. assert: Check conditions in debug build
  3. Breakpoints: Pause execution and inspect state
  4. Memory debugging: Use Valgrind or AddressSanitizer
  5. Conditional breakpoints: Break only when condition met

Debugging Tools

Visual Studio:

  • Integrated debugger
  • Easy to use
  • Windows-friendly ✅ GDB/LLDB:
  • Command-line debuggers
  • Powerful and flexible
  • Linux/Mac standard ✅ AddressSanitizer:
  • Fast memory error detection
  • Compile-time instrumentation
  • Recommended for daily use

Best Practices

  • ✅ Compile with debug symbols (-g)
  • ✅ Use assertions for preconditions
  • ✅ Learn debugger keyboard shortcuts
  • ❌ Don’t leave debug code in production
  • ❌ Don’t ignore warnings


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. C++ debugging practical guide #include using namespace std;. Focused on C++, debugging, and gdb. Start now.

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, debugging, gdb, lldb, dev-tools, VisualStudio.