How to Debug Code with `lldb` or `gdb` on FreeBSD

This article will guide you through setting up, using, and effectively debugging programs with lldb and gdb on the FreeBSD operating system.

Debugging is an essential part of software development, and FreeBSD provides robust tools for this purpose. Two of the most commonly used debuggers on FreeBSD are lldb (from the LLVM project) and gdb (the GNU Debugger). This article will guide you through setting up, using, and effectively debugging programs with these tools on the FreeBSD operating system.

1. Setting Up Debugging Tools

Installing lldb and gdb

FreeBSD ships with lldb as the default debugger, but gdb can be installed if needed.

Installing lldb

lldb comes preinstalled with the FreeBSD base system. To check if it’s available, run:

lldb --version

Installing gdb

If you prefer gdb, you can install it from the FreeBSD package manager or ports collection:

sudo pkg install gdb

Or using ports:

cd /usr/ports/devel/gdb
make install clean

After installation, verify it with:

gdb --version

2. Compiling Programs for Debugging

To use lldb or gdb effectively, compile your program with debugging symbols. Use the -g flag with clang (default compiler in FreeBSD) or gcc.

For clang:

clang -g -o myprogram myprogram.c

For gcc:

gcc -g -o myprogram myprogram.c

This ensures that symbol information is available for debugging.

3. Debugging with lldb

Starting lldb

To start debugging with lldb, run:

lldb myprogram

This opens the lldb interactive session.

Setting Breakpoints

To set a breakpoint at main:

breakpoint set --name main

Or at a specific line:

breakpoint set --file myprogram.c --line 10

Running the Program

Run the program with:

run

If arguments are needed:

run arg1 arg2

Inspecting Variables

To print the value of a variable:

frame variable var_name

Or:

print var_name

Stepping Through Code

  • Step over (execute next line but don’t enter functions):

    next
    
  • Step into (enter function calls):

    step
    
  • Continue execution until the next breakpoint:

    continue
    

Backtracing

If a crash occurs, view the call stack with:

bt

Exiting lldb

To quit:

quit

4. Debugging with gdb

Starting gdb

To start debugging with gdb, run:

gdb myprogram

This opens the gdb interactive session.

Setting Breakpoints

To set a breakpoint at main:

break main

Or at a specific line:

break myprogram.c:10

Running the Program

Run the program with:

run

If arguments are needed:

run arg1 arg2

Inspecting Variables

To print the value of a variable:

print var_name

Stepping Through Code

  • Step over (execute next line but don’t enter functions):

    next
    
  • Step into (enter function calls):

    step
    
  • Continue execution until the next breakpoint:

    continue
    

Backtracing

If a crash occurs, view the call stack with:

backtrace

Exiting gdb

To quit:

quit

5. Debugging Core Dumps

Core dumps help diagnose crashes by analyzing a snapshot of the program’s memory at the time of failure.

Enabling Core Dumps

Check if core dumps are enabled:

sysctl kern.corefile

Enable core dumps (if necessary):

sysctl kern.corefile=/var/core/%N.core

Generating a Core Dump

If a program crashes, a core dump file may be created. To force a core dump manually:

ulimit -c unlimited
kill -SIGSEGV <pid>

Analyzing a Core Dump with lldb

lldb myprogram -c myprogram.core

Analyzing a Core Dump with gdb

gdb myprogram myprogram.core

6. Attaching to a Running Process

To debug a running process:

With lldb

Find the process ID:

ps aux | grep myprogram

Attach to it:

lldb -p <pid>

With gdb

Find the process ID:

ps aux | grep myprogram

Attach to it:

gdb -p <pid>

7. Remote Debugging

For debugging applications running on a remote FreeBSD machine:

With lldb-server

On the target machine:

lldb-server gdbserver :1234 myprogram

On the host machine:

lldb
process connect connect://target-ip:1234

With gdbserver

On the target machine:

gdbserver :1234 myprogram

On the host machine:

gdb
(gdb) target remote target-ip:1234

Conclusion

Debugging with lldb and gdb on FreeBSD is straightforward once you understand the tools and techniques available. lldb is the default and recommended debugger, but gdb remains a powerful alternative. By leveraging breakpoints, stepping through code, analyzing core dumps, and even performing remote debugging, you can effectively troubleshoot and resolve issues in your programs.