5 Linux Commands for Debugging Every Developer Should Know

,

Debugging is an inevitable part of software development, and for developers working in Linux, the command line can be your best friend. The beauty of Linux lies in its flexibility and the array of tools it provides to solve complex problems. However, knowing which commands to use is critical. In this guide, we’ll walk through five essential Linux commands that will help you debug faster, with detailed examples, real-life scenarios, and explanations of when and why each command is used. Let’s dive in.


1. grep – Find Specific Patterns in Files Efficiently

The grep command allows you to search for specific patterns in files, helping you zero in on the exact data you need. As a developer, you’ll often find yourself buried in logs or large files, searching for errors, variable names, or specific user inputs.

When to Use It

You’re debugging a web application, and you need to find an instance of an error, like a “NullPointerException” in a massive log file. Instead of manually scrolling through the file, use grep to locate all occurrences of the error.

Related: Explain Like I’m Five: What’s a NullPointerException?

Example

grep "NullPointerException" /var/log/app.log
Bash

This command scans the /var/log/app.log file for lines containing “NullPointerException”. If you want to add context, such as finding a pattern along with its surrounding lines, you can use the -C option:

grep -C 3 "NullPointerException" /var/log/app.log
Bash

This will display the error along with 3 lines before and after it.

Real-life Scenario

You’re working on a Java-based REST API, and the application crashes intermittently. By searching through logs with grep, you quickly locate the exact line in your logs that reveals the root cause of the failure.


2. top – Real-time System Monitoring

When debugging performance issues, you need to know what resources your applications are consuming. top is the go-to command for real-time monitoring of CPU, memory, and process usage.

When to Use It

Your Python web app is running slower than expected. Before diving into the code, you suspect high CPU or memory usage could be the culprit.

Example

top
Bash

This command opens an interactive display showing the system’s resource usage, sorted by CPU usage by default. You can quickly identify which processes are hogging the CPU or RAM. Press q to quit, or press M to sort by memory usage.

Advanced Usage

You can set top to display only processes for a specific user, which is helpful when running multiple services on the same machine:

top -u your_username
Bash

Real-life Scenario

You’ve deployed an update to a Django application, but suddenly, the server becomes unresponsive. Running top, you discover the Python process is consuming 95% of the CPU due to a new memory leak introduced in your code. This insight leads you directly to the portion of the app that’s causing the performance hit.


3. strace – Tracking System Calls

strace is a powerful command for tracing the system calls a program makes. Every time a program interacts with the operating system, it does so via system calls. If a program is failing silently or behaving oddly, strace can pinpoint exactly where things go wrong.

When to Use It

Your C++ application fails unexpectedly without any output or error messages. You want to see what the program is trying to do at the system level to identify the issue.

Example

strace ./myapp
Bash

This command runs your program myapp and outputs every system call it makes. If the program is failing due to a missing file or permission issue, strace will highlight the system call that failed.

Filtering Output

Sometimes strace outputs too much information. You can filter the output to focus on file system operations, which are common culprits in program failures:

strace -e trace=open ./myapp
Bash

This limits the trace to open system calls, which occur when the program attempts to access files.

Real-life Scenario

You’ve written a C program that interacts with external configuration files. When it fails to launch properly, strace reveals that the program is looking for a config file in the wrong directory. By simply changing the path in your code, the issue is resolved.


4. lsof – Find Open Files and Network Connections

lsof (List Open Files) is a command-line utility that shows which files are currently open by which processes. It’s also useful for debugging networking issues since sockets are treated as files in Linux.

When to Use It

Your database server is refusing to start because it says a lock file is still in use. Use lsof to see which process has the file open and terminate it if necessary.

Example

lsof /var/db/mysqld.lock
Bash

This command tells you which process is currently using the file /var/db/mysqld.lock. Once identified, you can stop that process and free the lock.

Network Debugging

You can also use lsof to check network connections. This is useful for finding which process is using a specific port:

lsof -i :8080
Bash

This shows you which process is using port 8080, which could be helpful if your web server isn’t starting due to port conflicts.

Real-life Scenario

You try to delete a log file but receive a “file in use” error. By running lsof, you discover a long-running background process still has the file open. After stopping the process, you can successfully delete the file and resolve the issue.


5. tail – Monitoring Log Files in Real-time

tail is a simple yet essential tool for monitoring log files as they’re being updated. When debugging an issue, watching the log file in real-time can provide immediate insight into what’s happening.

When to Use It

You’re troubleshooting a web server, and you want to see new entries in the log as they’re added, especially when interacting with your app.

Example:

tail -f /var/log/nginx/error.log
Bash

The -f flag makes tail follow the file as it grows, updating the output in your terminal as new lines are added to the log file.

Combining with grep

You can combine tail with grep to only display relevant log lines in real-time:

tail -f /var/log/app.log | grep "ERROR"
Bash

This shows only lines in the log that contain the word “ERROR” as they are written.

Real-life Scenario

While testing your web app, you want to ensure that no new 404 errors appear in your Nginx logs. By running tail -f on the error log, you instantly see any issues the moment they occur, enabling you to respond to problems faster.


Putting It All Together: Master Debugging with These Linux Commands for a Slow Web Application

Let’s break down how to apply the commands mentioned when facing a slow web application. We’ll walk through a real-world debugging scenario, taking a systematic approach using these Linux tools.

Step 1: Check System Performance with top

First, run top to monitor system performance. This will help you identify if any processes, such as your web server or database, are using excessive CPU or memory.

top
Bash

Analysis: Let’s say python3 (your Django app) is taking up 80% of CPU. You now know which process is likely causing the slowdown.

Step 2: Monitor Logs in Real-Time with tail

Next, you need to observe the behavior of your web application. Use tail to follow your server logs and capture any real-time errors that might be thrown during requests.

tail -f /var/log/nginx/error.log
Bash

Scenario: While testing the app, you notice multiple 500 errors showing up in the logs.

Step 3: Pinpoint Errors with grep

Now that you have seen some error messages in the logs, use grep to find all occurrences of the error in the log file. This helps you identify how frequent the error is and what else is happening around the same time.

grep "500" /var/log/nginx/error.log
Bash

Scenario: You find that the 500 errors are accompanied by a database connection failure, giving you a clue that the issue might be database-related.

Step 4: Trace System Calls with strace

If you suspect the problem is due to system-level interactions, run strace on the problematic process to get a detailed trace of system calls. This could help uncover file access errors, permission problems, or failed system calls.

strace -p 12345  # Replace with your process ID from the 'top' output
Bash

Scenario: The trace reveals that your application is repeatedly trying to access a config file but is unable to find it. This could be the root cause of the application failure.

Step 5: Identify Locked Files with lsof

If you encounter files that are locked or cannot be accessed (such as log files or temporary files), use lsof to determine which processes are holding onto them. This is especially useful if you’re trying to delete files or diagnose issues with resource access.

lsof | grep /var/log/app.log
Bash

Scenario: You discover that an old backup process is still holding a lock on a log file, which is preventing your application from writing new logs. You can then terminate the backup process to resolve the issue.


Conclusion

These five Linux commands—grep, top, strace, lsof, and tail—are invaluable for developers debugging their applications. Each one serves a different purpose, from searching through logs, monitoring system performance, tracing system calls, identifying file locks, to monitoring logs in real-time. Mastering these commands will not only speed up your debugging process but also help you become a more efficient and capable developer. Whether you’re facing a complex bug or just monitoring system health, these tools should be at the top of your toolbox.

Feel free to try these out in your next debugging session, and watch how they streamline the process of identifying and fixing problems!

0 Shares